From 9ccc5a4f27493686107a7aeeca305ab6f735b5dd Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sat, 1 Oct 2016 23:18:49 +0200 Subject: [PATCH] New FToolTip widget to show assisted information --- ChangeLog | 4 + doc/class-diagram.txt | 21 +++-- src/Makefile.am | 2 + src/Makefile.clang | 2 + src/Makefile.gcc | 2 + src/Makefile.in | 9 +- src/fapp.cpp | 52 ++++++----- src/fapp.h | 25 ++++-- src/fbutton.h | 1 - src/fbuttongroup.h | 1 + src/fconfig.h | 4 +- src/fdialog.cpp | 99 ++++++++++++--------- src/fdialog.h | 5 +- src/fenum.h | 5 +- src/ffiledialog.cpp | 2 +- src/ffiledialog.h | 2 +- src/final.h | 47 +++++----- src/fmenu.cpp | 53 ++---------- src/fmenu.h | 1 - src/fmenuitem.h | 1 + src/fmessagebox.cpp | 2 +- src/fobject.cpp | 22 ++--- src/fobject.h | 8 +- src/fstatusbar.h | 1 + src/fterm.h | 7 ++ src/ftogglebutton.h | 3 +- src/ftooltip.cpp | 194 ++++++++++++++++++++++++++++++++++++++++++ src/ftooltip.h | 87 +++++++++++++++++++ src/fwidget.cpp | 66 ++++++++------ src/fwidget.h | 16 ++-- src/fwindow.cpp | 72 ++++++++++++++++ src/fwindow.h | 21 ++++- 32 files changed, 629 insertions(+), 208 deletions(-) create mode 100644 src/ftooltip.cpp create mode 100644 src/ftooltip.h diff --git a/ChangeLog b/ChangeLog index 825703f6..726e3e48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-10-01 Markus Gans + * Add an always-on-top mode for window objects + * New FToolTip widget to show assisted information + 2016-09-30 Markus Gans * Using arrow keys to move or to resize a window diff --git a/doc/class-diagram.txt b/doc/class-diagram.txt index ac71e628..836948ce 100644 --- a/doc/class-diagram.txt +++ b/doc/class-diagram.txt @@ -55,7 +55,7 @@ │ FTerm │◄─┘ : : ├────┤ FProgressbar │ └──┤ FSwitch ├-------: └┬─┬─┬──┘ : : │ └──────────────┘ └─────────┘ : :1:1:1 : : │ ┌────────────┐ : *┌─────────┐ - : : └----------: : ├────┤ FScrollbar │ ├---┤ FString │ + : : └----------┤ : ├────┤ FScrollbar │ ├---┤ FString │ : :1 : : │ └────────────┘ : └─────────┘ :┌┴──────────┐ : : │ ┌───────────┐1 : :│ FOptiAttr │ : : ├────┤ FTextView ├---------------------------: @@ -70,13 +70,16 @@ : : │ ┌─────────────┐1 : : : ┌───┴─────┐ ┌─────────┐ ┌──┤ FFileDialog ├----: : : │ FWindow │◄─┤ FDialog │◄──┤ └─────────────┘ : - : : └───┬─────┘ └────┬────┘ │ ┌─────────────┐1 : - : : ▲ 1: └──┤ FMessageBox ├----: - : : │ : └─────────────┘ : - : : │ └------------------------------: - : : └───────────────┐ ┌──────────┐ : - : : │ ┌───┤ FMenuBar │ : - : : ┌───────────┐ └─────┤ └──────────┘ : + : : └──┬──┬───┘ └────┬────┘ │ ┌─────────────┐1 : + : : ▲ ▲ 1: └──┤ FMessageBox ├----: + : : │ │ : └─────────────┘ : + : : │ │ └------------------------------: + : : │ │ ┌──────────┐ : + : : │ └──────┤ FToolTip │ : + : : │ └──────────┘ : + : : └───────────────┐ ┌──────────┐ : + : : │ ┌───┤ FMenuBar │ : + : : ┌───────────┐ └──────┤ └──────────┘ : : : │ FMenuList │◄──────────┤ ┌───────┐ : : : └────┬──────┘ └───┤ FMenu │◄──┐ : : : : └───────┘ │ : @@ -92,7 +95,7 @@ : : └---------------------------------------┘ : : └---------------------------------------------------┘ : *┌────────┐ - :---┤ FPoint │ + ├---┤ FPoint │ : └────────┘ : *┌───────┐ └---┤ FRect │ diff --git a/src/Makefile.am b/src/Makefile.am index 3f65c0e5..b0b5d0a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,6 +33,7 @@ libfinal_la_SOURCES = \ fdialog.cpp \ fwindow.cpp \ fmessagebox.cpp \ + ftooltip.cpp \ ffiledialog.cpp \ ftextview.cpp \ fstatusbar.cpp \ @@ -73,6 +74,7 @@ finalcutinclude_HEADERS = \ fcheckmenuitem.h \ fmenulist.h \ fmessagebox.h \ + ftooltip.h \ fobject.h \ fpoint.h \ foptiattr.h \ diff --git a/src/Makefile.clang b/src/Makefile.clang index f88fefda..dbe59036 100644 --- a/src/Makefile.clang +++ b/src/Makefile.clang @@ -26,6 +26,7 @@ INCLUDE_HEADERS = \ fradiomenuitem.h \ fcheckmenuitem.h \ fmessagebox.h \ + ftooltip.h \ fobject.h \ foptiattr.h \ foptimove.h \ @@ -77,6 +78,7 @@ OBJS = \ fdialog.o \ fwindow.o \ fmessagebox.o \ + ftooltip.o \ ffiledialog.o \ ftextview.o \ fstatusbar.o \ diff --git a/src/Makefile.gcc b/src/Makefile.gcc index abbff6b3..21a3ef38 100644 --- a/src/Makefile.gcc +++ b/src/Makefile.gcc @@ -26,6 +26,7 @@ INCLUDE_HEADERS = \ fradiomenuitem.h \ fcheckmenuitem.h \ fmessagebox.h \ + ftooltip.h \ fobject.h \ foptiattr.h \ foptimove.h \ @@ -77,6 +78,7 @@ OBJS = \ fdialog.o \ fwindow.o \ fmessagebox.o \ + ftooltip.o \ ffiledialog.o \ ftextview.o \ fstatusbar.o \ diff --git a/src/Makefile.in b/src/Makefile.in index 1409a602..e85a82f4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -133,9 +133,9 @@ am_libfinal_la_OBJECTS = fstring.lo fpoint.lo frect.lo fscrollbar.lo \ ftogglebutton.lo fradiobutton.lo fcheckbox.lo fswitch.lo \ flabel.lo flistbox.lo fmenu.lo fdialoglistmenu.lo fmenubar.lo \ fmenuitem.lo fradiomenuitem.lo fcheckmenuitem.lo fmenulist.lo \ - fdialog.lo fwindow.lo fmessagebox.lo ffiledialog.lo \ - ftextview.lo fstatusbar.lo fterm.lo fevent.lo foptiattr.lo \ - foptimove.lo fapp.lo fwidget.lo fobject.lo + fdialog.lo fwindow.lo fmessagebox.lo ftooltip.lo \ + ffiledialog.lo ftextview.lo fstatusbar.lo fterm.lo fevent.lo \ + foptiattr.lo foptimove.lo fapp.lo fwidget.lo fobject.lo libfinal_la_OBJECTS = $(am_libfinal_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -397,6 +397,7 @@ libfinal_la_SOURCES = \ fdialog.cpp \ fwindow.cpp \ fmessagebox.cpp \ + ftooltip.cpp \ ffiledialog.cpp \ ftextview.cpp \ fstatusbar.cpp \ @@ -435,6 +436,7 @@ finalcutinclude_HEADERS = \ fcheckmenuitem.h \ fmenulist.h \ fmessagebox.h \ + ftooltip.h \ fobject.h \ fpoint.h \ foptiattr.h \ @@ -563,6 +565,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fterm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftextview.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftogglebutton.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftooltip.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fwidget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fwindow.Plo@am__quote@ diff --git a/src/fapp.cpp b/src/fapp.cpp index b9e79e01..b0102764 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -13,16 +13,17 @@ static FApplication* rootObj = 0; static bool app_exit_loop = false; // static attributes -int FApplication::loop_level = 0; // event loop level -FWidget* FApplication::main_widget = 0; // main application widget -FWidget* FApplication::active_window = 0; // the active window -FWidget* FApplication::focus_widget = 0; // has keyboard input focus -FWidget* FApplication::clicked_widget = 0; // is focused by click -FWidget* FApplication::open_menu = 0; // currently open menu -FPoint* FApplication::zero_point = 0; // zero point (x=0, y=0) -int FApplication::quit_code = 0; -bool FApplication::quit_now = false; -bool FApplication::move_size_mode = false; // move/size by keyboard +int FApplication::loop_level = 0; // event loop level +FWidget* FApplication::main_widget = 0; // main application widget +FWidget* FApplication::active_window = 0; // the active window +FWidget* FApplication::focus_widget = 0; // has keyboard input focus +FWidget* FApplication::clicked_widget = 0; // is focused by click +FWidget* FApplication::open_menu = 0; // currently open menu +FWidget* FApplication::move_size_widget = 0; // move/size by keyboard +FPoint* FApplication::zero_point = 0; // zero point (x=0, y=0) +int FApplication::quit_code = 0; +bool FApplication::quit_now = false; + std::deque* FApplication::event_queue = 0; //---------------------------------------------------------------------- @@ -250,8 +251,8 @@ void FApplication::processKeyboardEvent() if ( focus_widget ) { - if ( move_size_mode ) - widget = FWindow::getWindowWidget(focus_widget); + if ( move_size_widget ) + widget = move_size_widget; else widget = focus_widget; } @@ -357,7 +358,7 @@ void FApplication::processKeyboardEvent() for (; n < fifo_buf_size; n++) fifo_buf[n-len] = '\0'; - input_data_pending = bool(fifo_buf[0] != '\0'); + unprocessedInput() = bool(fifo_buf[0] != '\0'); processMouseEvent(); } break; @@ -386,7 +387,7 @@ void FApplication::processKeyboardEvent() for (; n < fifo_buf_size; n++) // Fill rest with '\0' fifo_buf[n-len] = '\0'; - input_data_pending = bool(fifo_buf[0] != '\0'); + unprocessedInput() = bool(fifo_buf[0] != '\0'); processMouseEvent(); } break; @@ -415,7 +416,7 @@ void FApplication::processKeyboardEvent() for (; n < fifo_buf_size; n++) // Fill rest with '\0' fifo_buf[n-len] = '\0'; - input_data_pending = bool(fifo_buf[0] != '\0'); + unprocessedInput() = bool(fifo_buf[0] != '\0'); processMouseEvent(); } break; @@ -484,7 +485,7 @@ void FApplication::processKeyboardEvent() { FKeyEvent k_press_ev (fc::KeyPress_Event, fc::Fkey_escape); sendEvent (widget, &k_press_ev); - input_data_pending = false; + unprocessedInput() = false; } } @@ -780,7 +781,7 @@ bool FApplication::processDialogSwitchAccelerator() if ( s > 0 && s >= n ) { // unset the move/size mode - setMoveSizeMode(false); + move_size_widget = 0; FAccelEvent a_ev (fc::Accelerator_Event, focus_widget); sendEvent (dialog_list->at(n-1), &a_ev); return true; @@ -811,7 +812,7 @@ bool FApplication::processAccelerator (FWidget*& widget) if ( iter->key == key ) { // unset the move/size mode - setMoveSizeMode(false); + move_size_widget = 0; FAccelEvent a_ev (fc::Accelerator_Event, focus_widget); sendEvent (iter->object, &a_ev); accpt = a_ev.isAccepted(); @@ -1346,9 +1347,9 @@ bool FApplication::processGpmEvent() mouse->setPoint(gpm_ev.x, gpm_ev.y); if ( gpmEvent(false) == mouse_event ) - input_data_pending = true; + unprocessedInput() = true; else - input_data_pending = false; + unprocessedInput() = false; GPM_DRAWPOINTER(&gpm_ev); gpmMouseEvent = false; @@ -1419,7 +1420,12 @@ void FApplication::processMouseEvent() } // unset the move/size mode - setMoveSizeMode(false); + if ( move_size_widget ) + { + FWidget* w = move_size_widget; + move_size_widget = 0; + w->redraw(); + } } // close the open menu @@ -1662,7 +1668,7 @@ int FApplication::processTimerEvent() getCurrentTime (currentTime); - if ( modify_timer ) + if ( isTimerInUpdating() ) return 0; if ( ! timer_list ) @@ -1705,7 +1711,7 @@ void FApplication::processTerminalUpdate() if ( terminal_update_pending ) { - if ( ! input_data_pending ) + if ( ! unprocessedInput() ) { updateTerminal(); terminal_update_pending = false; diff --git a/src/fapp.h b/src/fapp.h index a4b421ba..77071040 100644 --- a/src/fapp.h +++ b/src/fapp.h @@ -38,6 +38,7 @@ #include "fevent.h" #include "fwidget.h" +#include "fwindow.h" //---------------------------------------------------------------------- @@ -109,7 +110,7 @@ class FApplication : public FWidget struct timeval time_keypressed; struct timeval time_mousepressed; FPoint new_mouse_position; - static bool move_size_mode; + static FWidget* move_size_widget; static FWidget* main_widget; static FWidget* active_window; static FWidget* focus_widget; @@ -147,9 +148,21 @@ class FApplication : public FWidget void processTerminalUpdate(); void processCloseWidget(); bool processNextEvent(); - friend class FDialog; - friend class FWidget; - friend class FWindow; + + // Friend functions from FWidget + friend FWidget* FWidget::getMainWidget(); + friend FWidget* FWidget::getFocusWidget() const; + friend void FWidget::setFocusWidget (FWidget*); + friend FWidget* FWidget::getClickedWidget(); + friend void FWidget::setClickedWidget (FWidget*); + friend FWidget* FWidget::getMoveSizeWidget(); + friend void FWidget::setMoveSizeWidget (FWidget*); + friend FWidget* FWidget::getOpenMenu(); + friend void FWidget::setOpenMenu (FWidget*); + + // Friend functions from FWindow + friend bool FWindow::activateWindow (bool); + friend FWindow* FWindow::getActiveWindow(); public: // Constructor @@ -162,7 +175,6 @@ class FApplication : public FWidget char** argv() const; FWidget* mainWidget() const; FWidget* focusWidget() const; - bool unprocessedInput() const; static void print_cmd_Options(); void setMainWidget (FWidget*); int exec(); // run @@ -201,8 +213,5 @@ inline FWidget* FApplication::mainWidget() const inline FWidget* FApplication::focusWidget() const { return focus_widget; } -//---------------------------------------------------------------------- -inline bool FApplication::unprocessedInput() const -{ return input_data_pending; } #endif // _FAPPLICATION_H diff --git a/src/fbutton.h b/src/fbutton.h index 89f0e6c5..7c4e5d53 100644 --- a/src/fbutton.h +++ b/src/fbutton.h @@ -61,7 +61,6 @@ class FButton : public FWidget void draw(); void updateButtonColor(); void processClick(); - friend class FDialog; public: // Constructors diff --git a/src/fbuttongroup.h b/src/fbuttongroup.h index 0aa389db..f6303cd0 100644 --- a/src/fbuttongroup.h +++ b/src/fbuttongroup.h @@ -26,6 +26,7 @@ #include "fwidget.h" +// class forward declaration class FToggleButton; //---------------------------------------------------------------------- diff --git a/src/fconfig.h b/src/fconfig.h index b299f2ba..caf06d89 100644 --- a/src/fconfig.h +++ b/src/fconfig.h @@ -1,6 +1,6 @@ #ifndef _SRC_FCONFIG_H #define _SRC_FCONFIG_H 1 - + /* src/fconfig.h. Generated automatically at end of configure. */ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ @@ -171,6 +171,6 @@ #ifndef F_VERSION #define F_VERSION "0.2.0" #endif - + /* once: _SRC_FCONFIG_H */ #endif diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 4c111b86..b6038a06 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -12,7 +12,7 @@ // constructor and destructor //---------------------------------------------------------------------- -FDialog::FDialog(FWidget* parent) +FDialog::FDialog (FWidget* parent) : FWindow(parent) , tb_text() , result_code(FDialog::Reject) @@ -26,6 +26,7 @@ FDialog::FDialog(FWidget* parent) , move_size_item() , zoom_item() , close_item() + , tooltip() { init(); } @@ -45,6 +46,7 @@ FDialog::FDialog (const FString& txt, FWidget* parent) , move_size_item() , zoom_item() , close_item() + , tooltip(0) { init(); } @@ -103,6 +105,7 @@ void FDialog::init() createArea (vwin); addDialog(this); addWindow(this); + alwaysOnTop(); setActiveWindow(this); setTransparentShadow(); @@ -173,7 +176,7 @@ void FDialog::drawBorder() int y1 = 2; int y2 = 1 + getHeight() - 1; - if ( (getMoveSizeMode() || ! resize_click_pos.isNull()) && ! isZoomed() ) + if ( (getMoveSizeWidget() || ! resize_click_pos.isNull()) && ! isZoomed() ) setColor (wc.dialog_resize_fg, getBackgroundColor()); else setColor(); @@ -203,29 +206,7 @@ void FDialog::drawBorder() } else { - printPos (x1, y1); - print (fc::BoxDrawingsDownAndRight); // ┌ - - for (int x=x1+1; x < x2; x++) - print (fc::BoxDrawingsHorizontal); // ─ - - print (fc::BoxDrawingsDownAndLeft); // ┐ - printPos (x1, y2); - print (fc::BoxDrawingsUpAndRight); // └ - - for (int x=x1+1; x < x2; x++) - print (fc::BoxDrawingsHorizontal); // ─ - - print (fc::BoxDrawingsUpAndLeft); // ┘ - - for (int y=y1+1; y < y2; y++) - { - printPos (x1, y); - print (fc::BoxDrawingsVertical); // │ - printPos (x2, y); - print (fc::BoxDrawingsVertical); // │ - } - + FWidget::drawBorder(x1, y1, x2, y2); } } @@ -478,25 +459,33 @@ void FDialog::setZoomItem() move_size_item->setEnable(); } } -#include "fmessagebox.h" + //---------------------------------------------------------------------- void FDialog::cb_move (FWidget*, void*) { if ( isZoomed() ) return; - setMoveSizeMode(true); + setMoveSizeWidget(this); save_geometry = getGeometry(); - redraw(); + tooltip = new FToolTip(this); - // Tooltip - // ┌──────────────────────────┐ - // │ Arrow keys: Move │ - // │Meta + Arrow keys: Resize │ - // │ Enter: Done │ - // │ Esc: Cancel │ - // └──────────────────────────┘ + if ( isResizeable() ) + { + tooltip->setText ( " Arrow keys: Move\n" + "Meta + Arrow keys: Resize\n" + " Enter: Done\n" + " Esc: Cancel" ); + } + else + { + tooltip->setText ( "Arrow keys: Move\n" + " Enter: Done\n" + " Esc: Cancel" ); + } + + tooltip->show(); } //---------------------------------------------------------------------- @@ -575,6 +564,14 @@ void FDialog::drawDialogShadow() //---------------------------------------------------------------------- void FDialog::draw() { + if ( tooltip && ! getMoveSizeWidget() ) + { + if ( tooltip ) + delete tooltip; + + tooltip = 0; + } + updateVTerm(false); // fill the background setColor(); @@ -634,7 +631,7 @@ void FDialog::onKeyPress (FKeyEvent* ev) selectFirstMenuItem(); } - if ( getMoveSizeMode() ) + if ( getMoveSizeWidget() ) { switch ( ev->key() ) { @@ -696,14 +693,24 @@ void FDialog::onKeyPress (FKeyEvent* ev) case fc::Fkey_return: case fc::Fkey_enter: - setMoveSizeMode(false); + setMoveSizeWidget(0); + + if ( tooltip ) + delete tooltip; + + tooltip = 0; redraw(); ev->accept(); break; case fc::Fkey_escape: case fc::Fkey_escape_mintty: - setMoveSizeMode(false); + setMoveSizeWidget(0); + + if ( tooltip ) + delete tooltip; + + tooltip = 0; move (save_geometry.getPos()); if ( isResizeable() ) @@ -1141,13 +1148,25 @@ void FDialog::onWindowInactive (FEvent*) //---------------------------------------------------------------------- void FDialog::onWindowRaised (FEvent*) { - widgetList::const_iterator iter, end; - if ( ! (isVisible() && isShown()) ) return; putArea (getTermPos(), vwin); + // handle always-on-top windows + if ( always_on_top_list && ! always_on_top_list->empty() ) + { + widgetList::const_iterator iter, end; + iter = always_on_top_list->begin(); + end = always_on_top_list->end(); + + while ( iter != end ) + { + putArea ((*iter)->getTermPos(), (*iter)->getVWin()); + ++iter; + } + } + if ( ! window_list ) return; diff --git a/src/fdialog.h b/src/fdialog.h index 755475d9..31f043bd 100644 --- a/src/fdialog.h +++ b/src/fdialog.h @@ -30,6 +30,7 @@ #include "fmenu.h" #include "fmenuitem.h" +#include "ftooltip.h" #include "fwindow.h" @@ -62,6 +63,7 @@ class FDialog : public FWindow FMenuItem* move_size_item; FMenuItem* zoom_item; FMenuItem* close_item; + FToolTip* tooltip; private: // Disable copy constructor @@ -154,7 +156,8 @@ class FDialog : public FWindow void setText (const FString&); private: - friend class FMenu; + // Friend function from FMenu + friend void FMenu::hideSuperMenus(); }; #pragma pack(pop) diff --git a/src/fenum.h b/src/fenum.h index 280f8190..b552d6d3 100644 --- a/src/fenum.h +++ b/src/fenum.h @@ -61,8 +61,9 @@ class fc window_widget = 0x00000080, dialog_widget = 0x00000100, menu_widget = 0x00000200, - flat = 0x00000400, - no_underline = 0x00000800 + always_on_top = 0x00000400, + flat = 0x00000800, + no_underline = 0x00001000 }; // internal character encoding diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index f7443129..198d3847 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -27,7 +27,7 @@ static bool sortDirFirst (const dir_entry &lhs, const dir_entry &rhs) // constructors and destructor //---------------------------------------------------------------------- -FFileDialog::FFileDialog(FWidget* parent) +FFileDialog::FFileDialog (FWidget* parent) : FDialog(parent) , directory_stream(0) , dir_entries() diff --git a/src/ffiledialog.h b/src/ffiledialog.h index fc42d27e..84b6dadd 100644 --- a/src/ffiledialog.h +++ b/src/ffiledialog.h @@ -1,5 +1,5 @@ // File: ffiledialog.h -// Provides: class FFileDialog.h +// Provides: class FFileDialog // // Inheritance diagram // ═══════════════════ diff --git a/src/final.h b/src/final.h index 4e75331e..243141bd 100644 --- a/src/final.h +++ b/src/final.h @@ -4,31 +4,32 @@ #define _FINAL_H #include "fapp.h" -#include "fterm.h" -#include "fwidget.h" -#include "fpoint.h" -#include "frect.h" -#include "fstring.h" -#include "fdialog.h" -#include "flabel.h" -#include "fbutton.h" -#include "fradiobutton.h" -#include "fcheckbox.h" -#include "fswitch.h" #include "fbuttongroup.h" -#include "flistbox.h" -#include "ftextview.h" -#include "flineedit.h" -#include "fmenu.h" -#include "fdialoglistmenu.h" -#include "fmenubar.h" -#include "fmenuitem.h" +#include "fbutton.h" +#include "fcheckbox.h" #include "fcheckmenuitem.h" -#include "fradiomenuitem.h" -#include "fstatusbar.h" -#include "fscrollbar.h" -#include "fprogressbar.h" -#include "fmessagebox.h" +#include "fdialog.h" +#include "fdialoglistmenu.h" #include "ffiledialog.h" +#include "flabel.h" +#include "flineedit.h" +#include "flistbox.h" +#include "fmenubar.h" +#include "fmenu.h" +#include "fmenuitem.h" +#include "fmessagebox.h" +#include "fpoint.h" +#include "fprogressbar.h" +#include "fradiobutton.h" +#include "fradiomenuitem.h" +#include "frect.h" +#include "fscrollbar.h" +#include "fstatusbar.h" +#include "fstring.h" +#include "fswitch.h" +#include "fterm.h" +#include "ftextview.h" +#include "ftooltip.h" +#include "fwidget.h" #endif // _FINAL_H diff --git a/src/fmenu.cpp b/src/fmenu.cpp index 82725724..f1e2419e 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -107,8 +107,8 @@ void FMenu::init(FWidget* parent) setMenuWidget(); setGeometry (1, 1, 10, 2, false); // initialize geometry values setTransparentShadow(); - setMenuWidget(); addWindow(this); + alwaysOnTop(); hide(); setForegroundColor (wc.menu_active_fg); @@ -595,38 +595,24 @@ void FMenu::draw() clearArea(); drawBorder(); drawItems(); + drawMenuShadow(); if ( isMonochron() ) setReverse(false); - if ( (flags & fc::shadow) != 0 ) - { - term_area* area = 0; - FWindow* area_widget = getWindowWidget(this); - drawMenuShadow(); - - if ( area_widget ) - { - area = area_widget->getVWin(); - - if ( area ) - putArea (getTermX(), getTermY(), area); - } - } - else - updateVTerm(true); + updateVTerm(true); } //---------------------------------------------------------------------- void FMenu::drawBorder() { - int x1 = 1; - int x2 = 1 + getWidth() - 1; - int y1 = 1; - int y2 = 1 + getHeight() - 1; - if ( isNewFont() ) { + int x1 = 1; + int x2 = 1 + getWidth() - 1; + int y1 = 1; + int y2 = 1 + getHeight() - 1; + printPos (x1, y1); print (fc::NF_border_corner_upper_left); // ⎡ @@ -658,28 +644,7 @@ void FMenu::drawBorder() } else { - printPos (x1, y1); - print (fc::BoxDrawingsDownAndRight); // ┌ - - for (int x=x1+1; x < x2; x++) - print (fc::BoxDrawingsHorizontal); // ─ - - print (fc::BoxDrawingsDownAndLeft); // ┐ - printPos (x1, y2); - print (fc::BoxDrawingsUpAndRight); // └ - - for (int x=x1+1; x < x2; x++) - print (fc::BoxDrawingsHorizontal); // ─ - - print (fc::BoxDrawingsUpAndLeft); // ┘ - - for (int y=y1+1; y < y2; y++) - { - printPos (x1, y); - print (fc::BoxDrawingsVertical); // │ - printPos (x2, y); - print (fc::BoxDrawingsVertical); // │ - } + FWidget::drawBorder(); } } diff --git a/src/fmenu.h b/src/fmenu.h index c521f25d..f60d6f99 100644 --- a/src/fmenu.h +++ b/src/fmenu.h @@ -35,7 +35,6 @@ #include "fmenulist.h" #include "fmenuitem.h" - //---------------------------------------------------------------------- // class FMenu //---------------------------------------------------------------------- diff --git a/src/fmenuitem.h b/src/fmenuitem.h index 8db0bc74..ca4da3a2 100644 --- a/src/fmenuitem.h +++ b/src/fmenuitem.h @@ -29,6 +29,7 @@ #include "fwidget.h" +// class forward declaration class FDialog; class FMenu; class FMenuList; diff --git a/src/fmessagebox.cpp b/src/fmessagebox.cpp index 42884522..12644fbf 100644 --- a/src/fmessagebox.cpp +++ b/src/fmessagebox.cpp @@ -24,7 +24,7 @@ static const char* button_text[] = // constructors and destructor //---------------------------------------------------------------------- -FMessageBox::FMessageBox(FWidget* parent) +FMessageBox::FMessageBox (FWidget* parent) : FDialog(parent) , headline_text() , text() diff --git a/src/fobject.cpp b/src/fobject.cpp index ee0643b5..da9e5302 100644 --- a/src/fobject.cpp +++ b/src/fobject.cpp @@ -4,7 +4,7 @@ #include "fobject.h" // static class attributes -bool FObject::modify_timer; +bool FObject::timer_modify_lock; FObject::TimerList* FObject::timer_list = 0; @@ -26,7 +26,7 @@ FObject::FObject (FObject* parent) if ( parent == 0 ) { - modify_timer = false; + timer_modify_lock = false; timer_list = new TimerList(); } else @@ -141,7 +141,7 @@ int FObject::addTimer (int interval) timeval currentTime; int id = 1; - modify_timer = true; + timer_modify_lock = true; if ( ! timer_list ) timer_list = new TimerList(); @@ -182,7 +182,7 @@ int FObject::addTimer (int interval) ++iter; timer_list->insert (iter, t); - modify_timer = false; + timer_modify_lock = false; return id; } @@ -195,7 +195,7 @@ bool FObject::delTimer (int id) if ( id <= 0 || id > int(timer_list->size()) ) return false; - modify_timer = true; + timer_modify_lock = true; iter = timer_list->begin(); end = timer_list->end(); @@ -205,11 +205,11 @@ bool FObject::delTimer (int id) if ( iter != end ) { timer_list->erase(iter); - modify_timer = false; + timer_modify_lock = false; return true; } - modify_timer = false; + timer_modify_lock = false; return false; } @@ -224,7 +224,7 @@ bool FObject::delOwnTimer() if ( timer_list->empty() ) return false; - modify_timer = true; + timer_modify_lock = true; iter = timer_list->begin(); while ( iter != timer_list->end() ) @@ -235,7 +235,7 @@ bool FObject::delOwnTimer() ++iter; } - modify_timer = false; + timer_modify_lock = false; return true; } @@ -248,9 +248,9 @@ bool FObject::delAllTimer() if ( timer_list->empty() ) return false; - modify_timer = true; + timer_modify_lock = true; timer_list->clear(); - modify_timer = false; + timer_modify_lock = false; return true; } diff --git a/src/fobject.h b/src/fobject.h index 9c38df4c..b1b40ad8 100644 --- a/src/fobject.h +++ b/src/fobject.h @@ -65,8 +65,7 @@ class FObject FObject* parent_obj; object_list children_list; bool has_parent; - static bool modify_timer; - friend class FApplication; + static bool timer_modify_lock; public: // Constructor @@ -90,6 +89,7 @@ class FObject bool delTimer (int); bool delOwnTimer(); bool delAllTimer(); + bool isTimerInUpdating() const; // Event handler virtual bool event (FEvent*); @@ -134,6 +134,10 @@ inline bool FObject::hasChildren() const inline int FObject::numOfChildren() const { return int(children_list.size()); } +//---------------------------------------------------------------------- +inline bool FObject::isTimerInUpdating() const +{ return timer_modify_lock; } + //---------------------------------------------------------------------- // Operator functions for timeval diff --git a/src/fstatusbar.h b/src/fstatusbar.h index 22fbf065..35299fda 100644 --- a/src/fstatusbar.h +++ b/src/fstatusbar.h @@ -34,6 +34,7 @@ #include "fwindow.h" +// class forward declaration class FStatusBar; //---------------------------------------------------------------------- diff --git a/src/fterm.h b/src/fterm.h index bd3a46a7..673b88b4 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -88,6 +88,7 @@ // parseKeyString return value #define NEED_MORE_DATA -1 +// class forward declaration class FWidget; //---------------------------------------------------------------------- @@ -283,6 +284,7 @@ class FTerm static uInt charEncode (uInt, fc::encoding); static uInt cp437_to_unicode (uChar); static void signal_handler (int); + // Friend classes friend class FWidget; friend class FApplication; @@ -320,6 +322,7 @@ class FTerm FTerm::term_area* getVWin() const; static bool isKeyTimeout (timeval*, register long); static int parseKeyString (char*, int, timeval*); + bool& unprocessedInput() const; int getLineNumber(); int getColumnNumber(); static FString getKeyName (int); @@ -509,6 +512,10 @@ inline const char* FTerm::getClassName() const inline FTerm::term_area* FTerm::getVWin() const { return vwin; } +//---------------------------------------------------------------------- +inline bool& FTerm::unprocessedInput() const +{ return input_data_pending; } + //---------------------------------------------------------------------- inline int FTerm::getLineNumber() { diff --git a/src/ftogglebutton.h b/src/ftogglebutton.h index 457535b0..fbe81fd2 100644 --- a/src/ftogglebutton.h +++ b/src/ftogglebutton.h @@ -1,5 +1,5 @@ // File: ftogglebutton.h -// Provides: class FToggleButton.h +// Provides: class FToggleButton // // Inheritance diagram // ═══════════════════ @@ -26,6 +26,7 @@ #include "fwidget.h" +// class forward declaration class FButtonGroup; //---------------------------------------------------------------------- diff --git a/src/ftooltip.cpp b/src/ftooltip.cpp new file mode 100644 index 00000000..2690e0e9 --- /dev/null +++ b/src/ftooltip.cpp @@ -0,0 +1,194 @@ +// File: ftooltip.cpp +// Provides: class FToolTip + +#include "fapp.h" +#include "ftooltip.h" + + +//---------------------------------------------------------------------- +// class FToolTip +//---------------------------------------------------------------------- + +// constructor and destructor +//---------------------------------------------------------------------- +FToolTip::FToolTip (FWidget* parent) + : FWindow(parent) + , text() + , max_line_width(0) +{ + init(); +} + +//---------------------------------------------------------------------- +FToolTip::FToolTip (const FString& txt, FWidget* parent) + : FWindow(parent) + , text(txt) + , max_line_width(0) +{ + init(); +} + +//---------------------------------------------------------------------- +FToolTip::~FToolTip() // destructor +{ + FApplication* fapp = static_cast(getRootWidget()); + + if ( ! fapp->isQuit() ) + { + FWidget* parent = getParentWidget(); + FWindow* parent_win = 0; + + if ( parent ) + parent_win = getWindowWidget(parent); + + if ( parent_win ) + setActiveWindow (parent_win); + else + switchToPrevWindow(); + } + + delWindow(this); + + if ( ! fapp->isQuit() ) + { + const FRect& t_geometry = getTermGeometryWithShadow(); + restoreVTerm (t_geometry); + } + + if ( vwin != 0 ) + { + if ( vwin->changes != 0 ) + delete[] vwin->changes; + + if ( vwin->text != 0 ) + delete[] vwin->text; + + delete vwin; + } +} + + +// private methods of FToolTip +//---------------------------------------------------------------------- +void FToolTip::init() +{ + setAlwaysOnTop(); + ignorePadding(); + // initialize geometry values + setGeometry (1, 1, 3, 3, false); + setMinimumSize (3, 3); + createArea (vwin); + addWindow(this); + alwaysOnTop(); + + setForegroundColor (wc.tooltip_fg); + setBackgroundColor (wc.tooltip_bg); + + calculateDimensions(); +} + +//---------------------------------------------------------------------- +void FToolTip::calculateDimensions() +{ + int x, y, w, h; + FWidget* r = getRootWidget(); + text_split = text.split("\n"); + text_num_lines = uInt(text_split.size()); + text_components = &text_split[0]; + max_line_width = 0; + + for (uInt i=0; i < text_num_lines; i++) + { + uInt len = text_components[i].getLength(); + + if ( len > max_line_width ) + max_line_width = len; + } + + h = int(text_num_lines) + 2 ; + w = int(max_line_width + 4); + + if ( r ) + { + x = 1 + int((r->getWidth()-w)/2); + y = 1 + int((r->getHeight()-h)/2); + } + else + x = y = 1; + + setGeometry (x, y, w, h); +} + +//---------------------------------------------------------------------- +void FToolTip::adjustSize() +{ + calculateDimensions(); + FWindow::adjustSize(); +} + + +// public methods of FToolTip +//---------------------------------------------------------------------- +void FToolTip::draw() +{ + updateVTerm(false); + setColor(); + + if ( getMaxColor() < 16 ) + setBold(); + + clearArea(); + drawBorder(); + + for (int i=0; i < int(text_num_lines); i++) + { + printPos (3, 2 + i); + print(text_components[i]); + } + + unsetBold(); + updateVTerm(true); +} + +//---------------------------------------------------------------------- +void FToolTip::show() +{ + if ( ! isVisible() ) + return; + + FWindow::show(); +} + +//---------------------------------------------------------------------- +void FToolTip::hide() +{ + FWindow::hide(); +} + +//---------------------------------------------------------------------- +void FToolTip::onMouseDown (FMouseEvent*) +{ + setClickedWidget(0); + close(); +} + +//---------------------------------------------------------------------- +void FToolTip::setText (const FString& txt) +{ + text = txt; + calculateDimensions(); +} + +//---------------------------------------------------------------------- +void FToolTip::setText (const std::string& txt) +{ + FString message_text(txt); + setText( message_text ); +} + +//---------------------------------------------------------------------- +void FToolTip::setText (const char* txt) +{ + FString message_text(txt); + setText( message_text ); +} diff --git a/src/ftooltip.h b/src/ftooltip.h new file mode 100644 index 00000000..00373fbe --- /dev/null +++ b/src/ftooltip.h @@ -0,0 +1,87 @@ +// File: ftooltip.h +// Provides: class FTooltip +// +// Inheritance diagram +// ═══════════════════ +// +// ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏ +// ▕ FObject ▏ ▕ FTerm ▏ +// ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏ +// ▲ ▲ +// │ │ +// └─────┬─────┘ +// │ +// ▕▔▔▔▔▔▔▔▔▔▏ +// ▕ FWidget ▏ +// ▕▁▁▁▁▁▁▁▁▁▏ +// ▲ +// │ +// ▕▔▔▔▔▔▔▔▔▔▏ +// ▕ FWindow ▏ +// ▕▁▁▁▁▁▁▁▁▁▏ +// ▲ +// │ +// ▕▔▔▔▔▔▔▔▔▔▔▏ +// ▕ FToolTip ▏ +// ▕▁▁▁▁▁▁▁▁▁▁▏ + +#ifndef _FTOOLTIP_H +#define _FTOOLTIP_H + +#include "fwindow.h" + + +//---------------------------------------------------------------------- +// class FToolTip +//---------------------------------------------------------------------- + +#pragma pack(push) +#pragma pack(1) + +class FToolTip : public FWindow +{ + private: + FString text; + FString* text_components; + std::vector text_split; + uInt max_line_width; + uInt text_num_lines; + + private: + // Disable copy constructor + FToolTip (const FToolTip&); + // Disable assignment operator (=) + FToolTip& operator = (const FToolTip&); + + void init(); + void calculateDimensions(); + virtual void adjustSize(); + + public: + // Constructor + explicit FToolTip (FWidget* = 0); + FToolTip (const FString&, FWidget* = 0); + // Destructor + virtual ~FToolTip (); + + const char* getClassName() const; + virtual void draw(); + void show(); + void hide(); + // Event handler + void onMouseDown (FMouseEvent*); + const FString getText() const; + void setText (const FString&); + void setText (const std::string&); + void setText (const char*); +}; +#pragma pack(pop) + + +// FToolTip inline functions +//---------------------------------------------------------------------- +inline const char* FToolTip::getClassName() const +{ return "FToolTip"; } + + +#endif // _FTOOLTIP_H diff --git a/src/fwidget.cpp b/src/fwidget.cpp index a833d9d1..ac5fdc90 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -19,6 +19,7 @@ FWidget* FWidget::show_root_widget = 0; FWidget* FWidget::redraw_root_widget = 0; FWidget::widgetList* FWidget::window_list = 0; FWidget::widgetList* FWidget::dialog_list = 0; +FWidget::widgetList* FWidget::always_on_top_list = 0; FWidget::widgetList* FWidget::close_widget = 0; FWidget::widget_colors FWidget::wc; @@ -32,7 +33,7 @@ FWidget::FWidget (FWidget* parent) : FObject(parent) , callback_objects() , member_callback_objects() - , accelerator_list() + , accelerator_list(0) , flags(0) , enable(true) , visible(true) @@ -120,9 +121,10 @@ FWidget::~FWidget() // destructor //---------------------------------------------------------------------- void FWidget::init() { - window_list = new widgetList(); - dialog_list = new widgetList(); - close_widget = new widgetList(); + window_list = new widgetList(); + dialog_list = new widgetList(); + always_on_top_list = new widgetList(); + close_widget = new widgetList(); // determine width and height of the terminal getTermSize(); @@ -165,6 +167,12 @@ void FWidget::finish() dialog_list = 0; } + if ( always_on_top_list ) + { + delete always_on_top_list; + always_on_top_list = 0; + } + if ( window_list ) { delete window_list; @@ -192,6 +200,8 @@ void FWidget::setColorTheme() wc.error_box_fg = fc::White; wc.error_box_emphasis_fg = fc::Yellow; wc.error_box_bg = fc::LightRed; + wc.tooltip_fg = fc::Black; + wc.tooltip_bg = fc::Yellow; wc.shadow_fg = fc::Black; wc.shadow_bg = fc::LightGray; // only for transparent shadow wc.current_element_focus_fg = fc::White; @@ -283,6 +293,8 @@ void FWidget::setColorTheme() wc.error_box_fg = fc::Black; wc.error_box_emphasis_fg = fc::Red; wc.error_box_bg = fc::LightGray; + wc.tooltip_fg = fc::LightGray; + wc.tooltip_bg = fc::Cyan; wc.shadow_fg = fc::Black; wc.shadow_bg = fc::LightGray; // only for transparent shadow wc.current_element_focus_fg = fc::LightGray; @@ -390,7 +402,12 @@ void FWidget::adjustSize() FWidget* p = getParentWidget(); if ( isWindowWidget() ) - offset = rootObject->client_offset; + { + if ( ignore_padding && ! isDialogWidget() ) + setTermOffset(); + else + offset = rootObject->client_offset; + } else if ( ignore_padding && p ) { offset.setCoordinates ( p->getTermX() - 1 @@ -890,7 +907,7 @@ FWidget* FWidget::getMainWidget() } //---------------------------------------------------------------------- -void FWidget::setMainWidget(FWidget* obj) +void FWidget::setMainWidget (FWidget* obj) { FApplication* fapp = static_cast(rootObject); fapp->setMainWidget(obj); @@ -936,7 +953,7 @@ FWidget* FWidget::getFocusWidget() const } //---------------------------------------------------------------------- -void FWidget::setFocusWidget(FWidget* obj) +void FWidget::setFocusWidget (FWidget* obj) { FApplication::focus_widget = obj; } @@ -949,11 +966,23 @@ FWidget* FWidget::getClickedWidget() } //---------------------------------------------------------------------- -void FWidget::setClickedWidget(FWidget* obj) +void FWidget::setClickedWidget (FWidget* obj) { FApplication::clicked_widget = obj; } +//---------------------------------------------------------------------- +FWidget* FWidget::getMoveSizeWidget() +{ + return FApplication::move_size_widget; +} + +//---------------------------------------------------------------------- +void FWidget::setMoveSizeWidget (FWidget* obj) +{ + FApplication::move_size_widget = obj; +} + //---------------------------------------------------------------------- FWidget* FWidget::getOpenMenu() { @@ -962,23 +991,11 @@ FWidget* FWidget::getOpenMenu() } //---------------------------------------------------------------------- -void FWidget::setOpenMenu(FWidget* obj) +void FWidget::setOpenMenu (FWidget* obj) { FApplication::open_menu = obj; } -//---------------------------------------------------------------------- -bool FWidget::getMoveSizeMode() -{ - return FApplication::move_size_mode; -} - -//---------------------------------------------------------------------- -void FWidget::setMoveSizeMode (bool on) -{ - FApplication::move_size_mode = on; -} - //---------------------------------------------------------------------- int FWidget::numOfFocusableChildren() { @@ -2353,7 +2370,7 @@ std::vector& FWidget::doubleFlatLine_ref (int side) } //---------------------------------------------------------------------- -void FWidget::drawBorder (int x1, int x2, int y1, int y2) +void FWidget::drawBorder (int x1, int y1, int x2, int y2) { if ( x1 > x2 ) std::swap (x1, x2); @@ -2373,11 +2390,6 @@ void FWidget::drawBorder (int x1, int x2, int y1, int y2) if ( y2 > getHeight() ) y2 = getHeight(); - if ( FWidget* p = getParentWidget() ) - setColor (wc.dialog_fg, p->getBackgroundColor()); - else - setColor (wc.dialog_fg, wc.dialog_bg); - if ( isNewFont() ) { printPos (x1, y1); diff --git a/src/fwidget.h b/src/fwidget.h index 16810b2f..bf4846ee 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -77,6 +77,7 @@ reinterpret_cast((i)) \ , reinterpret_cast((h)) +// class forward declaration class FStatusBar; class FMenuBar; @@ -93,6 +94,7 @@ class FWidget : public FObject, public FTerm typedef std::vector widgetList; static widgetList* window_list; static widgetList* dialog_list; + static widgetList* always_on_top_list; static widgetList* close_widget; typedef void (*FCallback)(FWidget*, void*); @@ -168,6 +170,8 @@ class FWidget : public FObject, public FTerm short error_box_fg; short error_box_emphasis_fg; short error_box_bg; + short tooltip_fg; + short tooltip_bg; short shadow_fg; short shadow_bg; short toggle_button_active_focus_fg; @@ -363,13 +367,13 @@ class FWidget : public FObject, public FTerm static FWidget* childWidgetAt (FWidget*, const FPoint&); static FWidget* childWidgetAt (FWidget*, int, int); virtual FWidget* getFocusWidget() const; - virtual void setFocusWidget(FWidget*); + virtual void setFocusWidget (FWidget*); static FWidget* getClickedWidget(); - static void setClickedWidget(FWidget*); + static void setClickedWidget (FWidget*); + static FWidget* getMoveSizeWidget(); + static void setMoveSizeWidget (FWidget*); static FWidget* getOpenMenu(); - static void setOpenMenu(FWidget*); - static bool getMoveSizeMode(); - static void setMoveSizeMode (bool); + static void setOpenMenu (FWidget*); int numOfFocusableChildren(); FWidget* getParentWidget() const; bool isRootWidget() const; @@ -1218,7 +1222,7 @@ inline void FWidget::unsetDoubleFlatLine (int side, int pos) //---------------------------------------------------------------------- inline void FWidget::drawBorder() -{ drawBorder (1, getWidth(), 1, getHeight()); } +{ drawBorder (1, 1, getWidth(), getHeight()); } // NewFont elements diff --git a/src/fwindow.cpp b/src/fwindow.cpp index dbc3b9bd..7e672384 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -30,6 +30,33 @@ FWindow::~FWindow() // destructor { if ( previous_widget == this ) previous_widget = 0; + + if ( isAlwaysOnTop() ) + deleteFromAlwaysOnTopList (this); +} + + +// private methods of FWindow +//---------------------------------------------------------------------- +void FWindow::deleteFromAlwaysOnTopList (FWidget* obj) +{ + // delete the window object obj from the always-on-top list + if ( always_on_top_list && ! always_on_top_list->empty() ) + { + widgetList::iterator iter; + iter = always_on_top_list->begin(); + + while ( iter != always_on_top_list->end() ) + { + if ( *iter == obj ) + { + always_on_top_list->erase (iter); + return; + } + + ++iter; + } + } } @@ -58,6 +85,7 @@ bool FWindow::event (FEvent* ev) default: return FWidget::event(ev); } + return true; } @@ -339,6 +367,7 @@ bool FWindow::raiseWindow (FWidget* obj) window_list->push_back (obj); FEvent ev(fc::WindowRaised_Event); FApplication::sendEvent(obj, &ev); + alwaysOnTop(); return true; } @@ -388,6 +417,24 @@ bool FWindow::lowerWindow (FWidget* obj) return false; } +//---------------------------------------------------------------------- +void FWindow::alwaysOnTop() +{ + // Raise all always-on-top windows + if ( always_on_top_list && ! always_on_top_list->empty() ) + { + widgetList::iterator iter; + iter = always_on_top_list->begin(); + + while ( iter != always_on_top_list->end() ) + { + delWindow (*iter); + addWindow (*iter); + ++iter; + } + } +} + //---------------------------------------------------------------------- bool FWindow::zoomWindow() { @@ -582,3 +629,28 @@ bool FWindow::isHiddenWindow() const else return false; } + +//---------------------------------------------------------------------- +bool FWindow::setAlwaysOnTop (bool on) +{ + if ( isAlwaysOnTop() == on ) + return true; + + if ( on ) + { + flags |= fc::always_on_top; + + if ( always_on_top_list ) + { + deleteFromAlwaysOnTopList (this); + always_on_top_list->push_back (this); + } + } + else + { + flags &= ~fc::always_on_top; + deleteFromAlwaysOnTopList (this); + } + + return on; +} diff --git a/src/fwindow.h b/src/fwindow.h index 6e3000a5..1a55356a 100644 --- a/src/fwindow.h +++ b/src/fwindow.h @@ -1,5 +1,5 @@ // File: fwindow.h -// Provides: class FWindow.h +// Provides: class FWindow // // Inheritance diagram // ═══════════════════ @@ -58,6 +58,8 @@ class FWindow : public FWidget // Disable assignment operator (=) FWindow& operator = (const FWindow&); + void deleteFromAlwaysOnTopList (FWidget*); + protected: // Event handlers bool event (FEvent*); @@ -94,6 +96,7 @@ class FWindow : public FWidget bool raiseWindow (); static bool lowerWindow (FWidget*); bool lowerWindow (); + static void alwaysOnTop(); bool zoomWindow (); bool isZoomed() const; bool setWindowWidget (bool); @@ -110,6 +113,10 @@ class FWindow : public FWidget bool deactivateWindow(); bool isActiveWindow() const; bool isHiddenWindow() const; + bool setAlwaysOnTop (bool); + bool setAlwaysOnTop(); + bool unsetAlwaysOnTop(); + bool isAlwaysOnTop(); }; #pragma pack(pop) @@ -155,5 +162,17 @@ inline bool FWindow::deactivateWindow() inline bool FWindow::isActiveWindow() const { return window_active; } +//---------------------------------------------------------------------- +inline bool FWindow::setAlwaysOnTop() +{ return setAlwaysOnTop(true); } + +//---------------------------------------------------------------------- +inline bool FWindow::unsetAlwaysOnTop() +{ return setAlwaysOnTop(false); } + +//---------------------------------------------------------------------- +inline bool FWindow::isAlwaysOnTop() +{ return ((flags & fc::always_on_top) != 0); } + #endif // _FWINDOW_H