From 303c402adaed765bd1bea2808c233ccf4c1f91bc Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 31 Jul 2016 20:28:45 +0200 Subject: [PATCH] Add the windows example to show the window behavior --- .gitignore | 1 + ChangeLog | 2 +- test/Makefile.am | 3 +- test/Makefile.in | 18 +- test/windows.cpp | 431 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 450 insertions(+), 5 deletions(-) create mode 100644 test/windows.cpp diff --git a/.gitignore b/.gitignore index 8e2bedb6..3cf94b9d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ test/string-operations test/hello test/watch test/menu +test/windows test/term-attributes test/input-dialog test/mandelbrot diff --git a/ChangeLog b/ChangeLog index e0096a96..f1737847 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ * Resetting the local window widget focus at the end of the lifetime of a widget. * Fix method setPos in the class FRect - * Add the windows example to show window behavior + * Add the windows example to show the window behavior 2016-07-30 Markus Gans * Delete all callbacks from a widget with delCallbacks() diff --git a/test/Makefile.am b/test/Makefile.am index 855185ec..deba7230 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,6 +16,7 @@ noinst_PROGRAMS = \ term-attributes \ keyboard \ timer \ + windows \ menu \ ui @@ -29,6 +30,6 @@ watch_SOURCES = watch.cpp term_attributes_SOURCES = term-attributes.cpp keyboard_SOURCES = keyboard.cpp timer_SOURCES = timer.cpp +windows_SOURCES = windows.cpp menu_SOURCES = menu.cpp ui_SOURCES = ui.cpp - diff --git a/test/Makefile.in b/test/Makefile.in index 38088180..687e1841 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -85,7 +85,8 @@ host_triplet = @host@ noinst_PROGRAMS = hello$(EXEEXT) dialog$(EXEEXT) input-dialog$(EXEEXT) \ string-operations$(EXEEXT) mandelbrot$(EXEEXT) \ calculator$(EXEEXT) watch$(EXEEXT) term-attributes$(EXEEXT) \ - keyboard$(EXEEXT) timer$(EXEEXT) menu$(EXEEXT) ui$(EXEEXT) + keyboard$(EXEEXT) timer$(EXEEXT) windows$(EXEEXT) \ + menu$(EXEEXT) ui$(EXEEXT) subdir = test DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -141,6 +142,9 @@ ui_LDADD = $(LDADD) am_watch_OBJECTS = watch.$(OBJEXT) watch_OBJECTS = $(am_watch_OBJECTS) watch_LDADD = $(LDADD) +am_windows_OBJECTS = windows.$(OBJEXT) +windows_OBJECTS = $(am_windows_OBJECTS) +windows_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -179,12 +183,14 @@ SOURCES = $(calculator_SOURCES) $(dialog_SOURCES) $(hello_SOURCES) \ $(input_dialog_SOURCES) $(keyboard_SOURCES) \ $(mandelbrot_SOURCES) $(menu_SOURCES) \ $(string_operations_SOURCES) $(term_attributes_SOURCES) \ - $(timer_SOURCES) $(ui_SOURCES) $(watch_SOURCES) + $(timer_SOURCES) $(ui_SOURCES) $(watch_SOURCES) \ + $(windows_SOURCES) DIST_SOURCES = $(calculator_SOURCES) $(dialog_SOURCES) \ $(hello_SOURCES) $(input_dialog_SOURCES) $(keyboard_SOURCES) \ $(mandelbrot_SOURCES) $(menu_SOURCES) \ $(string_operations_SOURCES) $(term_attributes_SOURCES) \ - $(timer_SOURCES) $(ui_SOURCES) $(watch_SOURCES) + $(timer_SOURCES) $(ui_SOURCES) $(watch_SOURCES) \ + $(windows_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -343,6 +349,7 @@ watch_SOURCES = watch.cpp term_attributes_SOURCES = term-attributes.cpp keyboard_SOURCES = keyboard.cpp timer_SOURCES = timer.cpp +windows_SOURCES = windows.cpp menu_SOURCES = menu.cpp ui_SOURCES = ui.cpp all: all-am @@ -437,6 +444,10 @@ watch$(EXEEXT): $(watch_OBJECTS) $(watch_DEPENDENCIES) $(EXTRA_watch_DEPENDENCIE @rm -f watch$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(watch_OBJECTS) $(watch_LDADD) $(LIBS) +windows$(EXEEXT): $(windows_OBJECTS) $(windows_DEPENDENCIES) $(EXTRA_windows_DEPENDENCIES) + @rm -f windows$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(windows_OBJECTS) $(windows_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -455,6 +466,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windows.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/test/windows.cpp b/test/windows.cpp new file mode 100644 index 00000000..389375e1 --- /dev/null +++ b/test/windows.cpp @@ -0,0 +1,431 @@ +// File: windows.cpp + +#include "fapp.h" +#include "fdialog.h" +#include "fdialoglistmenu.h" +#include "flabel.h" +#include "fmenubar.h" +#include "fmenu.h" +#include "fmessagebox.h" +#include "fstatusbar.h" +#include "fstring.h" + + +//---------------------------------------------------------------------- +// class Window +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class Window : public FDialog +{ + private: + typedef struct + { + bool is_open; + FString* title; + FDialog* dgl; + } + win_data; + std::vector windows; + + private: + Window (const Window&); // Disabled copy constructor + Window& operator = (const Window&); // and operator '=' + void activateWindow (FDialog*); + void onClose (FCloseEvent*); + void cb_createWindows (FWidget*, void*); + void cb_closeWindows (FWidget*, void*); + void cb_next (FWidget*, void*); + void cb_previous (FWidget*, void*); + void cb_exitApp (FWidget*, void*); + void cb_destroyWindow (FWidget*, void*); + void adjustSize(); + + public: + explicit Window (FWidget* = 0); // constructor + ~Window(); // destructor +}; +#pragma pack(pop) + +//---------------------------------------------------------------------- +Window::Window (FWidget* parent) + : FDialog(parent) + , windows() +{ + // menu bar + FMenuBar* Menubar = new FMenuBar (this); + + // menu bar item + FMenu* File = new FMenu ("&File", Menubar); + File->setStatusbarMessage ("File management commands"); + + // dialog list menu item + FString drop_down_symbol = wchar_t(fc::BlackDownPointingTriangle); + FDialogListMenu* DglList = new FDialogListMenu (drop_down_symbol, Menubar); + DglList->setStatusbarMessage ("List of all the active dialogs"); + + // "File" menu item + FMenuItem* New = new FMenuItem ("&New", File); + New->setStatusbarMessage ("Create the windows"); + + FMenuItem* Close = new FMenuItem ("&Close", File); + Close->setStatusbarMessage ("Close the windows"); + + FMenuItem* Line1 = new FMenuItem (File); + Line1->setSeparator(); + + FMenuItem* Next = new FMenuItem ("Ne&xt window", File); + Next->addAccelerator (fc::Fmkey_npage); // Meta/Alt + PgDn + Next->setStatusbarMessage ("Switch to the next window"); + + FMenuItem* Previous = new FMenuItem ("&Previous window", File); + Previous->addAccelerator (fc::Fmkey_ppage); // Meta/Alt + PgUp + Previous->setStatusbarMessage ("Switch to the previous window"); + + FMenuItem* Line2 = new FMenuItem (File); + Line2->setSeparator(); + + FMenuItem* Quit = new FMenuItem ("&Quit", File); + Quit->addAccelerator (fc::Fmkey_x); // Meta/Alt + X + Quit->setStatusbarMessage ("Exit the program"); + + // Statusbar at the bottom + FStatusBar* statusbar = new FStatusBar (this); + statusbar->setMessage("Status bar message"); + + // Buttons + FButton* CreateButton = new FButton (this); + CreateButton->setGeometry(2, 2, 9, 1); + CreateButton->setText (L"&Create"); + CreateButton->setShadow(); + + FButton* CloseButton = new FButton (this); + CloseButton->setGeometry(15, 2, 9, 1); + CloseButton->setText (L"C&lose"); + CloseButton->setShadow(); + + FButton* QuitButton = new FButton (this); + QuitButton->setGeometry(28, 2, 9, 1); + QuitButton->setText (L"&Quit"); + QuitButton->setShadow(); + + // Add menu item callback + New->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_createWindows) + ); + + Close->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_closeWindows) + ); + + Next->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_next) + ); + + Previous->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_previous) + ); + + Quit->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_exitApp) + ); + + // Add button callback + CreateButton->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_createWindows) + ); + + CloseButton->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_closeWindows) + ); + + QuitButton->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &Window::cb_exitApp) + ); + + for (int n=1; n <= 6; n++) + { + win_data* win_dat = new win_data; + win_dat->is_open = false; + win_dat->title = new FString(); + win_dat->title->sprintf("Window %d", n); + windows.push_back(win_dat); + } +} + +//---------------------------------------------------------------------- +Window::~Window() +{ + std::vector::iterator iter; + iter = windows.begin(); + + while ( iter != windows.end() ) + { + delete (*iter)->title; + delete *iter; + iter = windows.erase(iter); + } +} + +//---------------------------------------------------------------------- +void Window::activateWindow (FDialog* win) +{ + if ( win && ! win->isHiddenWindow() && ! win->isActiveWindow() ) + { + bool has_raised = FWindow::raiseWindow(win); + win->activateDialog(); + + if ( has_raised ) + win->redraw(); + + updateTerminal(); + } +} + +//---------------------------------------------------------------------- +void Window::onClose (FCloseEvent* ev) +{ + int ret = FMessageBox::info ( this, "Quit" + , "Do you really want\n" + "to quit the program ?" + , FMessageBox::Yes + , FMessageBox::No ); + if ( ret == FMessageBox::Yes ) + { + cb_closeWindows(0,0); + ev->accept(); + } + else + ev->ignore(); +} + +//---------------------------------------------------------------------- +void Window::cb_createWindows (FWidget*, void*) +{ + std::vector::const_iterator iter, begin; + iter = begin = windows.begin(); + + while ( iter != windows.end() ) + { + if ( ! (*iter)->is_open ) + { + int x,y,n; + win_data* win_dat = *iter; + FDialog* win = new FDialog(this); + win_dat->dgl = win; + win_dat->is_open = true; + win->setText(*(win_dat)->title); + n = int(std::distance(begin, iter)); + x = 5 + (n%3)*25 + int(n/3)*3; + y = 11 + int(n/3)*3; + win->setGeometry (x, y, 20, 8); + win->setTransparentShadow(); + win->show(); + + win->addCallback + ( + "destroy", + _METHOD_CALLBACK (this, &Window::cb_destroyWindow), + static_cast(win_dat) + ); + } + + ++iter; + } + + activateWindow(this); +} + +//---------------------------------------------------------------------- +void Window::cb_closeWindows (FWidget*, void*) +{ + if ( ! dialog_list || dialog_list->empty() ) + return; + + widgetList::const_iterator iter, begin; + iter = dialog_list->end(); + begin = dialog_list->begin(); + activateWindow(this); + + do + { + --iter; + + if ( (*iter) != this ) + (*iter)->close(); + } + while ( iter != begin ); +} + +//---------------------------------------------------------------------- +void Window::cb_next (FWidget*, void*) +{ + if ( ! dialog_list || dialog_list->empty() ) + return; + + widgetList::const_iterator iter; + iter = dialog_list->begin(); + + while ( iter != dialog_list->end() ) + { + if ( static_cast(*iter)->isActiveWindow() ) + { + FDialog* next; + widgetList::const_iterator next_element; + next_element = iter; + + do + { + ++next_element; + + if ( next_element == dialog_list->end() ) + next_element = dialog_list->begin(); + + next = static_cast(*next_element); + } while ( ! next->isEnabled() + || ! next->acceptFocus() + || ! next->isVisible() + || ! next->isWindow() ); + + activateWindow(next); + break; + } + + ++iter; + } +} + +//---------------------------------------------------------------------- +void Window::cb_previous (FWidget*, void*) +{ + if ( ! dialog_list || dialog_list->empty() ) + return; + + widgetList::const_iterator iter; + iter = dialog_list->end(); + + do + { + --iter; + + if ( (*iter)->isDialog() + && static_cast(*iter)->isActiveWindow() ) + { + FDialog* prev; + widgetList::const_iterator prev_element; + prev_element = iter; + + do + { + if ( prev_element == dialog_list->begin() ) + prev_element = dialog_list->end(); + + --prev_element; + prev = static_cast(*prev_element); + } while ( ! prev->isEnabled() + || ! prev->acceptFocus() + || ! prev->isVisible() + || ! prev->isWindow() ); + + activateWindow(prev); + break; + } + } + while ( iter != dialog_list->begin() ); +} + +//---------------------------------------------------------------------- +void Window::cb_exitApp (FWidget*, void*) +{ + close(); +} + +//---------------------------------------------------------------------- +void Window::cb_destroyWindow (FWidget*, void* data_ptr) +{ + win_data* win_dat = static_cast(data_ptr); + if ( win_dat ) + win_dat->is_open = false; +} + +//---------------------------------------------------------------------- +void Window::adjustSize() +{ + int w,h,X,Y; + std::vector::const_iterator iter, begin; + w = getRootWidget()->getWidth(); + h = getRootWidget()->getHeight(); + X = int(1 + (w - 40) / 2); + Y = int(1 + (h - 22) / 2); + + if ( Y < 2) + Y = 2; + + setPos (X, Y, false); + iter = begin = windows.begin(); + + while ( iter != windows.end() ) + { + if ( (*iter)->is_open ) + { + int x,y,dx,dy,n; + n = int(std::distance(begin, iter)); + dx = (w > 80) ? (w - 80) / 2 : 0; + dy = (h > 24) ? (h - 24) / 2 : 0; + x = dx + 5 + (n%3)*25 + int(n/3)*3; + y = dy + 11 + int(n/3)*3; + (*iter)->dgl->setPos (x, y, false); + } + + ++iter; + } + + FDialog::adjustSize(); +} + +//---------------------------------------------------------------------- +// main part +//---------------------------------------------------------------------- + +int main (int argc, char* argv[]) +{ + if ( argv[1] && ( strcmp(argv[1], "--help") == 0 + || strcmp(argv[1], "-h") == 0 ) ) + { + std::cout << "Generic options:" << std::endl + << " -h, --help " + << "Display this help and exit" << std::endl; + FApplication::print_cmd_Options(); + exit(EXIT_SUCCESS); + } + + FApplication app (argc, argv); + + Window main_dlg (&app); + main_dlg.setText ("Main window"); + main_dlg.setGeometry (int(1+(app.getWidth()-40)/2), 2, 40, 6); + main_dlg.setTransparentShadow(); + + app.setMainWidget (&main_dlg); + main_dlg.show(); + + return app.exec(); +}