From 75b452bf5261f1764ff066e98c6b7d5c98ed422b Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Wed, 2 Nov 2016 00:37:58 +0100 Subject: [PATCH] The class declaration now has a consistent order --- ChangeLog | 3 + doc/coding-style.txt | 38 + src/fapp.cpp | 448 +++--- src/fapp.h | 224 +-- src/fbutton.cpp | 732 +++++----- src/fbutton.h | 128 +- src/fbuttongroup.cpp | 789 +++++------ src/fbuttongroup.h | 94 +- src/fcheckbox.h | 24 +- src/fcheckmenuitem.h | 26 +- src/fdialog.cpp | 1455 +++++++++---------- src/fdialog.h | 210 +-- src/fdialoglistmenu.h | 20 +- src/ffiledialog.cpp | 717 +++++----- src/ffiledialog.h | 130 +- src/flabel.cpp | 404 +++--- src/flabel.h | 122 +- src/flineedit.cpp | 561 ++++---- src/flineedit.h | 162 ++- src/flistbox.cpp | 2648 +++++++++++++++++----------------- src/flistbox.h | 220 +-- src/fmenu.cpp | 1398 +++++++++--------- src/fmenu.h | 207 +-- src/fmenubar.cpp | 900 ++++++------ src/fmenubar.h | 85 +- src/fmenuitem.cpp | 680 ++++----- src/fmenuitem.h | 229 +-- src/fmenulist.cpp | 88 +- src/fmenulist.h | 73 +- src/fmessagebox.cpp | 380 ++--- src/fmessagebox.h | 127 +- src/fobject.cpp | 1 + src/fobject.h | 80 +- src/foptiattr.cpp | 1736 +++++++++++------------ src/foptiattr.h | 324 ++--- src/foptimove.cpp | 490 +++---- src/foptimove.h | 111 +- src/fpoint.cpp | 50 +- src/fpoint.h | 79 +- src/fprogressbar.cpp | 269 ++-- src/fprogressbar.h | 61 +- src/fradiobutton.h | 24 +- src/fradiomenuitem.h | 26 +- src/frect.h | 45 +- src/fscrollbar.cpp | 789 +++++------ src/fscrollbar.h | 100 +- src/fstatusbar.cpp | 883 ++++++------ src/fstatusbar.h | 221 +-- src/fstring.cpp | 870 ++++++------ src/fstring.h | 250 ++-- src/fswitch.cpp | 119 +- src/fswitch.h | 32 +- src/fterm.cpp | 2882 +++++++++++++++++++------------------- src/fterm.h | 560 ++++---- src/ftermcap.h | 41 +- src/ftextview.cpp | 802 +++++------ src/ftextview.h | 105 +- src/ftogglebutton.cpp | 642 +++++---- src/ftogglebutton.h | 140 +- src/ftooltip.cpp | 134 +- src/ftooltip.h | 56 +- src/fvterm.cpp | 2569 ++++++++++++++++----------------- src/fvterm.h | 540 +++---- src/fwidget.cpp | 2674 +++++++++++++++++------------------ src/fwidget.h | 806 +++++------ src/fwindow.cpp | 530 +++---- src/fwindow.h | 246 ++-- test/calculator.cpp | 60 +- test/mandelbrot.cpp | 10 +- test/menu.cpp | 42 +- test/term-attributes.cpp | 54 +- test/timer.cpp | 31 +- test/transparent.cpp | 18 +- test/ui.cpp | 66 +- test/watch.cpp | 32 +- test/windows.cpp | 118 +- 76 files changed, 16745 insertions(+), 16295 deletions(-) create mode 100644 doc/coding-style.txt diff --git a/ChangeLog b/ChangeLog index e61d6a84..9debbf68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2016-11-01 Markus Gans + * The class declaration now has a consistent order + 2016-10-17 Markus Gans * Refactor the VGA attribute controller access code diff --git a/doc/coding-style.txt b/doc/coding-style.txt new file mode 100644 index 00000000..25db2088 --- /dev/null +++ b/doc/coding-style.txt @@ -0,0 +1,38 @@ +============ +Coding style +============ + +Formatting +---------- +* A new line should begin after 72 (max. 80) characters +* Use 2 spaces indent. Do not use tabs! +* Leave a space after the keywords if, switch, while, do, for, and return +* Use one blank line before and afte a for, if, switch, + while, do..while code block +* In parameter lists, leave a space after each comma + +Class declaration order +----------------------- +The declaration section order is: + + * public: + * protected: + * private: + +Each declaration section should be in the following order: + + * Using-declarations (using std::string;) + * Typedefs and Enumerations + * Constants (static const data members) + * Constructors + * Destructor + * Overloaded operators (=, +, -, +=. ...) + * Accessors (getXY) + * Mutators (setXY) + * Inquiries (isXY) + * Methods, including static methods + * Event handler methods + * Callback methods + * Data Members (except static const data members) + + diff --git a/src/fapp.cpp b/src/fapp.cpp index ff4020ca..0b331aa8 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -25,7 +25,7 @@ uChar FApplication::x11_button_state = 0x03; int FApplication::quit_code = 0; bool FApplication::quit_now = false; -std::deque* FApplication::event_queue = 0; +FApplication::eventQueue* FApplication::event_queue = 0; //---------------------------------------------------------------------- // class FApplication @@ -79,6 +79,217 @@ FApplication::~FApplication() // destructor } +// public methods of FApplication +//---------------------------------------------------------------------- +void FApplication::setMainWidget (FWidget* widget) +{ + main_widget = widget; + + if ( widget && ! getFocusWidget() ) + rootObj->focusFirstChild(); +} + +//---------------------------------------------------------------------- +bool FApplication::isQuit() +{ + if ( rootObj ) + return quit_now; + else + return true; +} + +//---------------------------------------------------------------------- +int FApplication::exec() // run +{ + if ( quit_now ) + return EXIT_FAILURE; + + quit_now = false; + quit_code = 0; + + enter_loop(); + return quit_code; +} + +//---------------------------------------------------------------------- +int FApplication::enter_loop() // event loop +{ + bool old_app_exit_loop; + loop_level++; + quit_now = false; + + old_app_exit_loop = app_exit_loop; + app_exit_loop = false; + + while ( ! (quit_now || app_exit_loop) ) + processNextEvent(); + + app_exit_loop = old_app_exit_loop; + loop_level--; + return 0; +} + +//---------------------------------------------------------------------- +void FApplication::exit_loop() +{ + app_exit_loop = true; +} + +//---------------------------------------------------------------------- +void FApplication::exit (int retcode) +{ + if ( ! rootObj ) // no global app object + return; + + if ( quit_now ) // don't overwrite quit code + return; + + quit_now = true; + quit_code = retcode; +} + +//---------------------------------------------------------------------- +void FApplication::quit() +{ + FApplication::exit(0); +} + +//---------------------------------------------------------------------- +bool FApplication::sendEvent(FObject* receiver, FEvent* event) +{ + FWidget* widget; + + if ( quit_now || app_exit_loop ) + return false; + + if ( ! receiver ) + return false; + + widget = static_cast(receiver); + + if ( modal_dialogs > 0 ) + { + FWidget* window; + if ( widget->isWindowWidget() ) + window = widget; + else + window = FWindow::getWindowWidget(widget); + + // block events for widgets in non modal windows + if ( window + && (window->getFlags() & fc::modal) == 0 + && ! window->isMenuWidget() ) + { + switch ( event->type() ) + { + case fc::KeyPress_Event: + case fc::KeyUp_Event: + case fc::KeyDown_Event: + case fc::MouseDown_Event: + case fc::MouseUp_Event: + case fc::MouseDoubleClick_Event: + case fc::MouseWheel_Event: + case fc::MouseMove_Event: + case fc::FocusIn_Event: + case fc::FocusOut_Event: + case fc::Accelerator_Event: + return false; + + default: + break; + } + } + } + + // throw away mouse events to disabled widgets + if ( event->type() >= fc::MouseDown_Event + && event->type() <= fc::MouseMove_Event + && ! widget->isEnabled() ) + return false; + + // sends event event directly to receiver + FApplication* w = static_cast(widget); + return w->event(event); // access to a protected base class member +} + +//---------------------------------------------------------------------- +void FApplication::queueEvent (FObject* receiver, FEvent* event) +{ + if ( ! receiver ) + return; + + // queue this event + eventPair Event (receiver, event); + event_queue->push_back(Event); +} + +//---------------------------------------------------------------------- +void FApplication::sendQueuedEvents() +{ + eventQueue* events; + + if ( ! eventInQueue() ) + return; + + events = event_queue; + + while ( ! eventInQueue() ) + { + sendEvent(events->front().first, events->front().second); + events->pop_front(); + } +} + +//---------------------------------------------------------------------- +bool FApplication::eventInQueue() +{ + if ( rootObj ) + return ( ! event_queue->empty() ); + else + return false; +} + +//---------------------------------------------------------------------- +bool FApplication::removeQueuedEvent(FObject* receiver) +{ + bool retval; + eventQueue::iterator iter; + + if ( ! eventInQueue() ) + return false; + + if ( ! receiver ) + return false; + + retval = false; + iter = event_queue->begin(); + + while ( iter != event_queue->end() ) + { + if ( iter->first == receiver ) + { + iter = event_queue->erase(iter); + retval = true; + } + else + ++iter; + } + + return retval; +} + +//---------------------------------------------------------------------- +void FApplication::print_cmd_Options () +{ + std::printf ( "\nFinalCut Options:\n" + " --encoding Sets the character encoding mode\n" + " {UTF8, VT100, PC, ASCII}\n" + " --no-optimized-cursor No cursor optimisation\n" + " --vgafont Set the standard vga 8x16 font\n" + " --newfont Enables the graphical font\n" ); +} + + // private methods of FApplication //---------------------------------------------------------------------- void FApplication::init() @@ -95,7 +306,7 @@ void FApplication::init() #endif zero_point = new FPoint(0,0); - event_queue = new std::deque; + event_queue = new eventQueue; // init arrays with '\0' std::fill_n (k_buf, sizeof(k_buf), '\0'); std::fill_n (fifo_buf, fifo_buf_size, '\0'); @@ -1474,8 +1685,8 @@ void FApplication::processMouseEvent() if ( ! (clicked_widget || is_window_menu) ) FWindow::switchToPrevWindow(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); @@ -1483,24 +1694,24 @@ void FApplication::processMouseEvent() } // unselected menu bar item - if ( ! open_menu && menuBar() - && menuBar()->hasSelectedItem() + if ( ! open_menu && getMenuBar() + && getMenuBar()->hasSelectedItem() && ! b_state.mouse_moved ) { - if ( ! menuBar()->getTermGeometry().contains(mouse_position) ) + if ( ! getMenuBar()->getTermGeometry().contains(mouse_position) ) { - if ( statusBar() ) - statusBar()->clearMessage(); + if ( getStatusBar() ) + getStatusBar()->clearMessage(); - menuBar()->resetMenu(); - menuBar()->redraw(); + getMenuBar()->resetMenu(); + getMenuBar()->redraw(); // No widget was been clicked if ( ! clicked_widget ) FWindow::switchToPrevWindow(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); @@ -1764,214 +1975,3 @@ bool FApplication::processNextEvent() return (num_events > 0); } - - -// public methods of FApplication -//---------------------------------------------------------------------- -void FApplication::print_cmd_Options () -{ - std::printf ( "\nFinalCut Options:\n" - " --encoding Sets the character encoding mode\n" - " {UTF8, VT100, PC, ASCII}\n" - " --no-optimized-cursor No cursor optimisation\n" - " --vgafont Set the standard vga 8x16 font\n" - " --newfont Enables the graphical font\n" ); -} - -//---------------------------------------------------------------------- -void FApplication::setMainWidget (FWidget* widget) -{ - main_widget = widget; - - if ( widget && ! getFocusWidget() ) - rootObj->focusFirstChild(); -} - -//---------------------------------------------------------------------- -int FApplication::exec() // run -{ - if ( quit_now ) - return EXIT_FAILURE; - - quit_now = false; - quit_code = 0; - - enter_loop(); - return quit_code; -} - -//---------------------------------------------------------------------- -int FApplication::enter_loop() // event loop -{ - bool old_app_exit_loop; - loop_level++; - quit_now = false; - - old_app_exit_loop = app_exit_loop; - app_exit_loop = false; - - while ( ! (quit_now || app_exit_loop) ) - processNextEvent(); - - app_exit_loop = old_app_exit_loop; - loop_level--; - return 0; -} - -//---------------------------------------------------------------------- -void FApplication::exit_loop() -{ - app_exit_loop = true; -} - -//---------------------------------------------------------------------- -void FApplication::exit (int retcode) -{ - if ( ! rootObj ) // no global app object - return; - - if ( quit_now ) // don't overwrite quit code - return; - - quit_now = true; - quit_code = retcode; -} - -//---------------------------------------------------------------------- -void FApplication::quit() -{ - FApplication::exit(0); -} - -//---------------------------------------------------------------------- -bool FApplication::isQuit() -{ - if ( rootObj ) - return quit_now; - else - return true; -} - -//---------------------------------------------------------------------- -bool FApplication::sendEvent(FObject* receiver, FEvent* event) -{ - FWidget* widget; - - if ( quit_now || app_exit_loop ) - return false; - - if ( ! receiver ) - return false; - - widget = static_cast(receiver); - - if ( modal_dialogs > 0 ) - { - FWidget* window; - if ( widget->isWindowWidget() ) - window = widget; - else - window = FWindow::getWindowWidget(widget); - - // block events for widgets in non modal windows - if ( window - && (window->getFlags() & fc::modal) == 0 - && ! window->isMenuWidget() ) - { - switch ( event->type() ) - { - case fc::KeyPress_Event: - case fc::KeyUp_Event: - case fc::KeyDown_Event: - case fc::MouseDown_Event: - case fc::MouseUp_Event: - case fc::MouseDoubleClick_Event: - case fc::MouseWheel_Event: - case fc::MouseMove_Event: - case fc::FocusIn_Event: - case fc::FocusOut_Event: - case fc::Accelerator_Event: - return false; - - default: - break; - } - } - } - - // throw away mouse events to disabled widgets - if ( event->type() >= fc::MouseDown_Event - && event->type() <= fc::MouseMove_Event - && ! widget->isEnabled() ) - return false; - - // sends event event directly to receiver - FApplication* w = static_cast(widget); - return w->event(event); // access to a protected base class member -} - -//---------------------------------------------------------------------- -void FApplication::queueEvent (FObject* receiver, FEvent* event) -{ - if ( ! receiver ) - return; - - // queue this event - eventPair Event (receiver, event); - event_queue->push_back(Event); -} - -//---------------------------------------------------------------------- -void FApplication::sendQueuedEvents() -{ - std::deque* events; - - if ( ! eventInQueue() ) - return; - - events = event_queue; - - while ( ! eventInQueue() ) - { - sendEvent(events->front().first, events->front().second); - events->pop_front(); - } -} - -//---------------------------------------------------------------------- -bool FApplication::eventInQueue() -{ - if ( rootObj ) - return ( ! event_queue->empty() ); - else - return false; -} - -//---------------------------------------------------------------------- -bool FApplication::removeQueuedEvent(FObject* receiver) -{ - bool retval; - std::deque::iterator iter; - - if ( ! eventInQueue() ) - return false; - - if ( ! receiver ) - return false; - - retval = false; - iter = event_queue->begin(); - - while ( iter != event_queue->end() ) - { - if ( iter->first == receiver ) - { - iter = event_queue->erase(iter); - retval = true; - } - else - ++iter; - } - - return retval; -} diff --git a/src/fapp.h b/src/fapp.h index 8f65a6f2..8f05a330 100644 --- a/src/fapp.h +++ b/src/fapp.h @@ -54,37 +54,42 @@ class FApplication : public FWidget { public: - typedef std::pair eventPair; - static std::deque* event_queue; + // Constructor + FApplication (int&, char**& ); + + // Destructor + virtual ~FApplication(); + + // Accessors + const char* getClassName() const; + int getArgc() const; + char** getArgv() const; + FWidget* getMainWidget() const; + FWidget* getFocusWidget() const; + + // Mutator + void setMainWidget (FWidget*); + + // Inquiry + bool isQuit(); + + // Methods + int exec(); // run + int enter_loop(); + void exit_loop(); + static void exit (int = 0); + void quit(); + static bool sendEvent (FObject*, FEvent*); + static void queueEvent (FObject*, FEvent*); + static void sendQueuedEvents (); + static bool eventInQueue(); + static bool removeQueuedEvent(FObject*); + static void print_cmd_Options(); private: - int app_argc; - char** app_argv; - static int quit_code; - static bool quit_now; - static int loop_level; - static bool process_timer_event; - static FPoint* zero_point; - static uChar x11_button_state; - int key; - char k_buf[1024]; - char x11_mouse[4]; - char sgr_mouse[13]; - char urxvt_mouse[13]; - - -#ifdef F_HAVE_LIBGPM - - Gpm_Event gpm_ev; - bool gpmMouseEvent; - enum gpmEventType - { - no_event = 0, - keyboard_event = 1, - mouse_event = 2 - }; - -#endif + // Typedefs and Enumerations + typedef std::pair eventPair; + typedef std::deque eventQueue; enum btn_state { @@ -93,6 +98,60 @@ class FApplication : public FWidget DoubleClick = 3 }; +#ifdef F_HAVE_LIBGPM + enum gpmEventType + { + no_event = 0, + keyboard_event = 1, + mouse_event = 2 + }; +#endif + + // Constants + static const int NEED_MORE_DATA = -1; // parseKeyString return value + + // Disable copy constructor + FApplication (const FApplication&); + + // Disable assignment operator (=) + FApplication& operator = (const FApplication&); + + // Methods + void init(); + void setExitMessage (std::string); + void cmd_options(); + +#ifdef F_HAVE_LIBGPM + int gpmEvent (bool = true); + bool processGpmEvent(); +#endif + + bool KeyPressed(); + ssize_t readKey(); + void processKeyboardEvent(); + int modifierKeyCorrection (int& key); + bool processDialogSwitchAccelerator(); + bool processAccelerator (FWidget*&); + void getX11ButtonState (int); + bool parseX11Mouse(); + bool parseSGRMouse(); + bool parseUrxvtMouse(); + void processMouseEvent(); + void processResizeEvent(); + int processTimerEvent(); + void processCloseWidget(); + bool processNextEvent(); + + // Data Members + int app_argc; + char** app_argv; + int key; + +#ifdef F_HAVE_LIBGPM + Gpm_Event gpm_ev; + bool gpmMouseEvent; +#endif + struct button_state // bit field { uChar left_button : 2; // 0..3 @@ -107,54 +166,32 @@ class FApplication : public FWidget uChar : 4; // padding bits } b_state; - char fifo_buf[512]; - int fifo_offset; - bool fifo_in_use; - int fifo_buf_size; - long key_timeout; - long dblclick_interval; - struct timeval time_keypressed; - struct timeval time_mousepressed; - FPoint new_mouse_position; - static FWidget* move_size_widget; - static FWidget* main_widget; - static FWidget* active_window; - static FWidget* focus_widget; - static FWidget* clicked_widget; - static FWidget* open_menu; - - private: - // Disable copy constructor - FApplication (const FApplication&); - // Disable assignment operator (=) - FApplication& operator = (const FApplication&); - - void init(); - void setExitMessage (std::string); - void cmd_options(); - bool KeyPressed(); - ssize_t readKey(); - void processKeyboardEvent(); - int modifierKeyCorrection (int& key); - bool processDialogSwitchAccelerator(); - bool processAccelerator (FWidget*&); - void getX11ButtonState (int); - bool parseX11Mouse(); - bool parseSGRMouse(); - bool parseUrxvtMouse(); - -#ifdef F_HAVE_LIBGPM - - int gpmEvent (bool = true); - bool processGpmEvent(); - -#endif - - void processMouseEvent(); - void processResizeEvent(); - int processTimerEvent(); - void processCloseWidget(); - bool processNextEvent(); + char k_buf[1024]; + char x11_mouse[4]; + char sgr_mouse[13]; + char urxvt_mouse[13]; + char fifo_buf[512]; + int fifo_offset; + bool fifo_in_use; + int fifo_buf_size; + long key_timeout; + long dblclick_interval; + struct timeval time_keypressed; + struct timeval time_mousepressed; + FPoint new_mouse_position; + static eventQueue* event_queue; + static int quit_code; + static bool quit_now; + static int loop_level; + static bool process_timer_event; + static FPoint* zero_point; + static uChar x11_button_state; + static FWidget* move_size_widget; + static FWidget* main_widget; + static FWidget* active_window; + static FWidget* focus_widget; + static FWidget* clicked_widget; + static FWidget* open_menu; // Friend functions from FWidget friend FWidget* FWidget::getMainWidget(); @@ -170,31 +207,6 @@ class FApplication : public FWidget // Friend functions from FWindow friend bool FWindow::activateWindow (bool); friend FWindow* FWindow::getActiveWindow(); - - public: - // Constructor - FApplication (int&, char**& ); - // Destructor - virtual ~FApplication(); - - const char* getClassName() const; - int argc() const; - char** argv() const; - FWidget* mainWidget() const; - FWidget* focusWidget() const; - static void print_cmd_Options(); - void setMainWidget (FWidget*); - int exec(); // run - int enter_loop(); - void exit_loop(); - static void exit (int = 0); - void quit(); - bool isQuit(); - static bool sendEvent (FObject*, FEvent*); - static void queueEvent (FObject*, FEvent*); - static void sendQueuedEvents (); - static bool eventInQueue(); - static bool removeQueuedEvent(FObject*); }; #pragma pack(pop) @@ -205,19 +217,19 @@ inline const char* FApplication::getClassName() const { return "FApplication"; } //---------------------------------------------------------------------- -inline int FApplication::argc() const +inline int FApplication::getArgc() const { return app_argc; } //---------------------------------------------------------------------- -inline char** FApplication::argv() const +inline char** FApplication::getArgv() const { return app_argv; } //---------------------------------------------------------------------- -inline FWidget* FApplication::mainWidget() const +inline FWidget* FApplication::getMainWidget() const { return main_widget; } //---------------------------------------------------------------------- -inline FWidget* FApplication::focusWidget() const +inline FWidget* FApplication::getFocusWidget() const { return focus_widget; } diff --git a/src/fbutton.cpp b/src/fbutton.cpp index e4b28b50..e35463d8 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -56,6 +56,368 @@ FButton::~FButton() // destructor } +// public methods of FButton +//---------------------------------------------------------------------- +void FButton::setForegroundColor (short color) +{ + FWidget::setForegroundColor(color); + updateButtonColor(); +} + +//---------------------------------------------------------------------- +void FButton::setBackgroundColor (short color) +{ + FWidget::setBackgroundColor(color); + updateButtonColor(); +} + +//---------------------------------------------------------------------- +void FButton::setHotkeyForegroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + button_hotkey_fg = color; +} + +void FButton::setFocusForegroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + button_focus_fg = color; + + updateButtonColor(); +} + +//---------------------------------------------------------------------- +void FButton::setFocusBackgroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + button_focus_bg = color; + + updateButtonColor(); +} + +//---------------------------------------------------------------------- +void FButton::setInactiveForegroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + button_inactive_fg = color; + + updateButtonColor(); +} + +//---------------------------------------------------------------------- +void FButton::setInactiveBackgroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + button_inactive_bg = color; + + updateButtonColor(); +} + +//---------------------------------------------------------------------- +bool FButton::setNoUnderline (bool on) +{ + if ( on ) + flags |= fc::no_underline; + else + flags &= ~fc::no_underline; + + return on; +} + +//---------------------------------------------------------------------- +bool FButton::setEnable (bool on) +{ + FWidget::setEnable(on); + + if ( on ) + { + flags |= fc::active; + setHotkeyAccelerator(); + } + else + { + flags &= ~fc::active; + delAccelerator(); + } + + updateButtonColor(); + return on; +} + +//---------------------------------------------------------------------- +bool FButton::setFocus (bool on) +{ + FWidget::setFocus(on); + + if ( on ) + { + flags |= fc::focus; + + if ( isEnabled() ) + { + if ( getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + getStatusBar()->setMessage(msg); + } + } + } + else + { + flags &= ~fc::focus; + + if ( isEnabled() && getStatusBar() ) + getStatusBar()->clearMessage(); + } + + updateButtonColor(); + return on; +} + +//---------------------------------------------------------------------- +bool FButton::setFlat (bool on) +{ + if ( on ) + flags |= fc::flat; + else + flags &= ~fc::flat; + return on; +} + +//---------------------------------------------------------------------- +bool FButton::setShadow (bool on) +{ + if ( on + && (Encoding != fc::VT100 || isTeraTerm() ) + && Encoding != fc::ASCII ) + flags |= fc::shadow; + else + flags &= ~fc::shadow; + + return on; +} + +//---------------------------------------------------------------------- +bool FButton::setDown (bool on) +{ + if ( button_down != on ) + { + button_down = on; + redraw(); + } + + return on; +} + +//---------------------------------------------------------------------- +void FButton::setText (const FString& txt) +{ + if ( txt ) + text = txt; + else + text = ""; + + detectHotkey(); +} + +//---------------------------------------------------------------------- +void FButton::hide() +{ + int s, f, size; + short fg, bg; + char* blank; + FWidget* parent_widget = getParentWidget(); + FWidget::hide(); + + if ( parent_widget ) + { + fg = parent_widget->getForegroundColor(); + bg = parent_widget->getBackgroundColor(); + } + else + { + fg = wc.dialog_fg; + bg = wc.dialog_bg; + } + + setColor (fg, bg); + s = hasShadow() ? 1 : 0; + f = isFlat() ? 1 : 0; + size = getWidth() + s + (f << 1); + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset(blank, ' ', uLong(size)); + blank[size] = '\0'; + + for (int y=0; y < getHeight()+s+(f << 1); y++) + { + setPrintPos (1-f, 1+y-f); + print (blank); + } + + delete[] blank; +} + +//---------------------------------------------------------------------- +void FButton::onKeyPress (FKeyEvent* ev) +{ + int key; + + if ( ! isEnabled() ) + return; + + key = ev->key(); + + switch ( key ) + { + case fc::Fkey_return: + case fc::Fkey_enter: + case fc::Fkey_space: + if ( click_animation ) + { + setDown(); + addTimer(click_time); + } + processClick(); + ev->accept(); + break; + + default: + break; + } +} + +//---------------------------------------------------------------------- +void FButton::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + { + setUp(); + return; + } + + if ( ! hasFocus() ) + { + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + } + + FPoint tPos = ev->getTermPos(); + + if ( getTermGeometry().contains(tPos) ) + setDown(); +} + +//---------------------------------------------------------------------- +void FButton::onMouseUp (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( button_down ) + { + setUp(); + + if ( getTermGeometry().contains(ev->getTermPos()) ) + processClick(); + } +} + +//---------------------------------------------------------------------- +void FButton::onMouseMove (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + FPoint tPos = ev->getTermPos(); + + if ( click_animation ) + { + if ( getTermGeometry().contains(tPos) ) + setDown(); + else + setUp(); + } +} + +//---------------------------------------------------------------------- +void FButton::onTimer (FTimerEvent* ev) +{ + delTimer(ev->timerId()); + setUp(); +} + +//---------------------------------------------------------------------- +void FButton::onAccel (FAccelEvent* ev) +{ + if ( ! isEnabled() ) + return; + + if ( ! hasFocus() ) + { + FWidget* focused_widget = static_cast(ev->focusedWidget()); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + if ( click_animation ) + setDown(); + else + redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + } + else if ( click_animation ) + setDown(); + + if ( click_animation ) + addTimer(click_time); + + processClick(); + ev->accept(); +} + +//---------------------------------------------------------------------- +void FButton::onFocusIn (FFocusEvent*) +{ + if ( getStatusBar() ) + getStatusBar()->drawMessage(); +} + +//---------------------------------------------------------------------- +void FButton::onFocusOut (FFocusEvent*) +{ + if ( getStatusBar() ) + { + getStatusBar()->clearMessage(); + getStatusBar()->drawMessage(); + } +} + + // private methods of FButton //---------------------------------------------------------------------- void FButton::init() @@ -386,15 +748,15 @@ void FButton::draw() updateVTerm(true); delete[] ButtonText; - if ( is_Focus && statusBar() ) + if ( is_Focus && getStatusBar() ) { FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); + FString curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { - statusBar()->setMessage(msg); - statusBar()->drawMessage(); + getStatusBar()->setMessage(msg); + getStatusBar()->drawMessage(); } } } @@ -427,365 +789,3 @@ void FButton::processClick() { emitCallback("clicked"); } - - -// public methods of FButton -//---------------------------------------------------------------------- -void FButton::setForegroundColor (short color) -{ - FWidget::setForegroundColor(color); - updateButtonColor(); -} - -//---------------------------------------------------------------------- -void FButton::setBackgroundColor (short color) -{ - FWidget::setBackgroundColor(color); - updateButtonColor(); -} - -//---------------------------------------------------------------------- -void FButton::setHotkeyForegroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - button_hotkey_fg = color; -} - -void FButton::setFocusForegroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - button_focus_fg = color; - - updateButtonColor(); -} - -//---------------------------------------------------------------------- -void FButton::setFocusBackgroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - button_focus_bg = color; - - updateButtonColor(); -} - -//---------------------------------------------------------------------- -void FButton::setInactiveForegroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - button_inactive_fg = color; - - updateButtonColor(); -} - -//---------------------------------------------------------------------- -void FButton::setInactiveBackgroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - button_inactive_bg = color; - - updateButtonColor(); -} - -//---------------------------------------------------------------------- -void FButton::hide() -{ - int s, f, size; - short fg, bg; - char* blank; - FWidget* parent_widget = getParentWidget(); - FWidget::hide(); - - if ( parent_widget ) - { - fg = parent_widget->getForegroundColor(); - bg = parent_widget->getBackgroundColor(); - } - else - { - fg = wc.dialog_fg; - bg = wc.dialog_bg; - } - - setColor (fg, bg); - s = hasShadow() ? 1 : 0; - f = isFlat() ? 1 : 0; - size = getWidth() + s + (f << 1); - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset(blank, ' ', uLong(size)); - blank[size] = '\0'; - - for (int y=0; y < getHeight()+s+(f << 1); y++) - { - setPrintPos (1-f, 1+y-f); - print (blank); - } - - delete[] blank; -} - -//---------------------------------------------------------------------- -bool FButton::setNoUnderline (bool on) -{ - if ( on ) - flags |= fc::no_underline; - else - flags &= ~fc::no_underline; - - return on; -} - -//---------------------------------------------------------------------- -bool FButton::setEnable (bool on) -{ - FWidget::setEnable(on); - - if ( on ) - { - flags |= fc::active; - setHotkeyAccelerator(); - } - else - { - flags &= ~fc::active; - delAccelerator(); - } - - updateButtonColor(); - return on; -} - -//---------------------------------------------------------------------- -bool FButton::setFocus (bool on) -{ - FWidget::setFocus(on); - - if ( on ) - { - flags |= fc::focus; - - if ( isEnabled() ) - { - if ( statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) - statusBar()->setMessage(msg); - } - } - } - else - { - flags &= ~fc::focus; - - if ( isEnabled() && statusBar() ) - statusBar()->clearMessage(); - } - - updateButtonColor(); - return on; -} - -//---------------------------------------------------------------------- -bool FButton::setFlat (bool on) -{ - if ( on ) - flags |= fc::flat; - else - flags &= ~fc::flat; - return on; -} - -//---------------------------------------------------------------------- -bool FButton::setShadow (bool on) -{ - if ( on - && (Encoding != fc::VT100 || isTeraTerm() ) - && Encoding != fc::ASCII ) - flags |= fc::shadow; - else - flags &= ~fc::shadow; - - return on; -} - -//---------------------------------------------------------------------- -bool FButton::setDown (bool on) -{ - if ( button_down != on ) - { - button_down = on; - redraw(); - } - - return on; -} - -//---------------------------------------------------------------------- -void FButton::onKeyPress (FKeyEvent* ev) -{ - int key; - - if ( ! isEnabled() ) - return; - - key = ev->key(); - - switch ( key ) - { - case fc::Fkey_return: - case fc::Fkey_enter: - case fc::Fkey_space: - if ( click_animation ) - { - setDown(); - addTimer(click_time); - } - processClick(); - ev->accept(); - break; - - default: - break; - } -} - -//---------------------------------------------------------------------- -void FButton::onMouseDown (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - { - setUp(); - return; - } - - if ( ! hasFocus() ) - { - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - } - - FPoint tPos = ev->getTermPos(); - - if ( getTermGeometry().contains(tPos) ) - setDown(); -} - -//---------------------------------------------------------------------- -void FButton::onMouseUp (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( button_down ) - { - setUp(); - - if ( getTermGeometry().contains(ev->getTermPos()) ) - processClick(); - } -} - -//---------------------------------------------------------------------- -void FButton::onMouseMove (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - FPoint tPos = ev->getTermPos(); - - if ( click_animation ) - { - if ( getTermGeometry().contains(tPos) ) - setDown(); - else - setUp(); - } -} - -//---------------------------------------------------------------------- -void FButton::onTimer (FTimerEvent* ev) -{ - delTimer(ev->timerId()); - setUp(); -} - -//---------------------------------------------------------------------- -void FButton::onAccel (FAccelEvent* ev) -{ - if ( ! isEnabled() ) - return; - - if ( ! hasFocus() ) - { - FWidget* focused_widget = static_cast(ev->focusedWidget()); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - if ( click_animation ) - setDown(); - else - redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - } - else if ( click_animation ) - setDown(); - - if ( click_animation ) - addTimer(click_time); - - processClick(); - ev->accept(); -} - -//---------------------------------------------------------------------- -void FButton::onFocusIn (FFocusEvent*) -{ - if ( statusBar() ) - statusBar()->drawMessage(); -} - -//---------------------------------------------------------------------- -void FButton::onFocusOut (FFocusEvent*) -{ - if ( statusBar() ) - { - statusBar()->clearMessage(); - statusBar()->drawMessage(); - } -} - -//---------------------------------------------------------------------- -void FButton::setText (const FString& txt) -{ - if ( txt ) - text = txt; - else - text = ""; - - detectHotkey(); -} diff --git a/src/fbutton.h b/src/fbutton.h index 97876af3..c11f85be 100644 --- a/src/fbutton.h +++ b/src/fbutton.h @@ -40,41 +40,19 @@ class FButton : public FWidget { - private: - FString text; - bool button_down; - bool click_animation; - int click_time; - short button_fg; - short button_bg; - short button_hotkey_fg; - short button_focus_fg; - short button_focus_bg; - short button_inactive_fg; - short button_inactive_bg; - - private: - // Disable copy constructor - FButton (const FButton&); - // Disable assignment operator (=) - FButton& operator = (const FButton&); - - void init(); - uChar getHotkey(); - void setHotkeyAccelerator(); - void detectHotkey(); - void draw(); - void updateButtonColor(); - void processClick(); - public: // Constructors explicit FButton (FWidget* = 0); FButton (const FString&, FWidget* = 0); + // Destructor virtual ~FButton(); + // Accessors const char* getClassName() const; + FString& getText(); + + // Mutators void setForegroundColor (short); void setBackgroundColor (short); void setHotkeyForegroundColor (short); @@ -82,18 +60,6 @@ class FButton : public FWidget void setFocusBackgroundColor (short); void setInactiveForegroundColor (short); void setInactiveBackgroundColor (short); - void hide(); - - // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onTimer (FTimerEvent*); - void onAccel (FAccelEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); - bool setNoUnderline(bool); bool setNoUnderline(); bool unsetNoUnderline(); @@ -107,22 +73,64 @@ class FButton : public FWidget bool setFlat(bool); bool setFlat(); bool unsetFlat(); - bool isFlat() const; bool setShadow(bool); bool setShadow(); bool unsetShadow(); - bool hasShadow() const; bool setDown(bool); bool setDown(); bool setUp(); - bool isDown() const; bool setClickAnimation(bool); bool setClickAnimation(); bool unsetClickAnimation(); + void setText (const FString&); + + // Inquiries + bool isFlat() const; + bool isDown() const; + bool hasShadow() const; bool hasClickAnimation(); - void setText (const FString&); - FString& getText(); + // Methods + void hide(); + + // Event handlers + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onTimer (FTimerEvent*); + void onAccel (FAccelEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); + + private: + // Disable copy constructor + FButton (const FButton&); + + // Disable assignment operator (=) + FButton& operator = (const FButton&); + + // Methods + void init(); + uChar getHotkey(); + void setHotkeyAccelerator(); + void detectHotkey(); + void draw(); + void updateButtonColor(); + void processClick(); + + // Data Members + FString text; + bool button_down; + bool click_animation; + int click_time; + short button_fg; + short button_bg; + short button_hotkey_fg; + short button_focus_fg; + short button_focus_bg; + short button_inactive_fg; + short button_inactive_bg; }; #pragma pack(pop) @@ -132,6 +140,10 @@ class FButton : public FWidget inline const char* FButton::getClassName() const { return "FButton"; } +//---------------------------------------------------------------------- +inline FString& FButton::getText() +{ return text; } + //---------------------------------------------------------------------- inline bool FButton::setNoUnderline() { return setNoUnderline(true); } @@ -168,10 +180,6 @@ inline bool FButton::setFlat() inline bool FButton::unsetFlat() { return setFlat(false); } -//---------------------------------------------------------------------- -inline bool FButton::isFlat() const -{ return ((flags & fc::flat) != 0); } - //---------------------------------------------------------------------- inline bool FButton::setShadow() { return setShadow(true); } @@ -180,10 +188,6 @@ inline bool FButton::setShadow() inline bool FButton::unsetShadow() { return setShadow(false); } -//---------------------------------------------------------------------- -inline bool FButton::hasShadow() const -{ return ((flags & fc::shadow) != 0); } - //---------------------------------------------------------------------- inline bool FButton::setDown() { return setDown(true); } @@ -192,10 +196,6 @@ inline bool FButton::setDown() inline bool FButton::setUp() { return setDown(false); } -//---------------------------------------------------------------------- -inline bool FButton::isDown() const -{ return button_down; } - //---------------------------------------------------------------------- inline bool FButton::setClickAnimation(bool on) { return click_animation = on; } @@ -208,12 +208,20 @@ inline bool FButton::setClickAnimation() inline bool FButton::unsetClickAnimation() { return setClickAnimation(false); } +//---------------------------------------------------------------------- +inline bool FButton::isFlat() const +{ return ((flags & fc::flat) != 0); } + +//---------------------------------------------------------------------- +inline bool FButton::isDown() const +{ return button_down; } + +//---------------------------------------------------------------------- +inline bool FButton::hasShadow() const +{ return ((flags & fc::shadow) != 0); } + //---------------------------------------------------------------------- inline bool FButton::hasClickAnimation() { return click_animation; } -//---------------------------------------------------------------------- -inline FString& FButton::getText() -{ return text; } - #endif // _FBUTTON_H diff --git a/src/fbuttongroup.cpp b/src/fbuttongroup.cpp index 5b871193..a0d9525d 100644 --- a/src/fbuttongroup.cpp +++ b/src/fbuttongroup.cpp @@ -36,7 +36,7 @@ FButtonGroup::FButtonGroup (const FString& txt, FWidget* parent) //---------------------------------------------------------------------- FButtonGroup::~FButtonGroup() // destructor { - FButtonGroup::FButtonList::iterator iter; + FButtonList::iterator iter; if ( buttonlist.empty() ) return; @@ -50,121 +50,354 @@ FButtonGroup::~FButtonGroup() // destructor } } -// private methods of FButtonGroup + +// public methods of FButtonGroup //---------------------------------------------------------------------- -void FButtonGroup::init() +FToggleButton* FButtonGroup::getFirstButton() { - setTopPadding(1); - setLeftPadding(1); - setBottomPadding(1); - setRightPadding(1); + if ( buttonlist.empty() ) + return 0; + + FButtonList::const_iterator iter, end; + iter = buttonlist.begin(); + end = buttonlist.end(); + + while ( iter != end ) + { + if ( (*iter)->isEnabled() && (*iter)->acceptFocus() ) + return (*iter); + + ++iter; + } + + return 0; +} + +//---------------------------------------------------------------------- +FToggleButton* FButtonGroup::getLastButton() +{ + if ( buttonlist.empty() ) + return 0; + + FButtonList::const_iterator iter, begin; + begin = buttonlist.begin(); + iter = buttonlist.end(); + + do + { + --iter; + + if ( (*iter)->isEnabled() && (*iter)->acceptFocus() ) + return (*iter); + } + while ( iter != begin ); + + return 0; +} + +//---------------------------------------------------------------------- +bool FButtonGroup::setEnable (bool on) +{ + FWidget::setEnable(on); + + if ( on ) + { + flags |= fc::active; + setHotkeyAccelerator(); + } + else + { + flags &= ~fc::active; + delAccelerator(); + } + + return on; +} + +//---------------------------------------------------------------------- +bool FButtonGroup::setBorder(bool on) +{ + if ( on ) + border = true; + else + border = false; + + return on; +} + +//---------------------------------------------------------------------- +void FButtonGroup::setText (const FString& txt) +{ + text = txt; if ( isEnabled() ) - flags |= fc::active; - - setForegroundColor (wc.label_fg); - setBackgroundColor (wc.label_bg); - buttonlist.clear(); // no buttons yet + { + delAccelerator(); + setHotkeyAccelerator(); + } } //---------------------------------------------------------------------- -bool FButtonGroup::isRadioButton(FToggleButton* button) const +bool FButtonGroup::hasFocusedButton() { - if ( ! button ) + if ( buttonlist.empty() ) return false; - return bool ( std::strcmp ( button->getClassName() - , const_cast("FRadioButton") ) == 0 ); + FButtonList::const_iterator iter, end; + iter = buttonlist.begin(); + end = buttonlist.end(); + + while ( iter != end ) + { + if ( (*iter)->hasFocus() ) + return true; + + ++iter; + } + + return false; } //---------------------------------------------------------------------- -void FButtonGroup::directFocus() +bool FButtonGroup::hasCheckedButton() { - if ( ! hasFocusedButton() ) + if ( buttonlist.empty() ) + return false; + + FButtonList::const_iterator iter, end; + iter = buttonlist.begin(); + end = buttonlist.end(); + + while ( iter != end ) { - bool found_checked = false; + if ( (*iter)->isChecked() ) + return true; - if ( hasCheckedButton() && ! buttonlist.empty() ) + ++iter; + } + + return false; +} + +//---------------------------------------------------------------------- +void FButtonGroup::hide() +{ + int size; + short fg, bg; + char* blank; + FWidget::hide(); + FWidget* parent_widget = getParentWidget(); + + if ( ! buttonlist.empty() ) + { + FButtonList::const_iterator iter, end; + iter = buttonlist.begin(); + end = buttonlist.end(); + + while ( iter != end ) { - FButtonGroup::FButtonList::const_iterator iter, end; - iter = buttonlist.begin(); - end = buttonlist.end(); - - while ( iter != end ) - { - if ( (*iter)->isChecked() ) - { - if ( isRadioButton(*iter) ) - { - found_checked = true; - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - (*iter)->setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - focused_widget = getFocusWidget(); - - if ( focused_widget ) - focused_widget->redraw(); - } - - break; - } - - ++iter; - } - } - - if ( ! found_checked ) - { - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - focusFirstChild(); - - if ( focused_widget ) - focused_widget->redraw(); - - focused_widget = getFocusWidget(); - - if ( focused_widget ) - focused_widget->redraw(); + (*iter)->hide(); + ++iter; } } - if ( statusBar() ) + if ( parent_widget ) { - statusBar()->drawMessage(); + fg = parent_widget->getForegroundColor(); + bg = parent_widget->getBackgroundColor(); + } + else + { + fg = wc.dialog_fg; + bg = wc.dialog_bg; + } + + setColor (fg, bg); + size = getWidth(); + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset(blank, ' ', uLong(size)); + blank[size] = '\0'; + + for (int y=0; y < getHeight(); y++) + { + setPrintPos (1, 1+y); + print (blank); + } + + delete[] blank; +} + +//---------------------------------------------------------------------- +void FButtonGroup::insert (FToggleButton* button) +{ + if ( ! button ) + return; + + if ( button->getGroup() ) + button->getGroup()->remove(button); + + // setChecked the first FRadioButton + if ( buttonlist.size() == 1 && isRadioButton(*buttonlist.begin()) ) + (*buttonlist.begin())->setChecked(); + + button->setGroup(this); + buttonlist.push_back(button); + + button->addCallback + ( + "toggled", + _METHOD_CALLBACK (this, &FButtonGroup::cb_buttonToggled) + ); +} + +//---------------------------------------------------------------------- +void FButtonGroup::remove (FToggleButton* button) +{ + FButtonList::iterator iter; + + if ( ! button || buttonlist.empty() ) + return; + + iter = buttonlist.begin(); + + while ( iter != buttonlist.end() ) + { + if ( (*iter) == button ) + { + iter = buttonlist.erase(iter); + button->setGroup(0); + button->delCallback(this); + break; + } + else + ++iter; + } +} + +//---------------------------------------------------------------------- +void FButtonGroup::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + directFocus(); +} + +//---------------------------------------------------------------------- +void FButtonGroup::onAccel (FAccelEvent*) +{ + directFocus(); +} + +//---------------------------------------------------------------------- +void FButtonGroup::onFocusIn (FFocusEvent* in_ev) +{ + if ( hasCheckedButton() && ! buttonlist.empty() ) + { + FButtonList::const_iterator iter, end; + iter = buttonlist.begin(); + end = buttonlist.end(); + + while ( iter != end ) + { + if ( (*iter)->isChecked() ) + { + if ( isRadioButton(*iter) ) + { + in_ev->ignore(); + FWidget* prev_element = getFocusWidget(); + (*iter)->setFocus(); + + if ( prev_element ) + prev_element->redraw(); + + (*iter)->redraw(); + } + + break; + } + + ++iter; + } + } + + if ( in_ev->isAccepted() ) + { + if ( in_ev->getFocusType() == fc::FocusNextWidget ) + { + in_ev->ignore(); + FWidget* prev_element = getFocusWidget(); + focusFirstChild(); + + if ( prev_element ) + prev_element->redraw(); + + if ( getFocusWidget() ) + getFocusWidget()->redraw(); + } + else if ( in_ev->getFocusType() == fc::FocusPreviousWidget ) + { + in_ev->ignore(); + FWidget* prev_element = getFocusWidget(); + focusLastChild(); + + if ( prev_element ) + prev_element->redraw(); + + if ( getFocusWidget() ) + getFocusWidget()->redraw(); + } + } + + if ( getStatusBar() ) + { + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); } } -// protected methods of FButtonGroup //---------------------------------------------------------------------- -void FButtonGroup::draw() +void FButtonGroup::onFocusOut (FFocusEvent*) +{ } + +//---------------------------------------------------------------------- +void FButtonGroup::cb_buttonToggled (FWidget* widget, void*) { - updateVTerm(false); + FToggleButton* button = static_cast(widget); + FButtonList::const_iterator iter, end; - if ( isMonochron() ) - setReverse(true); + if ( ! button->isChecked() ) + return; - setColor(); + if ( buttonlist.empty() ) + return; - if ( border ) - drawBorder(); + iter = buttonlist.begin(); + end = buttonlist.end(); - drawLabel(); + while ( iter != end ) + { + if ( (*iter) != button + && (*iter)->isChecked() + && isRadioButton(*iter) ) + { + (*iter)->unsetChecked(); - if ( isMonochron() ) - setReverse(false); + if ( (*iter)->isVisible() && (*iter)->isShown() ) + (*iter)->redraw(); + } - updateVTerm(true); + ++iter; + } } + +// protected methods of FButtonGroup //---------------------------------------------------------------------- uChar FButtonGroup::getHotkey() { @@ -211,6 +444,27 @@ void FButtonGroup::setHotkeyAccelerator() delAccelerator(); } +//---------------------------------------------------------------------- +void FButtonGroup::draw() +{ + updateVTerm(false); + + if ( isMonochron() ) + setReverse(true); + + setColor(); + + if ( border ) + drawBorder(); + + drawLabel(); + + if ( isMonochron() ) + setReverse(false); + + updateVTerm(true); +} + //---------------------------------------------------------------------- void FButtonGroup::drawLabel() { @@ -284,347 +538,96 @@ void FButtonGroup::drawLabel() delete[] LabelText; } -// public methods of FButtonGroup + +// private methods of FButtonGroup //---------------------------------------------------------------------- -void FButtonGroup::hide() -{ - int size; - short fg, bg; - char* blank; - FWidget::hide(); - FWidget* parent_widget = getParentWidget(); - - if ( ! buttonlist.empty() ) - { - FButtonGroup::FButtonList::const_iterator iter, end; - iter = buttonlist.begin(); - end = buttonlist.end(); - - while ( iter != end ) - { - (*iter)->hide(); - ++iter; - } - } - - if ( parent_widget ) - { - fg = parent_widget->getForegroundColor(); - bg = parent_widget->getBackgroundColor(); - } - else - { - fg = wc.dialog_fg; - bg = wc.dialog_bg; - } - - setColor (fg, bg); - size = getWidth(); - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset(blank, ' ', uLong(size)); - blank[size] = '\0'; - - for (int y=0; y < getHeight(); y++) - { - setPrintPos (1, 1+y); - print (blank); - } - - delete[] blank; -} - -//---------------------------------------------------------------------- -void FButtonGroup::insert (FToggleButton* button) +bool FButtonGroup::isRadioButton(FToggleButton* button) const { if ( ! button ) - return; - - if ( button->group() ) - button->group()->remove(button); - - // setChecked the first FRadioButton - if ( buttonlist.size() == 1 && isRadioButton(*buttonlist.begin()) ) - (*buttonlist.begin())->setChecked(); - - button->setGroup(this); - buttonlist.push_back(button); - - button->addCallback - ( - "toggled", - _METHOD_CALLBACK (this, &FButtonGroup::cb_buttonToggled) - ); -} - -//---------------------------------------------------------------------- -void FButtonGroup::remove (FToggleButton* button) -{ - FButtonGroup::FButtonList::iterator iter; - - if ( ! button || buttonlist.empty() ) - return; - - iter = buttonlist.begin(); - - while ( iter != buttonlist.end() ) - { - if ( (*iter) == button ) - { - iter = buttonlist.erase(iter); - button->setGroup(0); - button->delCallback(this); - break; - } - else - ++iter; - } -} - -//---------------------------------------------------------------------- -void FButtonGroup::cb_buttonToggled (FWidget* widget, void*) -{ - FToggleButton* button = static_cast(widget); - FButtonGroup::FButtonList::const_iterator iter, end; - - if ( ! button->isChecked() ) - return; - - if ( buttonlist.empty() ) - return; - - iter = buttonlist.begin(); - end = buttonlist.end(); - - while ( iter != end ) - { - if ( (*iter) != button - && (*iter)->isChecked() - && isRadioButton(*iter) ) - { - (*iter)->unsetChecked(); - - if ( (*iter)->isVisible() && (*iter)->isShown() ) - (*iter)->redraw(); - } - - ++iter; - } -} - -//---------------------------------------------------------------------- -FToggleButton* FButtonGroup::getFirstButton() -{ - if ( buttonlist.empty() ) - return 0; - - FButtonGroup::FButtonList::const_iterator iter, end; - iter = buttonlist.begin(); - end = buttonlist.end(); - - while ( iter != end ) - { - if ( (*iter)->isEnabled() && (*iter)->acceptFocus() ) - return (*iter); - - ++iter; - } - - return 0; -} - -//---------------------------------------------------------------------- -FToggleButton* FButtonGroup::getLastButton() -{ - if ( buttonlist.empty() ) - return 0; - - FButtonGroup::FButtonList::const_iterator iter, begin; - begin = buttonlist.begin(); - iter = buttonlist.end(); - - do - { - --iter; - - if ( (*iter)->isEnabled() && (*iter)->acceptFocus() ) - return (*iter); - } - while ( iter != begin ); - - return 0; -} - -//---------------------------------------------------------------------- -bool FButtonGroup::hasFocusedButton() -{ - if ( buttonlist.empty() ) return false; - FButtonGroup::FButtonList::const_iterator iter, end; - iter = buttonlist.begin(); - end = buttonlist.end(); + return bool ( std::strcmp ( button->getClassName() + , const_cast("FRadioButton") ) == 0 ); +} - while ( iter != end ) +//---------------------------------------------------------------------- +void FButtonGroup::init() +{ + setTopPadding(1); + setLeftPadding(1); + setBottomPadding(1); + setRightPadding(1); + + if ( isEnabled() ) + flags |= fc::active; + + setForegroundColor (wc.label_fg); + setBackgroundColor (wc.label_bg); + buttonlist.clear(); // no buttons yet +} + +//---------------------------------------------------------------------- +void FButtonGroup::directFocus() +{ + if ( ! hasFocusedButton() ) { - if ( (*iter)->hasFocus() ) - return true; + bool found_checked = false; - ++iter; - } - - return false; -} - -//---------------------------------------------------------------------- -bool FButtonGroup::hasCheckedButton() -{ - if ( buttonlist.empty() ) - return false; - - FButtonGroup::FButtonList::const_iterator iter, end; - iter = buttonlist.begin(); - end = buttonlist.end(); - - while ( iter != end ) - { - if ( (*iter)->isChecked() ) - return true; - - ++iter; - } - - return false; -} - -//---------------------------------------------------------------------- -void FButtonGroup::onMouseDown (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - directFocus(); -} - -//---------------------------------------------------------------------- -void FButtonGroup::onAccel (FAccelEvent*) -{ - directFocus(); -} - -//---------------------------------------------------------------------- -void FButtonGroup::onFocusIn (FFocusEvent* in_ev) -{ - if ( hasCheckedButton() && ! buttonlist.empty() ) - { - FButtonGroup::FButtonList::const_iterator iter, end; - iter = buttonlist.begin(); - end = buttonlist.end(); - - while ( iter != end ) + if ( hasCheckedButton() && ! buttonlist.empty() ) { - if ( (*iter)->isChecked() ) + FButtonList::const_iterator iter, end; + iter = buttonlist.begin(); + end = buttonlist.end(); + + while ( iter != end ) { - if ( isRadioButton(*iter) ) + if ( (*iter)->isChecked() ) { - in_ev->ignore(); - FWidget* prev_element = getFocusWidget(); - (*iter)->setFocus(); + if ( isRadioButton(*iter) ) + { + found_checked = true; + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + (*iter)->setFocus(); - if ( prev_element ) - prev_element->redraw(); + if ( focused_widget ) + focused_widget->redraw(); - (*iter)->redraw(); + focused_widget = getFocusWidget(); + + if ( focused_widget ) + focused_widget->redraw(); + } + + break; } - break; + ++iter; } - - ++iter; } - } - if ( in_ev->isAccepted() ) - { - if ( in_ev->getFocusType() == fc::FocusNextWidget ) + if ( ! found_checked ) { - in_ev->ignore(); - FWidget* prev_element = getFocusWidget(); + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); focusFirstChild(); - if ( prev_element ) - prev_element->redraw(); + if ( focused_widget ) + focused_widget->redraw(); - if ( getFocusWidget() ) - getFocusWidget()->redraw(); - } - else if ( in_ev->getFocusType() == fc::FocusPreviousWidget ) - { - in_ev->ignore(); - FWidget* prev_element = getFocusWidget(); - focusLastChild(); + focused_widget = getFocusWidget(); - if ( prev_element ) - prev_element->redraw(); - - if ( getFocusWidget() ) - getFocusWidget()->redraw(); + if ( focused_widget ) + focused_widget->redraw(); } } - if ( statusBar() ) + if ( getStatusBar() ) { - statusBar()->drawMessage(); + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); } } - -//---------------------------------------------------------------------- -void FButtonGroup::onFocusOut (FFocusEvent*) -{ } - -//---------------------------------------------------------------------- -bool FButtonGroup::setEnable (bool on) -{ - FWidget::setEnable(on); - - if ( on ) - { - flags |= fc::active; - setHotkeyAccelerator(); - } - else - { - flags &= ~fc::active; - delAccelerator(); - } - - return on; -} - -//---------------------------------------------------------------------- -bool FButtonGroup::setBorder(bool on) -{ - if ( on ) - border = true; - else - border = false; - - return on; -} - -//---------------------------------------------------------------------- -void FButtonGroup::setText (const FString& txt) -{ - text = txt; - - if ( isEnabled() ) - { - delAccelerator(); - setHotkeyAccelerator(); - } -} diff --git a/src/fbuttongroup.h b/src/fbuttongroup.h index a05aea5c..14d9d89a 100644 --- a/src/fbuttongroup.h +++ b/src/fbuttongroup.h @@ -43,55 +43,21 @@ class FToggleButton; class FButtonGroup : public FWidget { - private: - FString text; - bool border; - typedef std::vector FButtonList; - FButtonGroup::FButtonList buttonlist; - - private: - // Disable copy constructor - FButtonGroup (const FButtonGroup&); - // Disable assignment operator (=) - FButtonGroup& operator = (const FButtonGroup&); - - void init(); - bool isRadioButton(FToggleButton*) const; - void directFocus(); - - protected: - virtual void draw(); - uChar getHotkey(); - void setHotkeyAccelerator(); - void drawLabel(); - public: // Constructors explicit FButtonGroup (FWidget* = 0); FButtonGroup (const FString&, FWidget* = 0); + // Destructor virtual ~FButtonGroup(); + // Accessor const char* getClassName() const; - void hide(); - FToggleButton* getFirstButton(); FToggleButton* getLastButton(); - bool hasFocusedButton(); - bool hasCheckedButton(); - - // Event handlers - void onMouseDown (FMouseEvent*); - void onAccel (FAccelEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); - - void insert (FToggleButton*); - void remove (FToggleButton*); - - // Callback method - void cb_buttonToggled (FWidget*, void*); + FString& getText(); + // Mutator bool setEnable(bool); bool setEnable(); bool unsetEnable(); @@ -100,7 +66,57 @@ class FButtonGroup : public FWidget bool setBorder(); bool unsetBorder(); void setText (const FString&); - FString& getText(); + + // Inquiries + bool hasFocusedButton(); + bool hasCheckedButton(); + + // Methods + void hide(); + void insert (FToggleButton*); + void remove (FToggleButton*); + + // Event handlers + void onMouseDown (FMouseEvent*); + void onAccel (FAccelEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); + + // Callback method + void cb_buttonToggled (FWidget*, void*); + + protected: + // Accessor + uChar getHotkey(); + + // Mutator + void setHotkeyAccelerator(); + + // Methods + virtual void draw(); + void drawLabel(); + + private: + // Typedef + typedef std::vector FButtonList; + + // Disable copy constructor + FButtonGroup (const FButtonGroup&); + + // Disable assignment operator (=) + FButtonGroup& operator = (const FButtonGroup&); + + // Inquiries + bool isRadioButton(FToggleButton*) const; + + // Methods + void init(); + void directFocus(); + + // Data Members + FString text; + bool border; + FButtonList buttonlist; }; #pragma pack(pop) diff --git a/src/fcheckbox.h b/src/fcheckbox.h index a52890d6..7d492011 100644 --- a/src/fcheckbox.h +++ b/src/fcheckbox.h @@ -45,24 +45,28 @@ class FCheckBox : public FToggleButton { - private: - // Disable copy constructor - FCheckBox (const FCheckBox&); - // Disable assignment operator (=) - FCheckBox& operator = (const FCheckBox&); - - void init(); - void draw(); - void drawCheckButton(); - public: // Constructors explicit FCheckBox (FWidget* = 0); FCheckBox (const FString&, FWidget* = 0); + // Destructor virtual ~FCheckBox(); + // Accessor const char* getClassName() const; + + private: + // Disable copy constructor + FCheckBox (const FCheckBox&); + + // Disable assignment operator (=) + FCheckBox& operator = (const FCheckBox&); + + // Methods + void init(); + void draw(); + void drawCheckButton(); }; #pragma pack(pop) diff --git a/src/fcheckmenuitem.h b/src/fcheckmenuitem.h index 36b3870e..85bfcaf0 100644 --- a/src/fcheckmenuitem.h +++ b/src/fcheckmenuitem.h @@ -45,26 +45,30 @@ class FCheckMenuItem : public FMenuItem { - private: - // Disable copy constructor - FCheckMenuItem (const FCheckMenuItem&); - // Disable assignment operator (=) - FCheckMenuItem& operator = (const FCheckMenuItem&); - - void init (FWidget*); - void processToggle(); - void processClicked(); - public: - // Constructor + // Constructors explicit FCheckMenuItem (FWidget* = 0); FCheckMenuItem (FString&, FWidget* = 0); FCheckMenuItem (const std::string&, FWidget* = 0); FCheckMenuItem (const char*, FWidget* = 0); + // Destructor virtual ~FCheckMenuItem(); + // Accessor const char* getClassName() const; + + private: + // Disable copy constructor + FCheckMenuItem (const FCheckMenuItem&); + + // Disable assignment operator (=) + FCheckMenuItem& operator = (const FCheckMenuItem&); + + // Methods + void init (FWidget*); + void processToggle(); + void processClicked(); }; #pragma pack(pop) diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 0b0e09aa..8793f9ab 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -70,530 +70,338 @@ FDialog::~FDialog() // destructor unsetModal(); } -// private methods of FDialog -//---------------------------------------------------------------------- -void FDialog::init() -{ - FWidget* old_focus; - setTopPadding(2); - setLeftPadding(1); - setBottomPadding(1); - setRightPadding(1); - ignorePadding(); - setDialogWidget(); - // initialize geometry values - setGeometry (1, 1, 10, 10, false); - setMinimumSize (15, 4); - addDialog(this); - setActiveWindow(this); - setTransparentShadow(); - setForegroundColor (wc.dialog_fg); - setBackgroundColor (wc.dialog_bg); - if ( hasFocus() ) +// public methods of FDialog +//---------------------------------------------------------------------- +bool FDialog::setFocus (bool on) +{ + FWidget::setFocus(on); + + if ( on ) flags |= fc::focus; + else + flags &= ~fc::focus; - if ( isEnabled() ) - flags |= fc::active; - - old_focus = FWidget::getFocusWidget(); - - if ( old_focus ) - { - setFocus(); - old_focus->redraw(); - } - - accelerator_list = new Accelerators(); - // Add the dialog menu - dialog_menu = new FMenu ("-", this); - dialog_menu->setPos (getX(), getY()+1); - dgl_menuitem = dialog_menu->getItem(); - - if ( dgl_menuitem ) - { - dgl_menuitem->ignorePadding(); - dgl_menuitem->unsetFocusable(); - } - - move_size_item = new FMenuItem (dialog_menu); - move_size_item->setText ("&Move/Size"); - move_size_item->setStatusbarMessage ("Move or change the size of the window"); - - move_size_item->addCallback - ( - "clicked", - _METHOD_CALLBACK (this, &FDialog::cb_move) - ); - - zoom_item = new FMenuItem (dialog_menu); - setZoomItem(); - zoom_item->setDisable(); - - zoom_item->addCallback - ( - "clicked", - _METHOD_CALLBACK (this, &FDialog::cb_zoom) - ); - - close_item = new FMenuItem ("&Close", dialog_menu); - close_item->setStatusbarMessage ("Close this window"); - - close_item->addCallback - ( - "clicked", - _METHOD_CALLBACK (this, &FDialog::cb_close) - ); + return on; } //---------------------------------------------------------------------- -void FDialog::drawBorder() +bool FDialog::setDialogWidget (bool on) { - int x1 = 1; - int x2 = 1 + getWidth() - 1; - int y1 = 2; - int y2 = 1 + getHeight() - 1; + if ( isDialogWidget() == on ) + return true; - if ( (getMoveSizeWidget() == this || ! resize_click_pos.isNull()) - && ! isZoomed() ) - setColor (wc.dialog_resize_fg, getBackgroundColor()); - else - setColor(); - - if ( isNewFont() ) + if ( on ) { - for (int y=y1; y < y2; y++) - { - setPrintPos (x1, y); - // border left ⎸ - print (fc::NF_border_line_left); - setPrintPos (x2, y); - // border right⎹ - print (fc::NF_rev_border_line_right); - } - - setPrintPos (x1, y2); - // lower left corner border ⎣ - print (fc::NF_border_corner_lower_left); - - for (int x=1; x < getWidth()-1; x++) // low line _ - print (fc::NF_border_line_bottom); - - setPrintPos (x2, y2); - // lower right corner border ⎦ - print (fc::NF_rev_border_corner_lower_right); + flags |= fc::dialog_widget; + setTermOffsetWithPadding(); } else { - FWidget::drawBorder(x1, y1, x2, y2); + flags &= ~fc::dialog_widget; + setParentOffset(); + } + + return on; +} + +//---------------------------------------------------------------------- +bool FDialog::setModal (bool on) +{ + if ( isModal() == on ) + return true; + + if ( on ) + { + flags |= fc::modal; + modal_dialogs++; + } + else + { + flags &= ~fc::modal; + modal_dialogs--; + } + + return on; +} + + +//---------------------------------------------------------------------- +bool FDialog::setScrollable (bool on) +{ + if ( on ) + flags |= fc::scrollable; + else + flags &= ~fc::scrollable; + + return on; +} + +//---------------------------------------------------------------------- +bool FDialog::setResizeable (bool on) +{ + FWindow::setResizeable (on); + + if ( on ) + zoom_item->setEnable(); + else + zoom_item->setDisable(); + + return on; +} + +//---------------------------------------------------------------------- +void FDialog::show() +{ + if ( ! isVisible() ) + return; + + FWindow::show(); + + if ( isModal() ) + { + FApplication* fapp = static_cast(getRootWidget()); + fapp->enter_loop(); + + if ( this == getMainWidget() ) + fapp->quit(); } } //---------------------------------------------------------------------- -void FDialog::drawTitleBar() +void FDialog::hide() { - int i,x,length, zoom_btn; - const int menu_btn = 3; + FWindow::hide(); - // draw the title button - setPrintPos (1, 1); - - if ( dialog_menu && dialog_menu->isVisible() ) - setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); - else - setColor (wc.titlebar_button_fg, wc.titlebar_button_bg); - - if ( isMonochron() ) + if ( isModal() ) { - if ( isWindowActive() ) - setReverse(false); - else - setReverse(true); + FApplication* fapp = static_cast(getRootWidget()); + fapp->exit_loop(); } +} +//---------------------------------------------------------------------- +int FDialog::exec() +{ + result_code = FDialog::Reject; + show(); + return result_code; +} - if ( isNewFont() ) +//---------------------------------------------------------------------- +void FDialog::setPos (int x, int y, bool) +{ + int dx, dy, old_x, old_y, rsw, bsh, width, height; + FRect old_geometry; + + if ( getX() == x && getY() == y ) + return; + + width = getWidth(); + height = getHeight(); + + // Avoid to move widget completely outside the terminal + if ( x+width <= 1 || x > getMaxWidth() || y < 1 || y > getMaxHeight() ) + return; + + if ( isZoomed() ) + return; + + dx = getX() - x; + dy = getY() - y; + old_x = getTermX(); + old_y = getTermY(); + const FPoint& shadow = getShadow(); + rsw = shadow.getX(); // right shadow width; + bsh = shadow.getY(); // bottom shadow height + old_geometry = getTermGeometryWithShadow(); + + // move to the new position + FWindow::setPos(x, y, false); + putArea (getTermPos(), vwin); + + // restoring the non-covered terminal areas + if ( getTermGeometry().overlap(old_geometry) ) { - print (fc::NF_rev_menu_button1); - print (fc::NF_rev_menu_button2); - print (fc::NF_rev_menu_button3); - } - else if ( isMonochron() ) - { - print ('['); + // dx > 0 : move left + // dx = 0 : move vertical + // dx < 0 : move right + // dy > 0 : move up + // dy = 0 : move horizontal + // dy < 0 : move down - if ( dgl_menuitem ) - print (dgl_menuitem->getText()); - else - print ('-'); - - print (']'); - } - else - { - print (' '); - - if ( dgl_menuitem ) - print (dgl_menuitem->getText()); - else - print ('-'); - - print (' '); - } - - // fill with spaces (left of the title) - if ( getMaxColor() < 16 ) - setBold(); - - if ( isWindowActive() || (dialog_menu && dialog_menu->isVisible()) ) - setColor (wc.titlebar_active_fg, wc.titlebar_active_bg); - else - setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg); - - if ( ! isResizeable() ) - zoom_btn = 0; - else if ( isNewFont() ) - zoom_btn = 2; - else - zoom_btn = 3; - - length = int(tb_text.getLength()); - i = getWidth() - length - menu_btn - zoom_btn; - i = int(i/2); - - for (x=1; x <= i; x++) - print (' '); - - // the title bar text - if ( tb_text ) - { - if ( length <= getWidth() - menu_btn - zoom_btn ) - print (tb_text); - else + if ( dx > 0 ) { - print (tb_text.left(getWidth() - menu_btn - zoom_btn - 2)); - print (".."); - } - } - - // fill the rest of the bar - for (; x+1+length < getWidth()-zoom_btn-1; x++) - print (' '); - - if ( getMaxColor() < 16 ) - unsetBold(); - - // draw the zoom/unzoom button - if ( isResizeable() ) - { - if ( zoom_button_pressed ) - setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); - else - setColor (wc.titlebar_button_fg, wc.titlebar_button_bg); - - if ( isZoomed() ) - { - if ( isNewFont() ) - { - print (fc::NF_rev_down_pointing_triangle1); - print (fc::NF_rev_down_pointing_triangle2); - } + if ( dy > 0 ) + restoreVTerm (old_x+width+rsw-dx, old_y, dx, getHeight()+bsh-dy); else - { - if ( isMonochron() ) - { - print ('['); - print (fc::BlackDownPointingTriangle); // ▼ - print (']'); - } - else - { - print (' '); - - if ( isCygwinTerminal() ) - print ('v'); - else - print (fc::BlackDownPointingTriangle); // ▼ - - print (' '); - } - } + restoreVTerm (old_x+width+rsw-dx, old_y+std::abs(dy), dx, height+bsh-std::abs(dy)); } - else // is not zoomed + else { - if ( isNewFont() ) - { - print (fc::NF_rev_up_pointing_triangle1); - print (fc::NF_rev_up_pointing_triangle2); - } + if ( dy > 0 ) + restoreVTerm (old_x, old_y, std::abs(dx), height+bsh-dy); else - { - if ( isMonochron() ) - { - print ('['); - print (fc::BlackUpPointingTriangle); // ▲ - print (']'); - } - else - { - print (' '); + restoreVTerm (old_x, old_y+std::abs(dy), std::abs(dx), height+bsh-std::abs(dy)); + } - if ( isCygwinTerminal() ) - print ('^'); - else - print (fc::BlackUpPointingTriangle); // ▲ + if ( dy > 0 ) + restoreVTerm (old_x, old_y+height+bsh-dy, width+rsw, dy); + else + restoreVTerm (old_x, old_y, width+rsw, std::abs(dy)); + } + else + { + restoreVTerm (old_geometry); + } - print (' '); - } - } + // handle overlaid windows + if ( window_list && ! window_list->empty() ) + { + bool overlaid = false; + widgetList::const_iterator iter, end; + iter = window_list->begin(); + end = window_list->end(); + + while ( iter != end ) + { + if ( overlaid ) + putArea ((*iter)->getTermPos(), (*iter)->getVWin()); + + if ( vwin == (*iter)->getVWin() ) + overlaid = true; + + ++iter; } } - if ( isMonochron() ) - setReverse(false); + FWindow::adjustSize(); -/* print the number of window in stack */ -//setPrintPos (getWidth()-2, 1); -//printf ("(%d)", getWindowLayer(this)); + // set the cursor to the focus widget + FWidget* focus_widget = FWidget::getFocusWidget(); + if ( focus_widget + && focus_widget->isVisible() + && focus_widget->hasVisibleCursor() ) + { + FPoint cursor_pos = focus_widget->getCursorPos(); + focus_widget->setCursorPos(cursor_pos); + } + updateTerminal(); } //---------------------------------------------------------------------- -void FDialog::leaveMenu() +void FDialog::move (int dx, int dy) { - dialog_menu->unselectItem(); - dialog_menu->hide(); - activateWindow(); - raiseWindow(); + setPos (getX() + dx, getY() + dy); +} - if ( getWindowFocusWidget() ) - getWindowFocusWidget()->setFocus(); +//---------------------------------------------------------------------- +void FDialog::setSize (int w, int h, bool adjust) +{ + int x, y, dw, dh, old_width, old_height, rsw, bsh; + + if ( getWidth() == w && getHeight() == h ) + return; + + if ( isZoomed() ) + return; + + x = getTermX(); + y = getTermY(); + old_width = getWidth(); + old_height = getHeight(); + dw = old_width - w; + dh = old_height - h; + const FPoint& shadow = getShadow(); + rsw = shadow.getX(); // right shadow width; + bsh = shadow.getY(); // bottom shadow height + + FWindow::setSize (w, h, adjust); + + // get adjust width and height + w = getWidth(); + h = getHeight(); + + // dw > 0 : scale down width + // dw = 0 : scale only height + // dw < 0 : scale up width + // dh > 0 : scale down height + // dh = 0 : scale only width + // dh < 0 : scale up height + + // restoring the non-covered terminal areas + if ( dw > 0 ) + restoreVTerm (x+w+rsw, y, dw, h+bsh+dh); // restore right + + if ( dh > 0 ) + restoreVTerm (x, y+h+bsh, w+rsw+dw, dh); // restore bottom redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); -} - -//---------------------------------------------------------------------- -void FDialog::openMenu() -{ - // open the titlebar menu - if ( ! dialog_menu ) - return; - - if ( dialog_menu->isVisible() ) + // handle overlaid windows + if ( window_list && ! window_list->empty() ) { - leaveMenu(); - drawTitleBar(); - } - else - { - setOpenMenu(dialog_menu); - dialog_menu->setPos (getX(), getY()+1); - dialog_menu->setVisible(); - drawTitleBar(); - dialog_menu->show(); - dialog_menu->raiseWindow(dialog_menu); - dialog_menu->redraw(); - } -} + bool overlaid = false; + widgetList::const_iterator iter, end; + iter = window_list->begin(); + end = window_list->end(); -//---------------------------------------------------------------------- -void FDialog::selectFirstMenuItem() -{ - // focus to the first enabled menu item - FMenuItem* first_item; - dialog_menu->selectFirstItem(); - first_item = dialog_menu->getSelectedItem(); - - if ( first_item ) - first_item->setFocus(); - - dialog_menu->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); -} - -//---------------------------------------------------------------------- -void FDialog::setZoomItem() -{ - if ( isZoomed() ) - { - zoom_item->setText ("&Unzoom"); - zoom_item->setStatusbarMessage ("Restore the window size"); - move_size_item->setDisable(); - } - else - { - zoom_item->setText ("&Zoom"); - zoom_item->setStatusbarMessage ("Enlarge the window to the entire desktop"); - move_size_item->setEnable(); - } -} - -//---------------------------------------------------------------------- -void FDialog::cb_move (FWidget*, void*) -{ - if ( isZoomed() ) - return; - - setMoveSizeWidget(this); - drawBorder(); - save_geometry = getGeometry(); - tooltip = new FToolTip(this); - - if ( isResizeable() ) - { - if ( isLinuxTerm() ) - tooltip->setText ( " Arrow keys: Move\n" - "Shift + Arrow keys: Resize\n" - " Enter: Done\n" - " Esc: Cancel" ); - else - 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(); -} - -//---------------------------------------------------------------------- -void FDialog::cb_zoom (FWidget*, void*) -{ - dialog_menu->unselectItem(); - dialog_menu->hide(); - setClickedWidget(0); - drawTitleBar(); - zoomWindow(); - setZoomItem(); -} - -//---------------------------------------------------------------------- -void FDialog::cb_close (FWidget*, void*) -{ - dialog_menu->unselectItem(); - dialog_menu->hide(); - setClickedWidget(0); - drawTitleBar(); - close(); -} - -//---------------------------------------------------------------------- -void FDialog::addDialog (FWidget* obj) -{ - // add the dialog object obj to the dialog list - if ( dialog_list ) - dialog_list->push_back(obj); -} - -//---------------------------------------------------------------------- -void FDialog::delDialog (FWidget* obj) -{ - // delete the dialog object obj from the dialog list - if ( ! dialog_list || dialog_list->empty() ) - return; - - widgetList::iterator iter; - iter = dialog_list->begin(); - - while ( iter != dialog_list->end() ) - { - if ( (*iter) == obj ) + while ( iter != end ) { - dialog_list->erase(iter); - return; + if ( overlaid ) + putArea ((*iter)->getTermPos(), (*iter)->getVWin()); + + if ( vwin == (*iter)->getVWin() ) + overlaid = true; + + ++iter; } - - ++iter; } -} - -// protected methods of FDialog -//---------------------------------------------------------------------- -void FDialog::done(int result) -{ - hide(); - result_code = result; -} - -//---------------------------------------------------------------------- -void FDialog::drawDialogShadow() -{ - if ( isMonochron() && (flags & fc::trans_shadow) == 0 ) - return; - - drawShadow(); - setPrintPos (1, 1+getHeight()); - setTransparent(); - print(' '); - unsetTransparent(); -} - -//---------------------------------------------------------------------- -void FDialog::draw() -{ - if ( tooltip && ! getMoveSizeWidget() ) + // set the cursor to the focus widget + FWidget* focus_widget = FWidget::getFocusWidget(); + if ( focus_widget + && focus_widget->isVisible() + && focus_widget->hasVisibleCursor() ) { - if ( tooltip ) - delete tooltip; + FPoint cursor_pos = focus_widget->getCursorPos(); + focus_widget->setCursorPos(cursor_pos); + } +} - tooltip = 0; +//---------------------------------------------------------------------- +void FDialog::activateDialog() +{ + FWidget* old_focus = FWidget::getFocusWidget(); + FWidget* win_focus = getWindowFocusWidget(); + setActiveWindow(this); + setFocus(); + setFocusWidget(this); + + if ( win_focus && numOfFocusableChildren() > 1 ) + { + win_focus->setFocus(); + win_focus->redraw(); + + if ( old_focus ) + old_focus->redraw(); + } + else if ( old_focus ) + { + if ( ! focusFirstChild() ) + old_focus->unsetFocus(); + + if ( ! old_focus->isWindowWidget() ) + old_focus->redraw(); } - updateVTerm(false); - // fill the background - setColor(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); - if ( isMonochron() ) - setReverse(true); - - clearArea (vwin); - drawBorder(); - drawTitleBar(); - setCursorPos(2, getHeight() - 1); - - if ( (flags & fc::shadow) != 0 ) - drawDialogShadow(); - - if ( isMonochron() ) - setReverse(false); - - updateVTerm(true); + updateTerminal(); } -//---------------------------------------------------------------------- -void FDialog::onShow (FShowEvent*) -{ } - -//---------------------------------------------------------------------- -void FDialog::onHide (FHideEvent*) -{ } - -//---------------------------------------------------------------------- -void FDialog::onClose (FCloseEvent* ev) -{ - ev->accept(); - result_code = FDialog::Reject; -} - -// public methods of FDialog //---------------------------------------------------------------------- void FDialog::onKeyPress (FKeyEvent* ev) { @@ -964,7 +772,7 @@ void FDialog::onMouseMove (FMouseEvent* ev) // Mouse event handover to the menu const FRect& menu_geometry = dialog_menu->getTermGeometry(); - if ( dialog_menu->count() > 0 + if ( dialog_menu->getCount() > 0 && menu_geometry.contains(ev->getTermPos()) ) { const FPoint& g = ev->getTermPos(); @@ -1110,8 +918,8 @@ void FDialog::onWindowActive (FEvent*) focusFirstChild(); } - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); } @@ -1179,332 +987,525 @@ void FDialog::onWindowLowered (FEvent*) } } + +// protected methods of FDialog //---------------------------------------------------------------------- -void FDialog::show() +void FDialog::done(int result) { - if ( ! isVisible() ) + hide(); + result_code = result; +} + +//---------------------------------------------------------------------- +void FDialog::draw() +{ + if ( tooltip && ! getMoveSizeWidget() ) + { + if ( tooltip ) + delete tooltip; + + tooltip = 0; + } + + updateVTerm(false); + // fill the background + setColor(); + + if ( isMonochron() ) + setReverse(true); + + clearArea (vwin); + drawBorder(); + drawTitleBar(); + setCursorPos(2, getHeight() - 1); + + if ( (flags & fc::shadow) != 0 ) + drawDialogShadow(); + + if ( isMonochron() ) + setReverse(false); + + updateVTerm(true); +} + +//---------------------------------------------------------------------- +void FDialog::drawDialogShadow() +{ + if ( isMonochron() && (flags & fc::trans_shadow) == 0 ) return; - FWindow::show(); - - if ( isModal() ) - { - FApplication* fapp = static_cast(getRootWidget()); - fapp->enter_loop(); - - if ( this == getMainWidget() ) - fapp->quit(); - } + drawShadow(); + setPrintPos (1, 1+getHeight()); + setTransparent(); + print(' '); + unsetTransparent(); } //---------------------------------------------------------------------- -void FDialog::hide() -{ - FWindow::hide(); - - if ( isModal() ) - { - FApplication* fapp = static_cast(getRootWidget()); - fapp->exit_loop(); - } -} +void FDialog::onShow (FShowEvent*) +{ } //---------------------------------------------------------------------- -int FDialog::exec() +void FDialog::onHide (FHideEvent*) +{ } + +//---------------------------------------------------------------------- +void FDialog::onClose (FCloseEvent* ev) { + ev->accept(); result_code = FDialog::Reject; - show(); - return result_code; +} + + +// private methods of FDialog +//---------------------------------------------------------------------- +void FDialog::init() +{ + FWidget* old_focus; + setTopPadding(2); + setLeftPadding(1); + setBottomPadding(1); + setRightPadding(1); + ignorePadding(); + setDialogWidget(); + // initialize geometry values + setGeometry (1, 1, 10, 10, false); + setMinimumSize (15, 4); + addDialog(this); + setActiveWindow(this); + setTransparentShadow(); + setForegroundColor (wc.dialog_fg); + setBackgroundColor (wc.dialog_bg); + + if ( hasFocus() ) + flags |= fc::focus; + + if ( isEnabled() ) + flags |= fc::active; + + old_focus = FWidget::getFocusWidget(); + + if ( old_focus ) + { + setFocus(); + old_focus->redraw(); + } + + accelerator_list = new Accelerators(); + // Add the dialog menu + dialog_menu = new FMenu ("-", this); + dialog_menu->setPos (getX(), getY()+1); + dgl_menuitem = dialog_menu->getItem(); + + if ( dgl_menuitem ) + { + dgl_menuitem->ignorePadding(); + dgl_menuitem->unsetFocusable(); + } + + move_size_item = new FMenuItem (dialog_menu); + move_size_item->setText ("&Move/Size"); + move_size_item->setStatusbarMessage ("Move or change the size of the window"); + + move_size_item->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &FDialog::cb_move) + ); + + zoom_item = new FMenuItem (dialog_menu); + setZoomItem(); + zoom_item->setDisable(); + + zoom_item->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &FDialog::cb_zoom) + ); + + close_item = new FMenuItem ("&Close", dialog_menu); + close_item->setStatusbarMessage ("Close this window"); + + close_item->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &FDialog::cb_close) + ); } //---------------------------------------------------------------------- -void FDialog::setPos (int x, int y, bool) +void FDialog::drawBorder() { - int dx, dy, old_x, old_y, rsw, bsh, width, height; - FRect old_geometry; + int x1 = 1; + int x2 = 1 + getWidth() - 1; + int y1 = 2; + int y2 = 1 + getHeight() - 1; - if ( getX() == x && getY() == y ) - return; + if ( (getMoveSizeWidget() == this || ! resize_click_pos.isNull()) + && ! isZoomed() ) + setColor (wc.dialog_resize_fg, getBackgroundColor()); + else + setColor(); - width = getWidth(); - height = getHeight(); - - // Avoid to move widget completely outside the terminal - if ( x+width <= 1 || x > getMaxWidth() || y < 1 || y > getMaxHeight() ) - return; - - if ( isZoomed() ) - return; - - dx = getX() - x; - dy = getY() - y; - old_x = getTermX(); - old_y = getTermY(); - const FPoint& shadow = getShadow(); - rsw = shadow.getX(); // right shadow width; - bsh = shadow.getY(); // bottom shadow height - old_geometry = getTermGeometryWithShadow(); - - // move to the new position - FWindow::setPos(x, y, false); - putArea (getTermPos(), vwin); - - // restoring the non-covered terminal areas - if ( getTermGeometry().overlap(old_geometry) ) + if ( isNewFont() ) { - // dx > 0 : move left - // dx = 0 : move vertical - // dx < 0 : move right - // dy > 0 : move up - // dy = 0 : move horizontal - // dy < 0 : move down - - if ( dx > 0 ) + for (int y=y1; y < y2; y++) { - if ( dy > 0 ) - restoreVTerm (old_x+width+rsw-dx, old_y, dx, getHeight()+bsh-dy); - else - restoreVTerm (old_x+width+rsw-dx, old_y+std::abs(dy), dx, height+bsh-std::abs(dy)); - } - else - { - if ( dy > 0 ) - restoreVTerm (old_x, old_y, std::abs(dx), height+bsh-dy); - else - restoreVTerm (old_x, old_y+std::abs(dy), std::abs(dx), height+bsh-std::abs(dy)); + setPrintPos (x1, y); + // border left ⎸ + print (fc::NF_border_line_left); + setPrintPos (x2, y); + // border right⎹ + print (fc::NF_rev_border_line_right); } - if ( dy > 0 ) - restoreVTerm (old_x, old_y+height+bsh-dy, width+rsw, dy); - else - restoreVTerm (old_x, old_y, width+rsw, std::abs(dy)); + setPrintPos (x1, y2); + // lower left corner border ⎣ + print (fc::NF_border_corner_lower_left); + + for (int x=1; x < getWidth()-1; x++) // low line _ + print (fc::NF_border_line_bottom); + + setPrintPos (x2, y2); + // lower right corner border ⎦ + print (fc::NF_rev_border_corner_lower_right); } else { - restoreVTerm (old_geometry); + FWidget::drawBorder(x1, y1, x2, y2); + } +} + +//---------------------------------------------------------------------- +void FDialog::drawTitleBar() +{ + int i,x,length, zoom_btn; + const int menu_btn = 3; + + // draw the title button + setPrintPos (1, 1); + + if ( dialog_menu && dialog_menu->isVisible() ) + setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); + else + setColor (wc.titlebar_button_fg, wc.titlebar_button_bg); + + if ( isMonochron() ) + { + if ( isWindowActive() ) + setReverse(false); + else + setReverse(true); } - // handle overlaid windows - if ( window_list && ! window_list->empty() ) + + if ( isNewFont() ) { - bool overlaid = false; - widgetList::const_iterator iter, end; - iter = window_list->begin(); - end = window_list->end(); + print (fc::NF_rev_menu_button1); + print (fc::NF_rev_menu_button2); + print (fc::NF_rev_menu_button3); + } + else if ( isMonochron() ) + { + print ('['); - while ( iter != end ) + if ( dgl_menuitem ) + print (dgl_menuitem->getText()); + else + print ('-'); + + print (']'); + } + else + { + print (' '); + + if ( dgl_menuitem ) + print (dgl_menuitem->getText()); + else + print ('-'); + + print (' '); + } + + // fill with spaces (left of the title) + if ( getMaxColor() < 16 ) + setBold(); + + if ( isWindowActive() || (dialog_menu && dialog_menu->isVisible()) ) + setColor (wc.titlebar_active_fg, wc.titlebar_active_bg); + else + setColor (wc.titlebar_inactive_fg, wc.titlebar_inactive_bg); + + if ( ! isResizeable() ) + zoom_btn = 0; + else if ( isNewFont() ) + zoom_btn = 2; + else + zoom_btn = 3; + + length = int(tb_text.getLength()); + i = getWidth() - length - menu_btn - zoom_btn; + i = int(i/2); + + for (x=1; x <= i; x++) + print (' '); + + // the title bar text + if ( tb_text ) + { + if ( length <= getWidth() - menu_btn - zoom_btn ) + print (tb_text); + else { - if ( overlaid ) - putArea ((*iter)->getTermPos(), (*iter)->getVWin()); - - if ( vwin == (*iter)->getVWin() ) - overlaid = true; - - ++iter; + print (tb_text.left(getWidth() - menu_btn - zoom_btn - 2)); + print (".."); } } - FWindow::adjustSize(); + // fill the rest of the bar + for (; x+1+length < getWidth()-zoom_btn-1; x++) + print (' '); - // set the cursor to the focus widget - FWidget* focus_widget = FWidget::getFocusWidget(); - if ( focus_widget - && focus_widget->isVisible() - && focus_widget->hasVisibleCursor() ) + if ( getMaxColor() < 16 ) + unsetBold(); + + // draw the zoom/unzoom button + if ( isResizeable() ) { - FPoint cursor_pos = focus_widget->getCursorPos(); - focus_widget->setCursorPos(cursor_pos); + if ( zoom_button_pressed ) + setColor (wc.titlebar_button_focus_fg, wc.titlebar_button_focus_bg); + else + setColor (wc.titlebar_button_fg, wc.titlebar_button_bg); + + if ( isZoomed() ) + { + if ( isNewFont() ) + { + print (fc::NF_rev_down_pointing_triangle1); + print (fc::NF_rev_down_pointing_triangle2); + } + else + { + if ( isMonochron() ) + { + print ('['); + print (fc::BlackDownPointingTriangle); // ▼ + print (']'); + } + else + { + print (' '); + + if ( isCygwinTerminal() ) + print ('v'); + else + print (fc::BlackDownPointingTriangle); // ▼ + + print (' '); + } + } + } + else // is not zoomed + { + if ( isNewFont() ) + { + print (fc::NF_rev_up_pointing_triangle1); + print (fc::NF_rev_up_pointing_triangle2); + } + else + { + if ( isMonochron() ) + { + print ('['); + print (fc::BlackUpPointingTriangle); // ▲ + print (']'); + } + else + { + print (' '); + + if ( isCygwinTerminal() ) + print ('^'); + else + print (fc::BlackUpPointingTriangle); // ▲ + + print (' '); + } + } + } } - updateTerminal(); + if ( isMonochron() ) + setReverse(false); + +/* print the number of window in stack */ +//setPrintPos (getWidth()-2, 1); +//printf ("(%d)", getWindowLayer(this)); } //---------------------------------------------------------------------- -void FDialog::move (int dx, int dy) +void FDialog::leaveMenu() { - setPos (getX() + dx, getY() + dy); -} + dialog_menu->unselectItem(); + dialog_menu->hide(); + activateWindow(); + raiseWindow(); -//---------------------------------------------------------------------- -void FDialog::setSize (int w, int h, bool adjust) -{ - int x, y, dw, dh, old_width, old_height, rsw, bsh; - - if ( getWidth() == w && getHeight() == h ) - return; - - if ( isZoomed() ) - return; - - x = getTermX(); - y = getTermY(); - old_width = getWidth(); - old_height = getHeight(); - dw = old_width - w; - dh = old_height - h; - const FPoint& shadow = getShadow(); - rsw = shadow.getX(); // right shadow width; - bsh = shadow.getY(); // bottom shadow height - - FWindow::setSize (w, h, adjust); - - // get adjust width and height - w = getWidth(); - h = getHeight(); - - // dw > 0 : scale down width - // dw = 0 : scale only height - // dw < 0 : scale up width - // dh > 0 : scale down height - // dh = 0 : scale only width - // dh < 0 : scale up height - - // restoring the non-covered terminal areas - if ( dw > 0 ) - restoreVTerm (x+w+rsw, y, dw, h+bsh+dh); // restore right - - if ( dh > 0 ) - restoreVTerm (x, y+h+bsh, w+rsw+dw, dh); // restore bottom + if ( getWindowFocusWidget() ) + getWindowFocusWidget()->setFocus(); redraw(); - // handle overlaid windows - if ( window_list && ! window_list->empty() ) - { - bool overlaid = false; - widgetList::const_iterator iter, end; - iter = window_list->begin(); - end = window_list->end(); - - while ( iter != end ) - { - if ( overlaid ) - putArea ((*iter)->getTermPos(), (*iter)->getVWin()); - - if ( vwin == (*iter)->getVWin() ) - overlaid = true; - - ++iter; - } - } - - // set the cursor to the focus widget - FWidget* focus_widget = FWidget::getFocusWidget(); - if ( focus_widget - && focus_widget->isVisible() - && focus_widget->hasVisibleCursor() ) - { - FPoint cursor_pos = focus_widget->getCursorPos(); - focus_widget->setCursorPos(cursor_pos); - } -} - -//---------------------------------------------------------------------- -void FDialog::activateDialog() -{ - FWidget* old_focus = FWidget::getFocusWidget(); - FWidget* win_focus = getWindowFocusWidget(); - setActiveWindow(this); - setFocus(); - setFocusWidget(this); - - if ( win_focus && numOfFocusableChildren() > 1 ) - { - win_focus->setFocus(); - win_focus->redraw(); - - if ( old_focus ) - old_focus->redraw(); - } - else if ( old_focus ) - { - if ( ! focusFirstChild() ) - old_focus->unsetFocus(); - - if ( ! old_focus->isWindowWidget() ) - old_focus->redraw(); - } - - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); + flush_out(); } //---------------------------------------------------------------------- -bool FDialog::setFocus (bool on) +void FDialog::openMenu() { - FWidget::setFocus(on); + // open the titlebar menu + if ( ! dialog_menu ) + return; - if ( on ) - flags |= fc::focus; - else - flags &= ~fc::focus; - - return on; -} - -//---------------------------------------------------------------------- -bool FDialog::setDialogWidget (bool on) -{ - if ( isDialogWidget() == on ) - return true; - - if ( on ) + if ( dialog_menu->isVisible() ) { - flags |= fc::dialog_widget; - setTermOffsetWithPadding(); + leaveMenu(); + drawTitleBar(); } else { - flags &= ~fc::dialog_widget; - setParentOffset(); + setOpenMenu(dialog_menu); + dialog_menu->setPos (getX(), getY()+1); + dialog_menu->setVisible(); + drawTitleBar(); + dialog_menu->show(); + dialog_menu->raiseWindow(dialog_menu); + dialog_menu->redraw(); } - - return on; } //---------------------------------------------------------------------- -bool FDialog::setModal (bool on) +void FDialog::selectFirstMenuItem() { - if ( isModal() == on ) - return true; + // focus to the first enabled menu item + FMenuItem* first_item; + dialog_menu->selectFirstItem(); + first_item = dialog_menu->getSelectedItem(); - if ( on ) + if ( first_item ) + first_item->setFocus(); + + dialog_menu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); +} + +//---------------------------------------------------------------------- +void FDialog::setZoomItem() +{ + if ( isZoomed() ) { - flags |= fc::modal; - modal_dialogs++; + zoom_item->setText ("&Unzoom"); + zoom_item->setStatusbarMessage ("Restore the window size"); + move_size_item->setDisable(); } else { - flags &= ~fc::modal; - modal_dialogs--; + zoom_item->setText ("&Zoom"); + zoom_item->setStatusbarMessage ("Enlarge the window to the entire desktop"); + move_size_item->setEnable(); + } +} + +//---------------------------------------------------------------------- +void FDialog::addDialog (FWidget* obj) +{ + // add the dialog object obj to the dialog list + if ( dialog_list ) + dialog_list->push_back(obj); +} + +//---------------------------------------------------------------------- +void FDialog::delDialog (FWidget* obj) +{ + // delete the dialog object obj from the dialog list + if ( ! dialog_list || dialog_list->empty() ) + return; + + widgetList::iterator iter; + iter = dialog_list->begin(); + + while ( iter != dialog_list->end() ) + { + if ( (*iter) == obj ) + { + dialog_list->erase(iter); + return; + } + + ++iter; + } +} + +//---------------------------------------------------------------------- +void FDialog::cb_move (FWidget*, void*) +{ + if ( isZoomed() ) + return; + + setMoveSizeWidget(this); + drawBorder(); + save_geometry = getGeometry(); + tooltip = new FToolTip(this); + + if ( isResizeable() ) + { + if ( isLinuxTerm() ) + tooltip->setText ( " Arrow keys: Move\n" + "Shift + Arrow keys: Resize\n" + " Enter: Done\n" + " Esc: Cancel" ); + else + 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" ); } - return on; -} - - -//---------------------------------------------------------------------- -bool FDialog::setScrollable (bool on) -{ - if ( on ) - flags |= fc::scrollable; - else - flags &= ~fc::scrollable; - - return on; + tooltip->show(); } //---------------------------------------------------------------------- -bool FDialog::setResizeable (bool on) +void FDialog::cb_zoom (FWidget*, void*) { - FWindow::setResizeable (on); - - if ( on ) - zoom_item->setEnable(); - else - zoom_item->setDisable(); - - return on; + dialog_menu->unselectItem(); + dialog_menu->hide(); + setClickedWidget(0); + drawTitleBar(); + zoomWindow(); + setZoomItem(); +} + +//---------------------------------------------------------------------- +void FDialog::cb_close (FWidget*, void*) +{ + dialog_menu->unselectItem(); + dialog_menu->hide(); + setClickedWidget(0); + drawTitleBar(); + close(); } diff --git a/src/fdialog.h b/src/fdialog.h index 4b16d025..c9b67d53 100644 --- a/src/fdialog.h +++ b/src/fdialog.h @@ -49,113 +49,122 @@ class FDialog : public FWindow { public: + // Using-declaration + using FWindow::setResizeable; + using FWindow::move; + using FWindow::setPos; + + // Enumeration enum DialogCode { Reject = 0, Accept = 1 }; - private: - FString tb_text; // title bar text - int result_code; - bool zoom_button_pressed; - bool zoom_button_active; - FPoint titlebar_click_pos; - FPoint resize_click_pos; - FRect save_geometry; // required by move/size by keyboard - FMenu* dialog_menu; - FMenuItem* dgl_menuitem; - FMenuItem* move_size_item; - FMenuItem* zoom_item; - FMenuItem* close_item; - FToolTip* tooltip; - - private: - // Disable copy constructor - FDialog (const FDialog&); - // Disable assignment operator (=) - FDialog& operator = (const FDialog&); - - void init(); - // make every drawBorder from FWidget available - using FWidget::drawBorder; - virtual void drawBorder(); - void drawTitleBar(); - void leaveMenu(); - void openMenu(); - void selectFirstMenuItem(); - void setZoomItem(); - - // Callback methods - void cb_move (FWidget*, void*); - void cb_zoom (FWidget*, void*); - void cb_close (FWidget*, void*); - - static void addDialog (FWidget*); - static void delDialog (FWidget*); - - protected: - virtual void done (int); - virtual void draw(); - virtual void onShow (FShowEvent*); - virtual void onHide (FHideEvent*); - virtual void onClose (FCloseEvent*); - - public: // Constructors explicit FDialog (FWidget* = 0); FDialog (const FString&, FWidget* = 0); + // Destructor virtual ~FDialog(); + // Accessors virtual const char* getClassName() const; + FString getText() const; + + // Mutators + bool setFocus (bool); + bool setFocus(); + bool unsetFocus(); + bool setDialogWidget (bool); + bool setDialogWidget(); + bool unsetDialogWidget(); + bool setModal (bool); + bool setModal(); + bool unsetModal(); + bool setResizeable (bool); + bool setScrollable (bool); + bool setScrollable(); + bool unsetScrollable(); + void setText (const FString&); + + // Inquiries + bool isModal(); + bool isScrollable(); + + // Methods + void show(); + void hide(); + int exec(); + void setPos (int, int, bool = true); + void move (int, int); + void setSize (int, int, bool = true); + void activateDialog(); // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onMouseDoubleClick (FMouseEvent*); - void onAccel (FAccelEvent*); - void onWindowActive (FEvent*); - void onWindowInactive (FEvent*); - void onWindowRaised (FEvent*); - void onWindowLowered (FEvent*); + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onMouseDoubleClick (FMouseEvent*); + void onAccel (FAccelEvent*); + void onWindowActive (FEvent*); + void onWindowInactive (FEvent*); + void onWindowRaised (FEvent*); + void onWindowLowered (FEvent*); - void activateDialog(); - void drawDialogShadow(); - void show(); - void hide(); - int exec(); - void setPos (int, int, bool = true); - // make every setPos from FWindow available - using FWindow::setPos; - void move (int, int); - // make every move from FWindow available - using FWindow::move; - void setSize (int, int, bool = true); + protected: + // Methods + virtual void done (int); + virtual void draw(); + void drawDialogShadow(); - bool setFocus (bool); - bool setFocus(); - bool unsetFocus(); - bool setDialogWidget (bool); - bool setDialogWidget(); - bool unsetDialogWidget(); - bool setModal (bool); - bool setModal(); - bool unsetModal(); - bool isModal(); - bool setResizeable (bool); - // make every setResizeable from FWindow available - using FWindow::setResizeable; - bool setScrollable (bool); - bool setScrollable(); - bool unsetScrollable(); - bool isScrollable(); - FString getText() const; - void setText (const FString&); + // Event handlers + virtual void onShow (FShowEvent*); + virtual void onHide (FHideEvent*); + virtual void onClose (FCloseEvent*); private: + // Using-declaration + using FWidget::drawBorder; + + // Disable copy constructor + FDialog (const FDialog&); + + // Disable assignment operator (=) + FDialog& operator = (const FDialog&); + + // Methods + void init(); + virtual void drawBorder(); + void drawTitleBar(); + void leaveMenu(); + void openMenu(); + void selectFirstMenuItem(); + void setZoomItem(); + static void addDialog (FWidget*); + static void delDialog (FWidget*); + + // Callback methods + void cb_move (FWidget*, void*); + void cb_zoom (FWidget*, void*); + void cb_close (FWidget*, void*); + + // Data Members + FString tb_text; // title bar text + int result_code; + bool zoom_button_pressed; + bool zoom_button_active; + FPoint titlebar_click_pos; + FPoint resize_click_pos; + FRect save_geometry; // required by keyboard move/size + FMenu* dialog_menu; + FMenuItem* dgl_menuitem; + FMenuItem* move_size_item; + FMenuItem* zoom_item; + FMenuItem* close_item; + FToolTip* tooltip; + // Friend function from FMenu friend void FMenu::hideSuperMenus(); }; @@ -166,6 +175,10 @@ class FDialog : public FWindow inline const char* FDialog::getClassName() const { return "FDialog"; } +//---------------------------------------------------------------------- +inline FString FDialog::getText() const +{ return tb_text; } + //---------------------------------------------------------------------- inline bool FDialog::setFocus() { return setFocus(true); } @@ -190,10 +203,6 @@ inline bool FDialog::setModal() inline bool FDialog::unsetModal() { return setModal(false); } -//---------------------------------------------------------------------- -inline bool FDialog::isModal() -{ return ((flags & fc::modal) != 0); } - //---------------------------------------------------------------------- inline bool FDialog::setScrollable() { return setScrollable(true); } @@ -202,17 +211,18 @@ inline bool FDialog::setScrollable() inline bool FDialog::unsetScrollable() { return setScrollable(false); } -//---------------------------------------------------------------------- -inline bool FDialog::isScrollable() -{ return ((flags & fc::scrollable) != 0); } - -//---------------------------------------------------------------------- -inline FString FDialog::getText() const -{ return tb_text; } - //---------------------------------------------------------------------- inline void FDialog::setText (const FString& txt) { tb_text = txt; } +//---------------------------------------------------------------------- +inline bool FDialog::isModal() +{ return ((flags & fc::modal) != 0); } + +//---------------------------------------------------------------------- +inline bool FDialog::isScrollable() +{ return ((flags & fc::scrollable) != 0); } + + #endif // _FDIALOG_H diff --git a/src/fdialoglistmenu.h b/src/fdialoglistmenu.h index 1a69ceb5..9c00dcfc 100644 --- a/src/fdialoglistmenu.h +++ b/src/fdialoglistmenu.h @@ -52,24 +52,28 @@ class FDialogListMenu : public FMenu { - private: - // Disable copy constructor - FDialogListMenu (const FDialogListMenu&); - // Disable assignment operator (=) - FDialogListMenu& operator = (const FDialogListMenu&); - - void init(); - public: // Constructors explicit FDialogListMenu (FWidget* = 0); FDialogListMenu (FString&, FWidget* = 0); FDialogListMenu (const std::string&, FWidget* = 0); FDialogListMenu (const char*, FWidget* = 0); + // Destructor virtual ~FDialogListMenu(); + // Accessors virtual const char* getClassName() const; + + private: + // Disable copy constructor + FDialogListMenu (const FDialogListMenu&); + + // Disable assignment operator (=) + FDialogListMenu& operator = (const FDialogListMenu&); + + // Method + void init(); }; #pragma pack(pop) diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index db0b93f5..aab1682f 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -3,15 +3,18 @@ #include "ffiledialog.h" +// non-member functions //---------------------------------------------------------------------- -static bool sortByName (const dir_entry &lhs, const dir_entry &rhs) +bool sortByName ( const FFileDialog::dir_entry& lhs + , const FFileDialog::dir_entry& rhs ) { // lhs < rhs return bool(strcasecmp(lhs.name, rhs.name) < 0); } //---------------------------------------------------------------------- -static bool sortDirFirst (const dir_entry &lhs, const dir_entry &rhs) +bool sortDirFirst ( const FFileDialog::dir_entry& lhs + , const FFileDialog::dir_entry& rhs ) { // sort directories first if ( lhs.type == DT_DIR && rhs.type != DT_DIR ) @@ -101,6 +104,366 @@ FFileDialog::~FFileDialog() // destructor } +// public methods of FFileDialog +//---------------------------------------------------------------------- +FFileDialog& FFileDialog::operator = (const FFileDialog& fdlg) +{ + if ( &fdlg == this ) + { + return *this; + } + else + { + delete open; + delete cancel; + delete hidden; + delete filebrowser; + delete filename; + clear(); + + if ( fdlg.getParentWidget() ) + fdlg.getParentWidget()->addChild (this); + + directory = fdlg.directory; + filter_pattern = fdlg.filter_pattern; + dlg_type = fdlg.dlg_type; + show_hidden = fdlg.show_hidden; + + if ( directory ) + setPath(directory); + + init(); + return *this; + } +} + +//---------------------------------------------------------------------- +const FString FFileDialog::getSelectedFile() const +{ + uLong n = uLong(filebrowser->currentItem() - 1); + + if ( dir_entries[n].type == DT_DIR ) + return FString(""); + else + return FString(dir_entries[n].name); +} + +//---------------------------------------------------------------------- +void FFileDialog::setPath (const FString& dir) +{ + const char* dirname = dir.c_str(); + char resolved_path[MAXPATHLEN]; + FString r_dir; + struct stat sb; + + if ( stat(dirname, &sb) != 0 ) + { + directory = '/'; + return; + } + + if ( S_ISLNK(sb.st_mode) ) + { + if ( lstat(dirname, &sb) != 0 ) + { + directory = '/'; + return; + } + } + + if ( ! S_ISDIR(sb.st_mode) ) + { + directory = '/'; + return; + } + + if ( realpath(dir.c_str(), resolved_path) != 0 ) + r_dir = resolved_path; + else + r_dir = dir; + + if ( r_dir[r_dir.getLength()-1] != '/' ) + directory = r_dir + "/"; + else + directory = r_dir; +} + +//---------------------------------------------------------------------- +void FFileDialog::setFilter (const FString& filter) +{ + filter_pattern = filter; +} + +//---------------------------------------------------------------------- +bool FFileDialog::setShowHiddenFiles (bool on) +{ + if ( on == show_hidden ) + return show_hidden; + + show_hidden = on; + readDir(); + filebrowser->redraw(); + return show_hidden; +} + +//---------------------------------------------------------------------- +void FFileDialog::onKeyPress (FKeyEvent* ev) +{ + if ( ! isEnabled() ) + return; + + FDialog::onKeyPress (ev); + + if ( ! filebrowser->hasFocus() ) + return; + + int key = ev->key(); + + switch ( key ) + { + case fc::Fkey_erase: + case fc::Fkey_backspace: + changeDir(".."); + ev->accept(); + break; + + default: + break; + } + +} + +//---------------------------------------------------------------------- +int FFileDialog::readDir() +{ + int start, dir_num; + const char* dir = directory.c_str(); + const char* filter = filter_pattern.c_str(); + errno = 0; + directory_stream = opendir(dir); + + if ( ! directory_stream ) + { + FMessageBox::error (this, "Can't open directory\n" + directory); + return -1; + } + + clear(); + + while ( true ) + { + errno = 0; + struct dirent* next = readdir (directory_stream); + + if ( next ) + { + if ( next->d_name[0] == '.' && next->d_name[1] == '\0' ) + continue; + + if ( ! show_hidden + && next->d_name[0] == '.' + && next->d_name[1] != '\0' + && next->d_name[1] != '.' ) + { + continue; + } + + if ( dir[0] == '/' && dir[1] == '\0' && std::strcmp(next->d_name, "..") == 0 ) + continue; + + dir_entry entry; + entry.name = strdup(next->d_name); + entry.type = next->d_type; + + if ( next->d_type == DT_LNK ) // symbolic link + { + char resolved_path[MAXPATHLEN] = {}; + char symLink[MAXPATHLEN] = {}; + std::strncpy (symLink, dir, sizeof(symLink) - 1); + std::strncat (symLink, next->d_name, sizeof(symLink) - std::strlen(symLink) - 1); + + if ( realpath(symLink, resolved_path) != 0 ) // follow link + { + struct stat sb; + + if ( lstat(resolved_path, &sb) == 0 ) + { + if ( S_ISDIR(sb.st_mode) ) + entry.type = DT_DIR; + } + } + } + + if ( entry.type == DT_DIR ) + dir_entries.push_back (entry); + else if ( pattern_match(filter, entry.name) ) + dir_entries.push_back (entry); + else + std::free(entry.name); + } + else if (errno != 0) + { + FMessageBox::error (this, "Reading directory\n" + directory); + + if ( errno != EOVERFLOW ) + break; + } + else + break; + + } // end while + + if ( closedir (directory_stream) != 0 ) + { + FMessageBox::error (this, "Closing directory\n" + directory); + return -2; + } + + if ( std::strcmp((*dir_entries.begin()).name, "..") == 0 ) + start=1; + else + start=0; + + dir_num = numOfDirs(); + // directories first + std::sort(dir_entries.begin()+start, dir_entries.end(), sortDirFirst); + // sort directories by name + std::sort(dir_entries.begin()+start, dir_entries.begin()+dir_num, sortByName); + // sort files by name + std::sort(dir_entries.begin()+dir_num, dir_entries.end(), sortByName); + // fill list with directory entries + filebrowser->clear(); + + if ( ! dir_entries.empty() ) + { + std::vector::const_iterator iter, end; + iter = dir_entries.begin(); + end = dir_entries.end(); + + while ( iter != end ) + { + if ( (*iter).type == DT_DIR ) + filebrowser->insert(FString((*iter).name), fc::SquareBrackets); + else + filebrowser->insert(FString((*iter).name)); + + ++iter; + } + } + + return 0; +} + +//---------------------------------------------------------------------- +FString FFileDialog::fileOpenChooser ( FWidget* parent + , const FString& dirname + , const FString& filter ) +{ + FFileDialog* fileopen; + FString ret; + FString path = dirname; + FString file_filter = filter; + + if ( path.isNull() || path.isEmpty() ) + { + path = getHomeDir(); + + if ( path.isEmpty() || path.isEmpty() ) + path = FString("/"); + } + + if ( file_filter.isNull() || file_filter.isEmpty() ) + file_filter = FString("*"); + + fileopen = new FFileDialog ( path + , file_filter + , FFileDialog::Open + , parent ); + + if ( fileopen->exec() == FDialog::Accept ) + ret = fileopen->getPath() + fileopen->getSelectedFile(); + else + ret = FString(); + + delete fileopen; + return ret; +} + +//---------------------------------------------------------------------- +FString FFileDialog::fileSaveChooser ( FWidget* parent + , const FString& dirname + , const FString& filter ) +{ + FFileDialog* fileopen; + FString ret; + FString path = dirname; + FString file_filter = filter; + + if ( path.isNull() || path.isEmpty() ) + { + path = getHomeDir(); + + if ( path.isEmpty() || path.isEmpty() ) + path = FString("/"); + } + + if ( file_filter.isNull() || file_filter.isEmpty() ) + file_filter = FString("*"); + + fileopen = new FFileDialog ( path + , file_filter + , FFileDialog::Save + , parent ); + + if ( fileopen->exec() == FDialog::Accept ) + ret = fileopen->getPath() + fileopen->getSelectedFile(); + else + ret = FString(); + + delete fileopen; + return ret; +} + + +// protected methods of FFileDialog +//---------------------------------------------------------------------- +void FFileDialog::adjustSize() +{ + int h, X, Y, max_width, max_height; + FWidget* root_widget = getRootWidget(); + + if ( root_widget ) + { + max_width = root_widget->getClientWidth(); + max_height = root_widget->getClientHeight(); + } + else + { + max_width = 80; + max_height = 24; + } + + h = max_height - 6; + + if ( h < 15 ) // minimum + h = 15; + + if ( h > 30 ) // maximum + h = 30; + + setHeight (h, false); + X = 1 + int((max_width - getWidth()) / 2); + Y = 1 + int((max_height - getHeight()) / 3); + setPos(X, Y, false); + filebrowser->setHeight (h-8, false); + hidden->setY(h-4, false); + cancel->setY(h-4, false); + open->setY(h-4, false); + FDialog::adjustSize(); + printPath(directory); +} + + // private methods of FFileDialog //---------------------------------------------------------------------- void FFileDialog::init() @@ -452,353 +815,3 @@ void FFileDialog::cb_processShowHidden (FWidget*, void*) { setShowHiddenFiles(not show_hidden); } - - -// protected methods of FFileDialog -//---------------------------------------------------------------------- -void FFileDialog::adjustSize() -{ - int h, X, Y, max_width, max_height; - FWidget* root_widget = getRootWidget(); - - if ( root_widget ) - { - max_width = root_widget->getClientWidth(); - max_height = root_widget->getClientHeight(); - } - else - { - max_width = 80; - max_height = 24; - } - - h = max_height - 6; - - if ( h < 15 ) // minimum - h = 15; - - if ( h > 30 ) // maximum - h = 30; - - setHeight (h, false); - X = 1 + int((max_width - getWidth()) / 2); - Y = 1 + int((max_height - getHeight()) / 3); - setPos(X, Y, false); - filebrowser->setHeight (h-8, false); - hidden->setY(h-4, false); - cancel->setY(h-4, false); - open->setY(h-4, false); - FDialog::adjustSize(); - printPath(directory); -} - - -// public methods of FFileDialog -//---------------------------------------------------------------------- -FFileDialog& FFileDialog::operator = (const FFileDialog& fdlg) -{ - if ( &fdlg == this ) - { - return *this; - } - else - { - delete open; - delete cancel; - delete hidden; - delete filebrowser; - delete filename; - clear(); - - if ( fdlg.getParentWidget() ) - fdlg.getParentWidget()->addChild (this); - - directory = fdlg.directory; - filter_pattern = fdlg.filter_pattern; - dlg_type = fdlg.dlg_type; - show_hidden = fdlg.show_hidden; - - if ( directory ) - setPath(directory); - - init(); - return *this; - } -} - -//---------------------------------------------------------------------- -void FFileDialog::onKeyPress (FKeyEvent* ev) -{ - if ( ! isEnabled() ) - return; - - FDialog::onKeyPress (ev); - - if ( ! filebrowser->hasFocus() ) - return; - - int key = ev->key(); - - switch ( key ) - { - case fc::Fkey_erase: - case fc::Fkey_backspace: - changeDir(".."); - ev->accept(); - break; - - default: - break; - } - -} - -//---------------------------------------------------------------------- -void FFileDialog::setPath (const FString& dir) -{ - const char* dirname = dir.c_str(); - char resolved_path[MAXPATHLEN]; - FString r_dir; - struct stat sb; - - if ( stat(dirname, &sb) != 0 ) - { - directory = '/'; - return; - } - - if ( S_ISLNK(sb.st_mode) ) - { - if ( lstat(dirname, &sb) != 0 ) - { - directory = '/'; - return; - } - } - - if ( ! S_ISDIR(sb.st_mode) ) - { - directory = '/'; - return; - } - - if ( realpath(dir.c_str(), resolved_path) != 0 ) - r_dir = resolved_path; - else - r_dir = dir; - - if ( r_dir[r_dir.getLength()-1] != '/' ) - directory = r_dir + "/"; - else - directory = r_dir; -} - -//---------------------------------------------------------------------- -void FFileDialog::setFilter (const FString& filter) -{ - filter_pattern = filter; -} - -//---------------------------------------------------------------------- -const FString FFileDialog::getSelectedFile() const -{ - uLong n = uLong(filebrowser->currentItem() - 1); - - if ( dir_entries[n].type == DT_DIR ) - return FString(""); - else - return FString(dir_entries[n].name); -} - -//---------------------------------------------------------------------- -int FFileDialog::readDir() -{ - int start, dir_num; - const char* dir = directory.c_str(); - const char* filter = filter_pattern.c_str(); - errno = 0; - directory_stream = opendir(dir); - - if ( ! directory_stream ) - { - FMessageBox::error (this, "Can't open directory\n" + directory); - return -1; - } - - clear(); - - while ( true ) - { - errno = 0; - struct dirent* next = readdir (directory_stream); - - if ( next ) - { - if ( next->d_name[0] == '.' && next->d_name[1] == '\0' ) - continue; - - if ( ! show_hidden - && next->d_name[0] == '.' - && next->d_name[1] != '\0' - && next->d_name[1] != '.' ) - { - continue; - } - - if ( dir[0] == '/' && dir[1] == '\0' && std::strcmp(next->d_name, "..") == 0 ) - continue; - - dir_entry entry; - entry.name = strdup(next->d_name); - entry.type = next->d_type; - - if ( next->d_type == DT_LNK ) // symbolic link - { - char resolved_path[MAXPATHLEN] = {}; - char symLink[MAXPATHLEN] = {}; - std::strncpy (symLink, dir, sizeof(symLink) - 1); - std::strncat (symLink, next->d_name, sizeof(symLink) - std::strlen(symLink) - 1); - - if ( realpath(symLink, resolved_path) != 0 ) // follow link - { - struct stat sb; - - if ( lstat(resolved_path, &sb) == 0 ) - { - if ( S_ISDIR(sb.st_mode) ) - entry.type = DT_DIR; - } - } - } - - if ( entry.type == DT_DIR ) - dir_entries.push_back (entry); - else if ( pattern_match(filter, entry.name) ) - dir_entries.push_back (entry); - else - std::free(entry.name); - } - else if (errno != 0) - { - FMessageBox::error (this, "Reading directory\n" + directory); - - if ( errno != EOVERFLOW ) - break; - } - else - break; - - } // end while - - if ( closedir (directory_stream) != 0 ) - { - FMessageBox::error (this, "Closing directory\n" + directory); - return -2; - } - - if ( std::strcmp((*dir_entries.begin()).name, "..") == 0 ) - start=1; - else - start=0; - - dir_num = numOfDirs(); - // directories first - std::sort(dir_entries.begin()+start, dir_entries.end(), sortDirFirst); - // sort directories by name - std::sort(dir_entries.begin()+start, dir_entries.begin()+dir_num, sortByName); - // sort files by name - std::sort(dir_entries.begin()+dir_num, dir_entries.end(), sortByName); - // fill list with directory entries - filebrowser->clear(); - - if ( ! dir_entries.empty() ) - { - std::vector::const_iterator iter, end; - iter = dir_entries.begin(); - end = dir_entries.end(); - - while ( iter != end ) - { - if ( (*iter).type == DT_DIR ) - filebrowser->insert(FString((*iter).name), fc::SquareBrackets); - else - filebrowser->insert(FString((*iter).name)); - - ++iter; - } - } - - return 0; -} - -//---------------------------------------------------------------------- -bool FFileDialog::setShowHiddenFiles (bool on) -{ - if ( on == show_hidden ) - return show_hidden; - - show_hidden = on; - readDir(); - filebrowser->redraw(); - return show_hidden; -} - -//---------------------------------------------------------------------- -FString FFileDialog::fileOpenChooser ( FWidget* parent - , const FString& dirname - , const FString& filter ) -{ - FFileDialog* fileopen; - FString ret; - FString path = dirname; - FString file_filter = filter; - - if ( path.isNull() ) - path = getHomeDir(); - - if ( file_filter.isNull() ) - file_filter = FString("*"); - - fileopen = new FFileDialog ( path - , file_filter - , FFileDialog::Open - , parent ); - - if ( fileopen->exec() == FDialog::Accept ) - ret = fileopen->getPath() + fileopen->getSelectedFile(); - else - ret = FString(); - - delete fileopen; - return ret; -} - -//---------------------------------------------------------------------- -FString FFileDialog::fileSaveChooser ( FWidget* parent - , const FString& dirname - , const FString& filter ) -{ - FFileDialog* fileopen; - FString ret; - FString path = dirname; - FString file_filter = filter; - - if ( path.isNull() ) - path = getHomeDir(); - - if ( file_filter.isNull() ) - file_filter = FString("*"); - - fileopen = new FFileDialog ( path - , file_filter - , FFileDialog::Save - , parent ); - - if ( fileopen->exec() == FDialog::Accept ) - ret = fileopen->getPath() + fileopen->getSelectedFile(); - else - ret = FString(); - - delete fileopen; - return ret; -} diff --git a/src/ffiledialog.h b/src/ffiledialog.h index 0fc00e82..d5acbffc 100644 --- a/src/ffiledialog.h +++ b/src/ffiledialog.h @@ -57,17 +57,6 @@ #include "fterm.h" -#pragma pack(push) -#pragma pack(1) - -struct dir_entry -{ - char* name; - uChar type; -}; -#pragma pack(pop) - - //---------------------------------------------------------------------- // class FFileDialog //---------------------------------------------------------------------- @@ -78,27 +67,67 @@ struct dir_entry class FFileDialog : public FDialog { public: + // Enumeration enum DialogType { Open = 0, Save = 1 }; - private: - DIR* directory_stream; - std::vector dir_entries; + // Constructors + explicit FFileDialog (FWidget* = 0); + FFileDialog (const FFileDialog&); // copy constructor + FFileDialog ( const FString& + , const FString& + , DialogType = FFileDialog::Open + , FWidget* = 0 ); + // Destructor + ~FFileDialog(); - FString directory; - FString filter_pattern; - FListBox* filebrowser; - FLineEdit* filename; - FCheckBox* hidden; - FButton* cancel; - FButton* open; - DialogType dlg_type; - bool show_hidden; + // Assignment operator (=) + FFileDialog& operator = (const FFileDialog&); + + // Accessors + const char* getClassName() const; + const FString getPath() const; + const FString getFilter() const; + const FString getSelectedFile() const; + bool getShowHiddenFiles(); + + // Mutators + void setPath (const FString&); + void setFilter (const FString&); + bool setShowHiddenFiles(bool); + bool setShowHiddenFiles(); + bool unsetShowHiddenFiles(); + + // Event handler + void onKeyPress (FKeyEvent*); + + // Methods + int readDir(); + static FString fileOpenChooser ( FWidget* + , const FString& = FString() + , const FString& = FString() ); + static FString fileSaveChooser ( FWidget* + , const FString& = FString() + , const FString& = FString() ); + + protected: + // Method + void adjustSize(); private: + // Typedef + struct dir_entry + { + char* name; + uChar type; + }; + + typedef std::vector dirEntries; + + // Method void init(); static char* getHomeDir(); inline bool pattern_match (const char*, const char*); @@ -115,45 +144,24 @@ class FFileDialog : public FDialog void cb_processOpen (FWidget*, void*); void cb_processShowHidden (FWidget*, void*); - protected: - void adjustSize(); + // Data Members + DIR* directory_stream; + dirEntries dir_entries; + FString directory; + FString filter_pattern; + FListBox* filebrowser; + FLineEdit* filename; + FCheckBox* hidden; + FButton* cancel; + FButton* open; + DialogType dlg_type; + bool show_hidden; - public: - // Constructors - explicit FFileDialog (FWidget* = 0); - FFileDialog (const FFileDialog&); // copy constructor - FFileDialog ( const FString& - , const FString& - , DialogType = FFileDialog::Open - , FWidget* = 0 ); - // Destructor - ~FFileDialog(); - - // Assignment operator (=) - FFileDialog& operator = (const FFileDialog&); - - const char* getClassName() const; - - // Event handler - void onKeyPress (FKeyEvent*); - - const FString getPath() const; - void setPath (const FString&); - const FString getFilter() const; - void setFilter (const FString&); - const FString getSelectedFile() const; - int readDir(); - bool setShowHiddenFiles(bool); - bool setShowHiddenFiles(); - bool unsetShowHiddenFiles(); - bool getShowHiddenFiles(); - - static FString fileOpenChooser ( FWidget* - , const FString& = FString() - , const FString& = FString() ); - static FString fileSaveChooser ( FWidget* - , const FString& = FString() - , const FString& = FString() ); + // Friend functions + friend bool sortByName ( const FFileDialog::dir_entry& + , const FFileDialog::dir_entry& ); + friend bool sortDirFirst ( const FFileDialog::dir_entry& + , const FFileDialog::dir_entry& ); }; #pragma pack(pop) diff --git a/src/flabel.cpp b/src/flabel.cpp index 2ec4dadf..ae54186e 100644 --- a/src/flabel.cpp +++ b/src/flabel.cpp @@ -51,6 +51,208 @@ FLabel::~FLabel() // destructor } +// public methods of FLabel +//---------------------------------------------------------------------- +void FLabel::setAccelWidget (FWidget* widget) +{ + if ( widget ) + accel_widget = widget; + + accel_widget->addCallback + ( + "destroy", + _METHOD_CALLBACK (this, &FLabel::cb_accel_widget_destroyed) + ); +} + +//---------------------------------------------------------------------- +void FLabel::setAlignment (uInt align) +{ + if ( align != fc::alignLeft + && align != fc::alignCenter + && align != fc::alignRight ) + alignment = fc::alignLeft; + else + alignment = align; +} + +//---------------------------------------------------------------------- +bool FLabel::setEmphasis (bool on) +{ + if ( emphasis != on ) + emphasis = on; + + return on; +} + +//---------------------------------------------------------------------- +bool FLabel::setReverseMode (bool on) +{ + if ( reverse_mode != on ) + reverse_mode = on; + + return on; +} + +//---------------------------------------------------------------------- +bool FLabel::setEnable (bool on) +{ + FWidget::setEnable(on); + + if ( on ) + { + flags |= fc::active; + setHotkeyAccelerator(); + } + else + { + flags &= ~fc::active; + delAccelerator(); + } + + return on; +} + +//---------------------------------------------------------------------- +void FLabel::setNumber (long num) +{ + setText(FString().setNumber(num)); +} + +//---------------------------------------------------------------------- +void FLabel::setText (const FString& txt) +{ + text = txt; + multiline_text = text.split("\r\n"); + + if ( int(multiline_text.size()) > 1 ) + multiline = true; + else + multiline = false; + + if ( isEnabled() ) + { + delAccelerator(); + setHotkeyAccelerator(); + } +} + +//---------------------------------------------------------------------- +void FLabel::hide() +{ + short fg, bg; + int size; + char* blank; + FWidget* parent_widget = getParentWidget(); + + FWidget::hide(); + + if ( parent_widget ) + { + fg = parent_widget->getForegroundColor(); + bg = parent_widget->getBackgroundColor(); + } + else + { + fg = wc.dialog_fg; + bg = wc.dialog_bg; + } + + setColor (fg, bg); + size = getWidth(); + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset(blank, ' ', uLong(size)); + blank[getWidth()] = '\0'; + setPrintPos (1,1); + print (blank); + delete[] blank; +} + +//---------------------------------------------------------------------- +void FLabel::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( ! (isEnabled() && accel_widget) ) + { + // send click to the parent widget + if ( FWidget* parent = getParentWidget() ) + { + int b = ev->getButton(); + const FPoint& tp = ev->getTermPos(); + const FPoint& p = parent->termToWidgetPos(tp); + FMouseEvent* _ev = new FMouseEvent (fc::MouseDown_Event, p, tp, b); + FApplication::sendEvent (parent, _ev); + delete _ev; + } + + return; + } + + if ( ! accel_widget->hasFocus() ) + { + // focus the accelerator widget + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + accel_widget->setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + accel_widget->redraw(); + + if ( getStatusBar() ) + { + accel_widget->getStatusBar()->drawMessage(); + updateTerminal(); + flush_out(); + } + } +} + +//---------------------------------------------------------------------- +void FLabel::onAccel (FAccelEvent* ev) +{ + if ( ! (isEnabled() && accel_widget) ) + return; + + if ( ! accel_widget->hasFocus() ) + { + FWidget* focused_widget = static_cast(ev->focusedWidget()); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + accel_widget->setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + accel_widget->redraw(); + + if ( getStatusBar() ) + { + accel_widget->getStatusBar()->drawMessage(); + updateTerminal(); + flush_out(); + } + } + + ev->accept(); +} + +//---------------------------------------------------------------------- +void FLabel::cb_accel_widget_destroyed (FWidget*, void*) +{ + accel_widget = 0; + delAccelerator(); +} + + // private methods of FLabel //---------------------------------------------------------------------- void FLabel::init() @@ -330,205 +532,3 @@ void FLabel::draw() updateVTerm(true); } - - -// public methods of FLabel -//---------------------------------------------------------------------- -void FLabel::hide() -{ - short fg, bg; - int size; - char* blank; - FWidget* parent_widget = getParentWidget(); - - FWidget::hide(); - - if ( parent_widget ) - { - fg = parent_widget->getForegroundColor(); - bg = parent_widget->getBackgroundColor(); - } - else - { - fg = wc.dialog_fg; - bg = wc.dialog_bg; - } - - setColor (fg, bg); - size = getWidth(); - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset(blank, ' ', uLong(size)); - blank[getWidth()] = '\0'; - setPrintPos (1,1); - print (blank); - delete[] blank; -} - -//---------------------------------------------------------------------- -void FLabel::onMouseDown (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( ! (isEnabled() && accel_widget) ) - { - // send click to the parent widget - if ( FWidget* parent = getParentWidget() ) - { - int b = ev->getButton(); - const FPoint& tp = ev->getTermPos(); - const FPoint& p = parent->termToWidgetPos(tp); - FMouseEvent* _ev = new FMouseEvent (fc::MouseDown_Event, p, tp, b); - FApplication::sendEvent (parent, _ev); - delete _ev; - } - - return; - } - - if ( ! accel_widget->hasFocus() ) - { - // focus the accelerator widget - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - accel_widget->setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - accel_widget->redraw(); - - if ( statusBar() ) - { - accel_widget->statusBar()->drawMessage(); - updateTerminal(); - flush_out(); - } - } -} - -//---------------------------------------------------------------------- -void FLabel::onAccel (FAccelEvent* ev) -{ - if ( ! (isEnabled() && accel_widget) ) - return; - - if ( ! accel_widget->hasFocus() ) - { - FWidget* focused_widget = static_cast(ev->focusedWidget()); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - accel_widget->setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - accel_widget->redraw(); - - if ( statusBar() ) - { - accel_widget->statusBar()->drawMessage(); - updateTerminal(); - flush_out(); - } - } - - ev->accept(); -} - -//---------------------------------------------------------------------- -void FLabel::cb_accel_widget_destroyed (FWidget*, void*) -{ - accel_widget = 0; - delAccelerator(); -} - -//---------------------------------------------------------------------- -void FLabel::setAccelWidget (FWidget* widget) -{ - if ( widget ) - accel_widget = widget; - - accel_widget->addCallback - ( - "destroy", - _METHOD_CALLBACK (this, &FLabel::cb_accel_widget_destroyed) - ); -} - -//---------------------------------------------------------------------- -void FLabel::setAlignment (uInt align) -{ - if ( align != fc::alignLeft - && align != fc::alignCenter - && align != fc::alignRight ) - alignment = fc::alignLeft; - else - alignment = align; -} - -//---------------------------------------------------------------------- -bool FLabel::setEmphasis (bool on) -{ - if ( emphasis != on ) - emphasis = on; - - return on; -} - -//---------------------------------------------------------------------- -bool FLabel::setReverseMode (bool on) -{ - if ( reverse_mode != on ) - reverse_mode = on; - - return on; -} - -//---------------------------------------------------------------------- -bool FLabel::setEnable (bool on) -{ - FWidget::setEnable(on); - - if ( on ) - { - flags |= fc::active; - setHotkeyAccelerator(); - } - else - { - flags &= ~fc::active; - delAccelerator(); - } - - return on; -} - -//---------------------------------------------------------------------- -void FLabel::setNumber (long num) -{ - setText(FString().setNumber(num)); -} - -//---------------------------------------------------------------------- -void FLabel::setText (const FString& txt) -{ - text = txt; - multiline_text = text.split("\r\n"); - - if ( int(multiline_text.size()) > 1 ) - multiline = true; - else - multiline = false; - - if ( isEnabled() ) - { - delAccelerator(); - setHotkeyAccelerator(); - } -} diff --git a/src/flabel.h b/src/flabel.h index e50d7fd0..030f7e1c 100644 --- a/src/flabel.h +++ b/src/flabel.h @@ -40,65 +40,79 @@ class FLabel : public FWidget { - private: - std::vector multiline_text; - bool multiline; - FString text; - uInt alignment; - short emphasis_color; - short ellipsis_color; - bool emphasis; - bool reverse_mode; - FWidget* accel_widget; - - private: - // Disable copy constructor - FLabel (const FLabel&); - // Disable assignment operator (=) - FLabel& operator = (const FLabel&); - - void init(); - uChar getHotkey(); - int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); - void setHotkeyAccelerator(); - int getXOffset (int); - void printLine (wchar_t*&, uInt, int, int = 0); - void draw(); - public: + // Using-declaration + using FWidget::setEnable; + // Constructor explicit FLabel (FWidget* = 0); FLabel (const FString&, FWidget* = 0); + // Destructor virtual ~FLabel(); + // Accessors const char* getClassName() const; - void hide(); + FTerm* getAccelWidget(); + uInt getAlignment(); + FString& getText(); + + // Mutators + void setAccelWidget (FWidget* = 0); + void setAlignment(uInt); + bool setEmphasis(bool); + bool setEmphasis(); + bool unsetEmphasis(); + bool setReverseMode(bool); + bool setReverseMode(); + bool unsetReverseMode(); + bool setEnable (bool); + void setNumber(long); + void setText (const FString&); + + // Inquiries + bool hasEmphasis(); + bool hasReverseMode(); + + // Methods + void hide(); // Event handlers - void onMouseDown (FMouseEvent*); - void onAccel (FAccelEvent*); + void onMouseDown (FMouseEvent*); + void onAccel (FAccelEvent*); // Callback method - void cb_accel_widget_destroyed (FWidget*, void*); + void cb_accel_widget_destroyed (FWidget*, void*); - void setAccelWidget (FWidget* = 0); - FTerm* getAccelWidget(); - void setAlignment(uInt); - uInt getAlignment(); - bool setEmphasis(bool); - bool setEmphasis(); - bool unsetEmphasis(); - bool hasEmphasis(); - bool setReverseMode(bool); - bool setReverseMode(); - bool unsetReverseMode(); - bool hasReverseMode(); - using FWidget::setEnable; - bool setEnable (bool); - void setNumber(long); - void setText (const FString&); - FString& getText(); + private: + // Typedef + typedef std::vector multiLineText; + + // Disable copy constructor + FLabel (const FLabel&); + + // Disable assignment operator (=) + FLabel& operator = (const FLabel&); + + // Methods + void init(); + uChar getHotkey(); + int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); + void setHotkeyAccelerator(); + int getXOffset (int); + void printLine (wchar_t*&, uInt, int, int = 0); + void draw(); + + // Data Members + multiLineText multiline_text; + bool multiline; + FString text; + uInt alignment; + short emphasis_color; + short ellipsis_color; + bool emphasis; + bool reverse_mode; + FWidget* accel_widget; }; #pragma pack(pop) @@ -116,6 +130,10 @@ inline FTerm* FLabel::getAccelWidget () inline uInt FLabel::getAlignment() { return alignment; } +//---------------------------------------------------------------------- +inline FString& FLabel::getText() +{ return text; } + //---------------------------------------------------------------------- inline bool FLabel::setEmphasis() { return setEmphasis(true); } @@ -124,10 +142,6 @@ inline bool FLabel::setEmphasis() inline bool FLabel::unsetEmphasis() { return setEmphasis(false); } -//---------------------------------------------------------------------- -inline bool FLabel::hasEmphasis() -{ return emphasis; } - //---------------------------------------------------------------------- inline bool FLabel::setReverseMode() { return setReverseMode(true); } @@ -136,12 +150,12 @@ inline bool FLabel::setReverseMode() inline bool FLabel::unsetReverseMode() { return setReverseMode(false); } +//---------------------------------------------------------------------- +inline bool FLabel::hasEmphasis() +{ return emphasis; } + //---------------------------------------------------------------------- inline bool FLabel::hasReverseMode() { return reverse_mode; } -//---------------------------------------------------------------------- -inline FString& FLabel::getText() -{ return text; } - #endif // _FLABEL_H diff --git a/src/flineedit.cpp b/src/flineedit.cpp index af7696ad..03ff1d0b 100644 --- a/src/flineedit.cpp +++ b/src/flineedit.cpp @@ -17,13 +17,13 @@ FLineEdit::FLineEdit(FWidget* parent) , text("") , label_text("") , label(new FLabel("", parent)) + , label_orientation(FLineEdit::label_left) , drag_scroll(FLineEdit::noScroll) , scroll_timer(false) , scroll_repeat(100) , insert_mode(true) , cursor_pos(0) , text_offset(0) - , label_orientation(FLineEdit::label_left) { init(); } @@ -34,13 +34,13 @@ FLineEdit::FLineEdit (const FString& txt, FWidget* parent) , text(txt) , label_text("") , label(new FLabel("", parent)) + , label_orientation(FLineEdit::label_left) , drag_scroll(FLineEdit::noScroll) , scroll_timer(false) , scroll_repeat(100) , insert_mode(true) , cursor_pos(0) , text_offset(0) - , label_orientation(FLineEdit::label_left) { init(); setText(txt); @@ -60,18 +60,14 @@ FLineEdit::~FLineEdit() // destructor } } -// private methods of FLineEdit + +// public methods of FLineEdit //---------------------------------------------------------------------- -void FLineEdit::init() +bool FLineEdit::setEnable (bool on) { - label->setAccelWidget(this); - setVisibleCursor(); - setShadow(); + FWidget::setEnable(on); - if ( hasFocus() ) - flags |= fc::focus; - - if ( isEnabled() ) + if ( on ) { flags |= fc::active; @@ -86,196 +82,97 @@ void FLineEdit::init() setBackgroundColor (wc.inputfield_active_bg); } } - else // inactive + else { + flags &= ~fc::active; setForegroundColor (wc.inputfield_inactive_fg); setBackgroundColor (wc.inputfield_inactive_bg); } + + return on; } //---------------------------------------------------------------------- -bool FLineEdit::hasHotkey() +bool FLineEdit::setFocus (bool on) { - if ( label_text.isEmpty() ) - return 0; + FWidget::setFocus(on); - return label_text.includes('&'); -} - -//---------------------------------------------------------------------- -void FLineEdit::draw() -{ - bool isFocus; - drawInputField(); - isFocus = ((flags & fc::focus) != 0); - - if ( isFocus && statusBar() ) + if ( on ) { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); + flags |= fc::focus; - if ( curMsg != msg ) + if ( isEnabled() ) { - statusBar()->setMessage(msg); - statusBar()->drawMessage(); + setForegroundColor (wc.inputfield_active_focus_fg); + setBackgroundColor (wc.inputfield_active_focus_bg); + + if ( getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + getStatusBar()->setMessage(msg); + } } } + else + { + flags &= ~fc::focus; + + if ( isEnabled() ) + { + setForegroundColor (wc.inputfield_active_fg); + setBackgroundColor (wc.inputfield_active_bg); + + if ( getStatusBar() ) + getStatusBar()->clearMessage(); + } + } + + return on; } //---------------------------------------------------------------------- -void FLineEdit::drawInputField() +bool FLineEdit::setShadow (bool on) { - bool isActiveFocus, isActive, isShadow; - int x; - FString show_text; - int active_focus = fc::active + fc::focus; - isActiveFocus = ((flags & active_focus) == active_focus); - isActive = ((flags & fc::active) != 0); - isShadow = ((flags & fc::shadow) != 0 ); + if ( on + && (Encoding != fc::VT100 || isTeraTerm() ) + && Encoding != fc::ASCII ) + flags |= fc::shadow; + else + flags &= ~fc::shadow; - updateVTerm(false); - setPrintPos (1, 1); - - if ( isMonochron() ) - { - setReverse(true); - print (' '); - - if ( isActiveFocus ) - setReverse(false); - else - setUnderline(true); - } - else if ( isActiveFocus ) - { - setColor (wc.inputfield_active_focus_bg, wc.dialog_bg); - - if ( isCygwinTerminal() ) // IBM Codepage 850 - print (fc::FullBlock); // █ - else if ( isTeraTerm() ) - print (0xdb); - else - print (fc::RightHalfBlock); // ▐ - } - else if ( isActive ) - { - setColor (wc.inputfield_active_bg, wc.dialog_bg); - - if ( isCygwinTerminal() ) // IBM Codepage 850 - print (fc::FullBlock); // █ - else if ( isTeraTerm() ) - print (0xdb); - else - print (fc::RightHalfBlock); // ▐ - } - else // isInactive - { - setColor (wc.inputfield_inactive_bg, wc.dialog_bg); - - if ( isCygwinTerminal() ) // IBM Codepage 850 - print (fc::FullBlock); // █ - else if ( isTeraTerm() ) - print (0xdb); - else - print (fc::RightHalfBlock); // ▐ - } - - if ( isActiveFocus && getMaxColor() < 16 ) - setBold(); - - setColor(); - show_text = text.mid(uInt(1+text_offset), uInt(getWidth()-2)); - - if ( isUTF8_linux_terminal() ) - { - setUTF8(true); - - if ( show_text ) - print (show_text); - - setUTF8(false); - } - else if ( show_text ) - print (show_text); - - x = int(show_text.getLength()); - - while ( x < getWidth()-1 ) - { - print (' '); - x++; - } - - if ( isActiveFocus && getMaxColor() < 16 ) - unsetBold(); - - if ( isMonochron() ) - { - setReverse(false); - setUnderline(false); - } - - if ( isShadow ) - drawShadow (); - - // set the cursor to the first pos. - setCursorPos (2+cursor_pos-text_offset, 1); - - updateVTerm(true); + return on; } //---------------------------------------------------------------------- -void FLineEdit::processActivate() +void FLineEdit::setText (FString txt) { - if ( ! hasFocus() ) - { - setFocus(); - redraw(); - } + text_offset = 0; + cursor_pos = 0; - emitCallback("activate"); + if ( txt ) + text = txt; + else + text = ""; } //---------------------------------------------------------------------- -void FLineEdit::processChanged() +void FLineEdit::setLabelText (FString ltxt) { - emitCallback("changed"); -} - - -// protected methods of FListBox -//---------------------------------------------------------------------- -void FLineEdit::adjustLabel() -{ - int label_length = int(label_text.getLength()); - - if ( hasHotkey() ) - label_length--; - - assert ( label_orientation == label_above - || label_orientation == label_left ); - - switch ( label_orientation ) - { - case label_above: - label->setGeometry(getX(), getY()-1, label_length, 1); - break; - - case label_left: - label->setGeometry(getX()-label_length, getY(), label_length, 1); - break; - } -} - -//---------------------------------------------------------------------- -void FLineEdit::adjustSize() -{ - FWidget::adjustSize(); + label_text = ltxt; + label->setText(label_text); adjustLabel(); } +//---------------------------------------------------------------------- +void FLineEdit::setLabelOrientation(label_o o) +{ + label_orientation = o; + adjustLabel(); +} -// public methods of FLineEdit //---------------------------------------------------------------------- void FLineEdit::hide() { @@ -321,87 +218,11 @@ void FLineEdit::hide() } //---------------------------------------------------------------------- -bool FLineEdit::setEnable (bool on) +void FLineEdit::clearText() { - FWidget::setEnable(on); - - if ( on ) - { - flags |= fc::active; - - if ( hasFocus() ) - { - setForegroundColor (wc.inputfield_active_focus_fg); - setBackgroundColor (wc.inputfield_active_focus_bg); - } - else - { - setForegroundColor (wc.inputfield_active_fg); - setBackgroundColor (wc.inputfield_active_bg); - } - } - else - { - flags &= ~fc::active; - setForegroundColor (wc.inputfield_inactive_fg); - setBackgroundColor (wc.inputfield_inactive_bg); - } - - return on; -} - -//---------------------------------------------------------------------- -bool FLineEdit::setFocus (bool on) -{ - FWidget::setFocus(on); - - if ( on ) - { - flags |= fc::focus; - - if ( isEnabled() ) - { - setForegroundColor (wc.inputfield_active_focus_fg); - setBackgroundColor (wc.inputfield_active_focus_bg); - - if ( statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) - statusBar()->setMessage(msg); - } - } - } - else - { - flags &= ~fc::focus; - - if ( isEnabled() ) - { - setForegroundColor (wc.inputfield_active_fg); - setBackgroundColor (wc.inputfield_active_bg); - - if ( statusBar() ) - statusBar()->clearMessage(); - } - } - - return on; -} - -//---------------------------------------------------------------------- -bool FLineEdit::setShadow (bool on) -{ - if ( on - && (Encoding != fc::VT100 || isTeraTerm() ) - && Encoding != fc::ASCII ) - flags |= fc::shadow; - else - flags &= ~fc::shadow; - - return on; + text_offset = 0; + cursor_pos = 0; + text.clear(); } //---------------------------------------------------------------------- @@ -581,8 +402,8 @@ void FLineEdit::onMouseDown (FMouseEvent* ev) redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); } mouse_x = ev->getX(); @@ -751,9 +572,9 @@ void FLineEdit::onAccel (FAccelEvent* ev) redraw(); - if ( statusBar() ) + if ( getStatusBar() ) { - statusBar()->drawMessage(); + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); } @@ -795,9 +616,9 @@ void FLineEdit::onFocusIn (FFocusEvent*) setXTermCursorColor("rgb:0000/0000/0000"); } - if ( statusBar() ) + if ( getStatusBar() ) { - statusBar()->drawMessage(); + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); } @@ -806,10 +627,10 @@ void FLineEdit::onFocusIn (FFocusEvent*) //---------------------------------------------------------------------- void FLineEdit::onFocusOut (FFocusEvent*) { - if ( statusBar() ) + if ( getStatusBar() ) { - statusBar()->clearMessage(); - statusBar()->drawMessage(); + getStatusBar()->clearMessage(); + getStatusBar()->drawMessage(); } if ( ! insert_mode ) @@ -823,37 +644,217 @@ void FLineEdit::onFocusOut (FFocusEvent*) } } + +// protected methods of FListBox //---------------------------------------------------------------------- -void FLineEdit::clearText() +void FLineEdit::adjustLabel() { - text_offset = 0; - cursor_pos = 0; - text.clear(); + int label_length = int(label_text.getLength()); + + if ( hasHotkey() ) + label_length--; + + assert ( label_orientation == label_above + || label_orientation == label_left ); + + switch ( label_orientation ) + { + case label_above: + label->setGeometry(getX(), getY()-1, label_length, 1); + break; + + case label_left: + label->setGeometry(getX()-label_length, getY(), label_length, 1); + break; + } } //---------------------------------------------------------------------- -void FLineEdit::setText (FString txt) +void FLineEdit::adjustSize() { - text_offset = 0; - cursor_pos = 0; - - if ( txt ) - text = txt; - else - text = ""; -} - -//---------------------------------------------------------------------- -void FLineEdit::setLabelText (FString ltxt) -{ - label_text = ltxt; - label->setText(label_text); + FWidget::adjustSize(); adjustLabel(); } + +// private methods of FLineEdit //---------------------------------------------------------------------- -void FLineEdit::setLabelOrientation(label_o o) +void FLineEdit::init() { - label_orientation = o; - adjustLabel(); + label->setAccelWidget(this); + setVisibleCursor(); + setShadow(); + + if ( hasFocus() ) + flags |= fc::focus; + + if ( isEnabled() ) + { + flags |= fc::active; + + if ( hasFocus() ) + { + setForegroundColor (wc.inputfield_active_focus_fg); + setBackgroundColor (wc.inputfield_active_focus_bg); + } + else + { + setForegroundColor (wc.inputfield_active_fg); + setBackgroundColor (wc.inputfield_active_bg); + } + } + else // inactive + { + setForegroundColor (wc.inputfield_inactive_fg); + setBackgroundColor (wc.inputfield_inactive_bg); + } +} + +//---------------------------------------------------------------------- +bool FLineEdit::hasHotkey() +{ + if ( label_text.isEmpty() ) + return 0; + + return label_text.includes('&'); +} + +//---------------------------------------------------------------------- +void FLineEdit::draw() +{ + bool isFocus; + drawInputField(); + isFocus = ((flags & fc::focus) != 0); + + if ( isFocus && getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + { + getStatusBar()->setMessage(msg); + getStatusBar()->drawMessage(); + } + } +} + +//---------------------------------------------------------------------- +void FLineEdit::drawInputField() +{ + bool isActiveFocus, isActive, isShadow; + int x; + FString show_text; + int active_focus = fc::active + fc::focus; + isActiveFocus = ((flags & active_focus) == active_focus); + isActive = ((flags & fc::active) != 0); + isShadow = ((flags & fc::shadow) != 0 ); + + updateVTerm(false); + setPrintPos (1, 1); + + if ( isMonochron() ) + { + setReverse(true); + print (' '); + + if ( isActiveFocus ) + setReverse(false); + else + setUnderline(true); + } + else if ( isActiveFocus ) + { + setColor (wc.inputfield_active_focus_bg, wc.dialog_bg); + + if ( isCygwinTerminal() ) // IBM Codepage 850 + print (fc::FullBlock); // █ + else if ( isTeraTerm() ) + print (0xdb); + else + print (fc::RightHalfBlock); // ▐ + } + else if ( isActive ) + { + setColor (wc.inputfield_active_bg, wc.dialog_bg); + + if ( isCygwinTerminal() ) // IBM Codepage 850 + print (fc::FullBlock); // █ + else if ( isTeraTerm() ) + print (0xdb); + else + print (fc::RightHalfBlock); // ▐ + } + else // isInactive + { + setColor (wc.inputfield_inactive_bg, wc.dialog_bg); + + if ( isCygwinTerminal() ) // IBM Codepage 850 + print (fc::FullBlock); // █ + else if ( isTeraTerm() ) + print (0xdb); + else + print (fc::RightHalfBlock); // ▐ + } + + if ( isActiveFocus && getMaxColor() < 16 ) + setBold(); + + setColor(); + show_text = text.mid(uInt(1+text_offset), uInt(getWidth()-2)); + + if ( isUTF8_linux_terminal() ) + { + setUTF8(true); + + if ( show_text ) + print (show_text); + + setUTF8(false); + } + else if ( show_text ) + print (show_text); + + x = int(show_text.getLength()); + + while ( x < getWidth()-1 ) + { + print (' '); + x++; + } + + if ( isActiveFocus && getMaxColor() < 16 ) + unsetBold(); + + if ( isMonochron() ) + { + setReverse(false); + setUnderline(false); + } + + if ( isShadow ) + drawShadow (); + + // set the cursor to the first pos. + setCursorPos (2+cursor_pos-text_offset, 1); + + updateVTerm(true); +} + +//---------------------------------------------------------------------- +void FLineEdit::processActivate() +{ + if ( ! hasFocus() ) + { + setFocus(); + redraw(); + } + + emitCallback("activate"); +} + +//---------------------------------------------------------------------- +void FLineEdit::processChanged() +{ + emitCallback("changed"); } diff --git a/src/flineedit.h b/src/flineedit.h index 50882bae..c38032d6 100644 --- a/src/flineedit.h +++ b/src/flineedit.h @@ -41,11 +41,65 @@ class FLineEdit : public FWidget { - private: - FString text; - FString label_text; - FLabel* label; + public: + // Enumeration + enum label_o + { + label_above = 0, + label_left = 1 + }; + // Constructor + explicit FLineEdit (FWidget* = 0); + FLineEdit (const FString&, FWidget* = 0); + + // Destructor + virtual ~FLineEdit(); + + // Accessors + const char* getClassName() const; + FString getText() const; + int getLabelOrientation(); + + // Mutators + void setText (FString); + void setLabelText (FString); + void setLabelOrientation(label_o); + bool setEnable(bool); + bool setEnable(); + bool unsetEnable(); + bool setDisable(); + bool setFocus(bool); + bool setFocus(); + bool unsetFocus(); + bool setShadow(bool); + bool setShadow(); + bool unsetShadow(); + + // Inquiry + bool hasShadow(); + + // Methods + void hide(); + void clearText(); + + // Event handlers + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onTimer (FTimerEvent*); + void onAccel (FAccelEvent*); + void onHide (FHideEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); + + protected: + void adjustLabel(); + void adjustSize(); + + private: + // Enumeration enum dragScroll { noScroll = 0, @@ -53,77 +107,31 @@ class FLineEdit : public FWidget scrollRight = 2 }; - dragScroll drag_scroll; - bool scroll_timer; - int scroll_repeat; - bool insert_mode; - int cursor_pos; - int text_offset; - - public: - enum label_o - { - label_above = 0, - label_left = 1 - }; - label_o label_orientation; - - private: // Disable copy constructor FLineEdit (const FLineEdit&); + // Disable assignment operator (=) FLineEdit& operator = (const FLineEdit&); - void init(); - bool hasHotkey(); - void draw(); - void drawInputField(); - void processActivate(); - void processChanged(); + // Methods + void init(); + bool hasHotkey(); + void draw(); + void drawInputField(); + void processActivate(); + void processChanged(); - protected: - void adjustLabel(); - void adjustSize(); - - public: - // Constructor - explicit FLineEdit (FWidget* = 0); - FLineEdit (const FString&, FWidget* = 0); - // Destructor - virtual ~FLineEdit(); - - const char* getClassName() const; - void hide(); - - bool setEnable(bool); - bool setEnable(); - bool unsetEnable(); - bool setDisable(); - bool setFocus(bool); - bool setFocus(); - bool unsetFocus(); - bool setShadow(bool); - bool setShadow(); - bool unsetShadow(); - bool hasShadow(); - - // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onTimer (FTimerEvent*); - void onAccel (FAccelEvent*); - void onHide (FHideEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); - - void clearText(); - void setText (FString); - FString getText() const; - void setLabelText (FString); - void setLabelOrientation(label_o); - int getLabelOrientation(); + // Data Members + FString text; + FString label_text; + FLabel* label; + label_o label_orientation; + dragScroll drag_scroll; + bool scroll_timer; + int scroll_repeat; + bool insert_mode; + int cursor_pos; + int text_offset; }; #pragma pack(pop) @@ -133,6 +141,14 @@ class FLineEdit : public FWidget inline const char* FLineEdit::getClassName() const { return "FLineEdit"; } +//---------------------------------------------------------------------- +inline FString FLineEdit::getText() const +{ return text; } + +//---------------------------------------------------------------------- +inline int FLineEdit::getLabelOrientation() +{ return int(label_orientation); } + //---------------------------------------------------------------------- inline bool FLineEdit::setEnable() { return setEnable(true); } @@ -165,12 +181,4 @@ inline bool FLineEdit::unsetShadow() inline bool FLineEdit::hasShadow() { return ((flags & fc::shadow) != 0); } -//---------------------------------------------------------------------- -inline FString FLineEdit::getText() const -{ return text; } - -//---------------------------------------------------------------------- -inline int FLineEdit::getLabelOrientation() -{ return int(label_orientation); } - #endif // _FLINEEDIT_H diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 75bccfff..dfe9efe6 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -86,6 +86,1325 @@ FListBox::~FListBox() // destructor } +// public methods of FListBox +//---------------------------------------------------------------------- +void FListBox::setCurrentItem(int index) +{ + int element_count; + + if ( index == current ) + return; + + element_count = int(getCount()); + + if ( index > element_count ) + current = element_count; + else if ( index < 1 ) + current = 1; + else + current = index; + + xoffset = 0; + yoffset = 0; + adjustSize(); + vbar->setValue(yoffset); + + if ( isVisible() ) + redraw(); +} + +//---------------------------------------------------------------------- +void FListBox::showInsideBrackets ( int index + , fc::brackets_type b ) +{ + data[uInt(index-1)].brackets = b; + + if ( b == fc::NoBrackets ) + return; + + int len = int(data[uInt(index-1)].getText().getLength() + 2); + + if ( len > max_line_width ) + { + max_line_width = len; + + if ( len >= getWidth() - nf_offset - 3 ) + { + hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); + hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); + hbar->setValue (xoffset); + + if ( ! hbar->isVisible() ) + hbar->setVisible(); + } + } +} + +//---------------------------------------------------------------------- +void FListBox::setGeometry (int x, int y, int w, int h, bool adjust) +{ + FWidget::setGeometry(x, y, w, h, adjust); + + if ( isNewFont() ) + { + vbar->setGeometry (getWidth(), 2, 2, getHeight()-2); + hbar->setGeometry (1, getHeight(), getWidth()-2, 1); + } + else + { + vbar->setGeometry (getWidth(), 2, 1, getHeight()-2); + hbar->setGeometry (2, getHeight(), getWidth()-2, 1); + } +} + +//---------------------------------------------------------------------- +bool FListBox::setEnable (bool on) +{ + FWidget::setEnable(on); + + if ( on ) + flags |= fc::active; + else + flags &= ~fc::active; + + return on; +} + +//---------------------------------------------------------------------- +bool FListBox::setFocus (bool on) +{ + FWidget::setFocus(on); + + if ( on ) + { + flags |= fc::focus; + + if ( getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + getStatusBar()->setMessage(msg); + } + } + else + { + flags &= ~fc::focus; + + if ( getStatusBar() ) + getStatusBar()->clearMessage(); + } + + return on; +} + +//---------------------------------------------------------------------- +void FListBox::setText (FString txt) +{ + text = txt; +} + +//---------------------------------------------------------------------- +void FListBox::hide() +{ + int n, size; + short fg, bg; + char* blank; + FWidget* parent_widget = getParentWidget(); + + FWidget::hide(); + + if ( parent_widget ) + { + fg = parent_widget->getForegroundColor(); + bg = parent_widget->getBackgroundColor(); + } + else + { + fg = wc.dialog_fg; + bg = wc.dialog_bg; + } + + setColor (fg, bg); + n = isNewFont() ? 1 : 0; + size = getWidth() + n; + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset (blank, ' ', uLong(size)); + blank[size] = '\0'; + + for (int y=0; y < getHeight(); y++) + { + setPrintPos (1, 1 + y); + print (blank); + } + + delete[] blank; +} + +//---------------------------------------------------------------------- +void FListBox::insert ( FString item + , fc::brackets_type b + , bool s ) +{ + int len, element_count; + + len = int(item.getLength()); + + if ( b ) + len += 2; + + if ( len > max_line_width ) + { + max_line_width = len; + + if ( len >= getWidth() - nf_offset - 3 ) + { + hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); + hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); + hbar->calculateSliderValues(); + + if ( ! hbar->isVisible() ) + hbar->setVisible(); + } + } + FListBoxItem listItem (item); + listItem.brackets = b; + listItem.selected = s; + data.push_back (listItem); + + element_count = int(getCount()); + vbar->setMaximum(element_count - getHeight() + 2); + vbar->setPageSize(element_count, getHeight() - 2); + vbar->calculateSliderValues(); + + if ( ! vbar->isVisible() && element_count >= getHeight() - 1 ) + vbar->setVisible(); +} + +//---------------------------------------------------------------------- +void FListBox::insert ( long item + , fc::brackets_type b + , bool s ) +{ + insert (FString().setNumber(item), b, s); +} + +//---------------------------------------------------------------------- +void FListBox::remove (int item) +{ + int element_count; + + if ( int(getCount()) < item ) + return; + + data.erase (data.begin() + item - 1); + element_count = int(getCount()); + max_line_width = 0; + + for (int i=0; i < element_count; i++) + { + int len = int(data[uInt(i)].getText().getLength()); + + if ( len > max_line_width ) + max_line_width = len; + } + + hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); + hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); + + if ( hbar->isVisible() && max_line_width < getWidth() - nf_offset - 3 ) + hbar->hide(); + + vbar->setMaximum(element_count - getHeight() + 2); + vbar->setPageSize(element_count, getHeight() - 2); + + if ( vbar->isVisible() && element_count < getHeight() - 1 ) + vbar->hide(); + + if ( current >= item && current > 1 ) + current--; + + if ( current > element_count ) + current = element_count; + + if ( yoffset > element_count - getHeight() + 2 ) + yoffset = element_count - getHeight() + 2; + + if ( yoffset < 0 ) + yoffset = 0; +} + +//---------------------------------------------------------------------- +void FListBox::clear() +{ + int size; + char* blank; + + data.clear(); + + current = 0; + xoffset = 0; + yoffset = 0; + max_line_width = 0; + last_current = -1; + last_yoffset = -1; + + vbar->setMinimum(0); + vbar->setValue(0); + vbar->hide(); + + hbar->setMinimum(0); + hbar->setValue(0); + hbar->hide(); + + // clear list from screen + setColor (wc.list_fg, wc.list_bg); + size = getWidth() - 2; + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset (blank, ' ', uLong(size)); + blank[size] = '\0'; + + for (int y=0; y < getHeight()-2; y++) + { + setPrintPos (2, 2 + y); + print (blank); + } + + delete[] blank; +} + +//---------------------------------------------------------------------- +void FListBox::onKeyPress (FKeyEvent* ev) +{ + int element_count = int(getCount()); + int current_before = current; + int xoffset_before = xoffset; + int yoffset_before = yoffset; + int key = ev->key(); + + switch ( key ) + { + case fc::Fkey_return: + case fc::Fkey_enter: + processClick(); + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_up: + current--; + + if ( current < 1 ) + current=1; + + if ( current <= yoffset ) + yoffset--; + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_down: + current++; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset >= getHeight() - 1 ) + yoffset++; + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_left: + xoffset--; + + if ( xoffset < 0 ) + xoffset = 0; + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_right: + xoffset++; + + if ( xoffset > max_line_width - getWidth() + nf_offset + 4 ) + xoffset = max_line_width - getWidth() + nf_offset + 4; + + if ( xoffset < 0 ) + xoffset = 0; + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_ppage: + current -= getHeight()-3; + + if ( current < 1 ) + current=1; + + if ( current <= yoffset ) + { + yoffset -= getHeight()-3; + + if ( yoffset < 0 ) + yoffset=0; + } + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_npage: + current += getHeight()-3; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset >= getHeight() - 1 ) + { + yoffset += getHeight()-3; + + if ( yoffset > element_count - getHeight() + 2 ) + yoffset = element_count - getHeight() + 2; + } + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_home: + current = 1; + yoffset = 0; + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_end: + current = element_count; + + if ( current >= getHeight() - 1 ) + yoffset = element_count - getHeight() + 2; + + inc_search.clear(); + ev->accept(); + break; + + case fc::Fkey_ic: // insert key + if ( isMultiSelection() ) + { + if ( isSelected(current) ) + unselectItem(current); + else + selectItem(current); + + processSelect(); + current++; + + if ( current > element_count ) + current = element_count; + + if ( current-yoffset >= getHeight() - 1 ) + yoffset++; + + ev->accept(); + } + + inc_search.clear(); + break; + + case fc::Fkey_space: + { + uInt inc_len = inc_search.getLength(); + + if ( inc_len > 0 ) + { + inc_search += L' '; + bool inc_found = false; + uInt end = getCount(); + + for (uInt i=0; i < end; i++) + { + if ( ! inc_found + && inc_search.toLower() + == data[i].getText().left(inc_len+1).toLower() ) + { + setCurrentItem(int(i+1)); + inc_found = true; + break; + } + } + + if ( ! inc_found ) + { + inc_search.remove(inc_len, 1); + ev->ignore(); + } + else + ev->accept(); + } + else if ( isMultiSelection() ) + { + if ( isSelected(current) ) + unselectItem(current); + else + selectItem(current); + + processSelect(); + inc_search.clear(); + ev->accept(); + } + } + break; + + case fc::Fkey_erase: + case fc::Fkey_backspace: + { + uInt inc_len = inc_search.getLength(); + + if ( inc_len > 0 ) + { + inc_search.remove(inc_len-1, 1); + + if ( inc_len > 1 ) + { + uInt end = getCount(); + + for (uInt i=0; i < end; i++) + { + if ( inc_search.toLower() + == data[i].getText().left(inc_len-1).toLower() ) + { + setCurrentItem(int(i+1)); + break; + } + } + } + + ev->accept(); + } + else + ev->ignore(); + } + break; + + case fc::Fkey_escape: + case fc::Fkey_escape_mintty: + if ( inc_search.getLength() > 0 ) + { + inc_search.clear(); + ev->accept(); + } + break; + + default: + if ( key > 0x20 && key <= 0x10fff ) + { + // incremental search + if ( inc_search.getLength() == 0 ) + inc_search = wchar_t(key); + else + inc_search += wchar_t(key); + + uInt inc_len = inc_search.getLength(); + bool inc_found = false; + uInt end = getCount(); + + for (uInt i=0; i < end; i++) + { + if ( ! inc_found + && inc_search.toLower() + == data[i].getText().left(inc_len).toLower() ) + { + setCurrentItem(int(i+1)); + inc_found = true; + break; + } + } + + if ( ! inc_found ) + { + inc_search.remove(inc_len-1, 1); + + if ( inc_len == 1 ) + ev->ignore(); + else + ev->accept(); + } + else + ev->accept(); + } + else + ev->ignore(); + } + + if ( current_before != current ) + { + processChanged(); + + if ( ! isMultiSelection() ) + processSelect(); + } + + if ( ev->isAccepted() ) + { + if ( isVisible() ) + drawList(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() && yoffset_before != yoffset ) + vbar->drawBar(); + + hbar->setValue (xoffset); + + if ( hbar->isVisible() && xoffset_before != xoffset ) + hbar->drawBar(); + + updateTerminal(); + flush_out(); + } +} + +//---------------------------------------------------------------------- +void FListBox::onMouseDown (FMouseEvent* ev) +{ + int yoffset_before, mouse_x, mouse_y; + + if ( ev->getButton() != fc::LeftButton + && ev->getButton() != fc::RightButton ) + { + return; + } + + if ( ev->getButton() == fc::RightButton && ! isMultiSelection() ) + return; + + if ( ! hasFocus() ) + { + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + } + + yoffset_before = yoffset; + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( mouse_x > 1 && mouse_x < getWidth() + && mouse_y > 1 && mouse_y < getHeight() ) + { + current = yoffset + mouse_y - 1; + + if ( current > int(getCount()) ) + current = int(getCount()); + inc_search.clear(); + + if ( ev->getButton() == fc::RightButton ) + { + if ( isMultiSelection() ) + { + if ( isSelected(current) ) + { + mouse_select = false; + unselectItem(current); + } + else + { + mouse_select = true; + selectItem(current); + } + + processSelect(); + secect_from_item = current; + } + } + + if ( isVisible() ) + drawList(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() && yoffset_before != yoffset ) + vbar->drawBar(); + + updateTerminal(); + flush_out(); + } +} + +//---------------------------------------------------------------------- +void FListBox::onMouseUp (FMouseEvent* ev) +{ + if ( drag_scroll != FListBox::noScroll ) + { + delOwnTimer(); + drag_scroll = FListBox::noScroll; + scroll_distance = 1; + scroll_timer = false; + } + + if ( ev->getButton() == fc::LeftButton ) + { + int mouse_x = ev->getX(); + int mouse_y = ev->getY(); + + if ( mouse_x > 1 && mouse_x < getWidth() + && mouse_y > 1 && mouse_y < getHeight() ) + { + processChanged(); + + if ( ! isMultiSelection() ) + processSelect(); + } + } +} + +//---------------------------------------------------------------------- +void FListBox::onMouseMove (FMouseEvent* ev) +{ + int current_before, yoffset_before, mouse_x, mouse_y; + + if ( ev->getButton() != fc::LeftButton + && ev->getButton() != fc::RightButton ) + { + return; + } + + if ( ev->getButton() == fc::RightButton && ! isMultiSelection() ) + return; + + current_before = current; + yoffset_before = yoffset; + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( mouse_x > 1 && mouse_x < getWidth() + && mouse_y > 1 && mouse_y < getHeight() ) + { + current = yoffset + mouse_y - 1; + + if ( current > int(getCount()) ) + current = int(getCount()); + + inc_search.clear(); + + // handle multiple selections + if ( ev->getButton() == fc::RightButton + && isMultiSelection() + && current_before != current ) + { + int from, to; + + if ( secect_from_item > current ) + { + from = current; + to = secect_from_item - 1; + } + else + { + from = secect_from_item + 1; + to = current; + } + for (int i=from; i <= to; i++) + { + if ( mouse_select ) + { + selectItem(i); + processSelect(); + } + else + { + unselectItem(i); + processSelect(); + } + } + + secect_from_item = current; + } + + if ( isVisible() ) + drawList(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() && yoffset_before != yoffset ) + vbar->drawBar(); + + updateTerminal(); + flush_out(); + } + + // auto-scrolling when dragging mouse outside the widget + if ( mouse_y < 2 ) + { + // drag up + if ( drag_scroll != FListBox::noScroll + && scroll_distance < getHeight()-2 ) + scroll_distance++; + + if ( ! scroll_timer && current > 1 ) + { + scroll_timer = true; + addTimer(scroll_repeat); + + if ( ev->getButton() == fc::RightButton ) + drag_scroll = FListBox::scrollUpSelect; + else + drag_scroll = FListBox::scrollUp; + } + + if ( current == 1 ) + { + delOwnTimer(); + drag_scroll = FListBox::noScroll; + } + } + else if ( mouse_y >= getHeight() ) + { + // drag down + if ( drag_scroll != FListBox::noScroll + && scroll_distance < getHeight()-2 ) + scroll_distance++; + + if ( ! scroll_timer && current < int(getCount()) ) + { + scroll_timer = true; + addTimer(scroll_repeat); + + if ( ev->getButton() == fc::RightButton ) + drag_scroll = FListBox::scrollDownSelect; + else + drag_scroll = FListBox::scrollDown; + } + + if ( current == int(getCount()) ) + { + delOwnTimer(); + drag_scroll = FListBox::noScroll; + } + } + else + { + // no dragging + delOwnTimer(); + scroll_timer = false; + scroll_distance = 1; + drag_scroll = FListBox::noScroll; + } +} + +//---------------------------------------------------------------------- +void FListBox::onMouseDoubleClick (FMouseEvent* ev) +{ + int mouse_x, mouse_y; + + if ( ev->getButton() != fc::LeftButton ) + return; + + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( mouse_x > 1 && mouse_x < getWidth() + && mouse_y > 1 && mouse_y < getHeight() ) + { + if ( yoffset + mouse_y - 1 > int(getCount()) ) + return; + + processClick(); + } +} + +//---------------------------------------------------------------------- +void FListBox::onTimer (FTimerEvent*) +{ + int element_count = int(getCount()); + int current_before = current; + int yoffset_before = yoffset; + + switch ( int(drag_scroll) ) + { + case FListBox::noScroll: + return; + + case FListBox::scrollUp: + case FListBox::scrollUpSelect: + if ( current_before == 1) + { + drag_scroll = FListBox::noScroll; + return; + } + + current -= scroll_distance; + + if ( current < 1 ) + current=1; + + if ( current <= yoffset ) + yoffset -= scroll_distance; + + if ( yoffset < 0 ) + yoffset=0; + break; + + case FListBox::scrollDown: + case FListBox::scrollDownSelect: + if ( current_before == element_count ) + { + drag_scroll = FListBox::noScroll; + return; + } + + current += scroll_distance; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset >= getHeight() - 1 ) + yoffset += scroll_distance; + + if ( yoffset > element_count - getHeight() + 2 ) + yoffset = element_count - getHeight() + 2; + + break; + + default: + break; + } + + // handle multiple selections + if ( drag_scroll == FListBox::scrollUpSelect + || drag_scroll == FListBox::scrollDownSelect ) + { + if ( isMultiSelection() && current_before != current ) + { + int from, to; + + if ( secect_from_item > current ) + { + from = current; + to = secect_from_item - 1; + } + else + { + from = secect_from_item + 1; + to = current; + } + + for (int i=from; i <= to; i++) + { + if ( mouse_select ) + { + selectItem(i); + processSelect(); + } + else + { + unselectItem(i); + processSelect(); + } + } + + secect_from_item = current; + } + } + + if ( isVisible() ) + drawList(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() && yoffset_before != yoffset ) + vbar->drawBar(); + + updateTerminal(); + flush_out(); +} + +//---------------------------------------------------------------------- +void FListBox::onWheel (FWheelEvent* ev) +{ + int element_count, current_before, yoffset_before, yoffset_end, wheel; + element_count = int(getCount()); + current_before = current; + yoffset_before = yoffset; + yoffset_end = element_count - getHeight() + 2; + + if ( yoffset_end < 0 ) + yoffset_end = 0; + + wheel = ev->getWheel(); + + if ( drag_scroll != FListBox::noScroll ) + { + delOwnTimer(); + scroll_timer = false; + scroll_distance = 1; + drag_scroll = FListBox::noScroll; + } + + switch ( wheel ) + { + case fc::WheelUp: + if ( yoffset == 0 ) + break; + + yoffset -= 4; + + if ( yoffset < 0 ) + { + current -= 4+yoffset; + yoffset=0; + } + else + current -= 4; + + if ( current < 1 ) + current=1; + + inc_search.clear(); + break; + + case fc::WheelDown: + if ( yoffset == yoffset_end ) + break; + + yoffset += 4; + + if ( yoffset > yoffset_end ) + { + current += 4 - (yoffset - yoffset_end); + yoffset = yoffset_end; + } + else + current += 4; + + if ( current > element_count ) + current = element_count; + + inc_search.clear(); + break; + + default: + break; + } + + if ( current_before != current ) + { + processChanged(); + + if ( ! isMultiSelection() ) + processSelect(); + } + + if ( isVisible() ) + drawList(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() && yoffset_before != yoffset ) + vbar->drawBar(); + + updateTerminal(); + flush_out(); +} + +//---------------------------------------------------------------------- +void FListBox::onFocusIn (FFocusEvent*) +{ + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +void FListBox::onFocusOut (FFocusEvent*) +{ + if ( getStatusBar() ) + { + getStatusBar()->clearMessage(); + getStatusBar()->drawMessage(); + } + + delOwnTimer(); + inc_search.clear(); +} + +//---------------------------------------------------------------------- +void FListBox::cb_VBarChange (FWidget*, void*) +{ + int distance = 1; + int element_count = int(getCount()); + int yoffset_before = yoffset; + int scrollType = vbar->getScrollType(); + + switch ( scrollType ) + { + case FScrollbar::scrollPageBackward: + distance = getHeight()-2; + // fall through + case FScrollbar::scrollStepBackward: + current -= distance; + + if ( current < 1 ) + current=1; + + if ( current <= yoffset ) + yoffset -= distance; + + if ( yoffset < 0 ) + yoffset = 0; + + break; + + case FScrollbar::scrollPageForward: + distance = getHeight()-2; + // fall through + case FScrollbar::scrollStepForward: + current += distance; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset >= getHeight() - 1 ) + yoffset += distance; + + if ( yoffset > element_count - getHeight() + 2 ) + yoffset = element_count - getHeight() + 2; + + break; + + case FScrollbar::scrollJump: + { + int val = vbar->getValue(); + + if ( yoffset == val ) + break; + + int c = current - yoffset; + yoffset = val; + + if ( yoffset > element_count - getHeight() + 2 ) + yoffset = element_count - getHeight() + 2; + + if ( yoffset < 0 ) + yoffset = 0; + + current = yoffset + c; + + if ( current < yoffset ) + current = yoffset; + + if ( current > element_count ) + current = element_count; + + break; + } + + case FScrollbar::scrollWheelUp: + { + FWheelEvent wheel_ev (fc::MouseWheel_Event, FPoint(2,2), fc::WheelUp); + onWheel(&wheel_ev); + } + break; + + case FScrollbar::scrollWheelDown: + { + FWheelEvent wheel_ev (fc::MouseWheel_Event, FPoint(2,2), fc::WheelDown); + onWheel(&wheel_ev); + } + break; + + default: + break; + } + + if ( isVisible() ) + drawList(); + + if ( scrollType >= FScrollbar::scrollStepBackward + && scrollType <= FScrollbar::scrollPageForward ) + { + vbar->setValue (yoffset); + + if ( vbar->isVisible() && yoffset_before != yoffset ) + vbar->drawBar(); + + updateTerminal(); + flush_out(); + } +} + +//---------------------------------------------------------------------- +void FListBox::cb_HBarChange (FWidget*, void*) +{ + int distance = 1; + int xoffset_before = xoffset; + int xoffset_end = max_line_width - getWidth() + nf_offset + 4; + int scrollType = hbar->getScrollType(); + + switch ( scrollType ) + { + case FScrollbar::scrollPageBackward: + distance = getWidth() - nf_offset - 4; + // fall through + case FScrollbar::scrollStepBackward: + xoffset -= distance; + + if ( xoffset < 0 ) + xoffset = 0; + break; + + case FScrollbar::scrollPageForward: + distance = getWidth() - nf_offset - 4; + // fall through + case FScrollbar::scrollStepForward: + xoffset += distance; + + if ( xoffset > max_line_width - getWidth() + nf_offset + 4 ) + xoffset = max_line_width - getWidth() + nf_offset + 4; + + if ( xoffset < 0 ) + xoffset = 0; + + break; + + case FScrollbar::scrollJump: + { + int val = hbar->getValue(); + + if ( xoffset == val ) + break; + + xoffset = val; + + if ( xoffset > max_line_width - getWidth() + nf_offset + 4 ) + xoffset = max_line_width - getWidth() + nf_offset + 4; + + if ( xoffset < 0 ) + xoffset = 0; + + break; + } + + case FScrollbar::scrollWheelUp: + if ( xoffset == 0 ) + break; + + xoffset -= 4; + + if ( xoffset < 0 ) + xoffset=0; + + break; + + case FScrollbar::scrollWheelDown: + if ( xoffset == xoffset_end ) + break; + + xoffset += 4; + + if ( xoffset > xoffset_end ) + xoffset = xoffset_end; + + break; + + default: + break; + } + + if ( isVisible() ) + { + drawList(); + updateTerminal(); + flush_out(); + } + + if ( scrollType >= FScrollbar::scrollStepBackward + && scrollType <= FScrollbar::scrollWheelDown ) + { + hbar->setValue (xoffset); + + if ( hbar->isVisible() && xoffset_before != xoffset ) + hbar->drawBar(); + + updateTerminal(); + flush_out(); + } +} + + +// protected methods of FListBox +//---------------------------------------------------------------------- +void FListBox::adjustYOffset() +{ + int element_count = int(getCount()); + + if ( yoffset > element_count - getHeight() + 2 ) + yoffset = element_count - getHeight() + 2; + + if ( yoffset < 0 ) + yoffset = 0; + + if ( current < yoffset ) + current = yoffset; + + if ( current >= yoffset + getHeight() - 1 ) + yoffset = current - getHeight() + 2; +} + +//---------------------------------------------------------------------- +void FListBox::adjustSize() +{ + int element_count; + adjustYOffset(); + FWidget::adjustSize(); + + element_count = int(getCount()); + vbar->setMaximum(element_count - getHeight() + 2); + vbar->setPageSize(element_count, getHeight() - 2); + vbar->setX(getWidth()); + vbar->setHeight (getHeight()-2, false); + vbar->resize(); + + hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); + hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); + hbar->setY(getHeight()); + hbar->setWidth (getWidth()-2, false); + hbar->resize(); + + if ( element_count < getHeight() - 1 ) + vbar->hide(); + else + vbar->setVisible(); + + if ( max_line_width < getWidth() - nf_offset - 3 ) + hbar->hide(); + else + hbar->setVisible(); +} + + // private methods of FListBox //---------------------------------------------------------------------- void FListBox::init() @@ -172,15 +1491,15 @@ void FListBox::draw() drawList(); isFocus = ((flags & fc::focus) != 0); - if ( isFocus && statusBar() ) + if ( isFocus && getStatusBar() ) { FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); + FString curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { - statusBar()->setMessage(msg); - statusBar()->drawMessage(); + getStatusBar()->setMessage(msg); + getStatusBar()->drawMessage(); } } } @@ -228,8 +1547,8 @@ void FListBox::drawList() end = uInt(getHeight()-2); inc_len = inc_search.getLength(); - if ( end > count() ) - end = count(); + if ( end > getCount() ) + end = getCount(); if ( last_yoffset >= 0 && last_yoffset == yoffset @@ -487,1320 +1806,3 @@ void FListBox::processChanged() { emitCallback("row-changed"); } - -// protected methods of FListBox -//---------------------------------------------------------------------- -void FListBox::adjustYOffset() -{ - int element_count = int(count()); - - if ( yoffset > element_count - getHeight() + 2 ) - yoffset = element_count - getHeight() + 2; - - if ( yoffset < 0 ) - yoffset = 0; - - if ( current < yoffset ) - current = yoffset; - - if ( current >= yoffset + getHeight() - 1 ) - yoffset = current - getHeight() + 2; -} - -//---------------------------------------------------------------------- -void FListBox::adjustSize() -{ - int element_count; - adjustYOffset(); - FWidget::adjustSize(); - - element_count = int(count()); - vbar->setMaximum(element_count - getHeight() + 2); - vbar->setPageSize(element_count, getHeight() - 2); - vbar->setX(getWidth()); - vbar->setHeight (getHeight()-2, false); - vbar->resize(); - - hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); - hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); - hbar->setY(getHeight()); - hbar->setWidth (getWidth()-2, false); - hbar->resize(); - - if ( element_count < getHeight() - 1 ) - vbar->hide(); - else - vbar->setVisible(); - - if ( max_line_width < getWidth() - nf_offset - 3 ) - hbar->hide(); - else - hbar->setVisible(); -} - -// public methods of FListBox -//---------------------------------------------------------------------- -void FListBox::setCurrentItem(int index) -{ - int element_count; - - if ( index == current ) - return; - - element_count = int(count()); - - if ( index > element_count ) - current = element_count; - else if ( index < 1 ) - current = 1; - else - current = index; - - xoffset = 0; - yoffset = 0; - adjustSize(); - vbar->setValue(yoffset); - - if ( isVisible() ) - redraw(); -} - -//---------------------------------------------------------------------- -void FListBox::hide() -{ - int n, size; - short fg, bg; - char* blank; - FWidget* parent_widget = getParentWidget(); - - FWidget::hide(); - - if ( parent_widget ) - { - fg = parent_widget->getForegroundColor(); - bg = parent_widget->getBackgroundColor(); - } - else - { - fg = wc.dialog_fg; - bg = wc.dialog_bg; - } - - setColor (fg, bg); - n = isNewFont() ? 1 : 0; - size = getWidth() + n; - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset (blank, ' ', uLong(size)); - blank[size] = '\0'; - - for (int y=0; y < getHeight(); y++) - { - setPrintPos (1, 1 + y); - print (blank); - } - - delete[] blank; -} - -//---------------------------------------------------------------------- -void FListBox::showInsideBrackets ( int index - , fc::brackets_type b ) -{ - data[uInt(index-1)].brackets = b; - - if ( b == fc::NoBrackets ) - return; - - int len = int(data[uInt(index-1)].getText().getLength() + 2); - - if ( len > max_line_width ) - { - max_line_width = len; - - if ( len >= getWidth() - nf_offset - 3 ) - { - hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); - hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); - hbar->setValue (xoffset); - - if ( ! hbar->isVisible() ) - hbar->setVisible(); - } - } -} - -//---------------------------------------------------------------------- -void FListBox::setGeometry (int x, int y, int w, int h, bool adjust) -{ - FWidget::setGeometry(x, y, w, h, adjust); - - if ( isNewFont() ) - { - vbar->setGeometry (getWidth(), 2, 2, getHeight()-2); - hbar->setGeometry (1, getHeight(), getWidth()-2, 1); - } - else - { - vbar->setGeometry (getWidth(), 2, 1, getHeight()-2); - hbar->setGeometry (2, getHeight(), getWidth()-2, 1); - } -} - -//---------------------------------------------------------------------- -bool FListBox::setEnable (bool on) -{ - FWidget::setEnable(on); - - if ( on ) - flags |= fc::active; - else - flags &= ~fc::active; - - return on; -} - -//---------------------------------------------------------------------- -bool FListBox::setFocus (bool on) -{ - FWidget::setFocus(on); - - if ( on ) - { - flags |= fc::focus; - - if ( statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) - statusBar()->setMessage(msg); - } - } - else - { - flags &= ~fc::focus; - - if ( statusBar() ) - statusBar()->clearMessage(); - } - - return on; -} - -//---------------------------------------------------------------------- -void FListBox::onKeyPress (FKeyEvent* ev) -{ - int element_count = int(count()); - int current_before = current; - int xoffset_before = xoffset; - int yoffset_before = yoffset; - int key = ev->key(); - - switch ( key ) - { - case fc::Fkey_return: - case fc::Fkey_enter: - processClick(); - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_up: - current--; - - if ( current < 1 ) - current=1; - - if ( current <= yoffset ) - yoffset--; - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_down: - current++; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset >= getHeight() - 1 ) - yoffset++; - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_left: - xoffset--; - - if ( xoffset < 0 ) - xoffset = 0; - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_right: - xoffset++; - - if ( xoffset > max_line_width - getWidth() + nf_offset + 4 ) - xoffset = max_line_width - getWidth() + nf_offset + 4; - - if ( xoffset < 0 ) - xoffset = 0; - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_ppage: - current -= getHeight()-3; - - if ( current < 1 ) - current=1; - - if ( current <= yoffset ) - { - yoffset -= getHeight()-3; - - if ( yoffset < 0 ) - yoffset=0; - } - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_npage: - current += getHeight()-3; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset >= getHeight() - 1 ) - { - yoffset += getHeight()-3; - - if ( yoffset > element_count - getHeight() + 2 ) - yoffset = element_count - getHeight() + 2; - } - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_home: - current = 1; - yoffset = 0; - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_end: - current = element_count; - - if ( current >= getHeight() - 1 ) - yoffset = element_count - getHeight() + 2; - - inc_search.clear(); - ev->accept(); - break; - - case fc::Fkey_ic: // insert key - if ( isMultiSelection() ) - { - if ( isSelected(current) ) - unselectItem(current); - else - selectItem(current); - - processSelect(); - current++; - - if ( current > element_count ) - current = element_count; - - if ( current-yoffset >= getHeight() - 1 ) - yoffset++; - - ev->accept(); - } - - inc_search.clear(); - break; - - case fc::Fkey_space: - { - uInt inc_len = inc_search.getLength(); - - if ( inc_len > 0 ) - { - inc_search += L' '; - bool inc_found = false; - uInt end = count(); - - for (uInt i=0; i < end; i++) - { - if ( ! inc_found - && inc_search.toLower() - == data[i].getText().left(inc_len+1).toLower() ) - { - setCurrentItem(int(i+1)); - inc_found = true; - break; - } - } - - if ( ! inc_found ) - { - inc_search.remove(inc_len, 1); - ev->ignore(); - } - else - ev->accept(); - } - else if ( isMultiSelection() ) - { - if ( isSelected(current) ) - unselectItem(current); - else - selectItem(current); - - processSelect(); - inc_search.clear(); - ev->accept(); - } - } - break; - - case fc::Fkey_erase: - case fc::Fkey_backspace: - { - uInt inc_len = inc_search.getLength(); - - if ( inc_len > 0 ) - { - inc_search.remove(inc_len-1, 1); - - if ( inc_len > 1 ) - { - uInt end = count(); - - for (uInt i=0; i < end; i++) - { - if ( inc_search.toLower() - == data[i].getText().left(inc_len-1).toLower() ) - { - setCurrentItem(int(i+1)); - break; - } - } - } - - ev->accept(); - } - else - ev->ignore(); - } - break; - - case fc::Fkey_escape: - case fc::Fkey_escape_mintty: - if ( inc_search.getLength() > 0 ) - { - inc_search.clear(); - ev->accept(); - } - break; - - default: - if ( key > 0x20 && key <= 0x10fff ) - { - // incremental search - if ( inc_search.getLength() == 0 ) - inc_search = wchar_t(key); - else - inc_search += wchar_t(key); - - uInt inc_len = inc_search.getLength(); - bool inc_found = false; - uInt end = count(); - - for (uInt i=0; i < end; i++) - { - if ( ! inc_found - && inc_search.toLower() - == data[i].getText().left(inc_len).toLower() ) - { - setCurrentItem(int(i+1)); - inc_found = true; - break; - } - } - - if ( ! inc_found ) - { - inc_search.remove(inc_len-1, 1); - - if ( inc_len == 1 ) - ev->ignore(); - else - ev->accept(); - } - else - ev->accept(); - } - else - ev->ignore(); - } - - if ( current_before != current ) - { - processChanged(); - - if ( ! isMultiSelection() ) - processSelect(); - } - - if ( ev->isAccepted() ) - { - if ( isVisible() ) - drawList(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - hbar->setValue (xoffset); - - if ( hbar->isVisible() && xoffset_before != xoffset ) - hbar->drawBar(); - - updateTerminal(); - flush_out(); - } -} - -//---------------------------------------------------------------------- -void FListBox::onMouseDown (FMouseEvent* ev) -{ - int yoffset_before, mouse_x, mouse_y; - - if ( ev->getButton() != fc::LeftButton - && ev->getButton() != fc::RightButton ) - { - return; - } - - if ( ev->getButton() == fc::RightButton && ! isMultiSelection() ) - return; - - if ( ! hasFocus() ) - { - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - } - - yoffset_before = yoffset; - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( mouse_x > 1 && mouse_x < getWidth() - && mouse_y > 1 && mouse_y < getHeight() ) - { - current = yoffset + mouse_y - 1; - - if ( current > int(count()) ) - current = int(count()); - inc_search.clear(); - - if ( ev->getButton() == fc::RightButton ) - { - if ( isMultiSelection() ) - { - if ( isSelected(current) ) - { - mouse_select = false; - unselectItem(current); - } - else - { - mouse_select = true; - selectItem(current); - } - - processSelect(); - secect_from_item = current; - } - } - - if ( isVisible() ) - drawList(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - updateTerminal(); - flush_out(); - } -} - -//---------------------------------------------------------------------- -void FListBox::onMouseUp (FMouseEvent* ev) -{ - if ( drag_scroll != FListBox::noScroll ) - { - delOwnTimer(); - drag_scroll = FListBox::noScroll; - scroll_distance = 1; - scroll_timer = false; - } - - if ( ev->getButton() == fc::LeftButton ) - { - int mouse_x = ev->getX(); - int mouse_y = ev->getY(); - - if ( mouse_x > 1 && mouse_x < getWidth() - && mouse_y > 1 && mouse_y < getHeight() ) - { - processChanged(); - - if ( ! isMultiSelection() ) - processSelect(); - } - } -} - -//---------------------------------------------------------------------- -void FListBox::onMouseMove (FMouseEvent* ev) -{ - int current_before, yoffset_before, mouse_x, mouse_y; - - if ( ev->getButton() != fc::LeftButton - && ev->getButton() != fc::RightButton ) - { - return; - } - - if ( ev->getButton() == fc::RightButton && ! isMultiSelection() ) - return; - - current_before = current; - yoffset_before = yoffset; - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( mouse_x > 1 && mouse_x < getWidth() - && mouse_y > 1 && mouse_y < getHeight() ) - { - current = yoffset + mouse_y - 1; - - if ( current > int(count()) ) - current = int(count()); - - inc_search.clear(); - - // handle multiple selections - if ( ev->getButton() == fc::RightButton - && isMultiSelection() - && current_before != current ) - { - int from, to; - - if ( secect_from_item > current ) - { - from = current; - to = secect_from_item - 1; - } - else - { - from = secect_from_item + 1; - to = current; - } - for (int i=from; i <= to; i++) - { - if ( mouse_select ) - { - selectItem(i); - processSelect(); - } - else - { - unselectItem(i); - processSelect(); - } - } - - secect_from_item = current; - } - - if ( isVisible() ) - drawList(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - updateTerminal(); - flush_out(); - } - - // auto-scrolling when dragging mouse outside the widget - if ( mouse_y < 2 ) - { - // drag up - if ( drag_scroll != FListBox::noScroll - && scroll_distance < getHeight()-2 ) - scroll_distance++; - - if ( ! scroll_timer && current > 1 ) - { - scroll_timer = true; - addTimer(scroll_repeat); - - if ( ev->getButton() == fc::RightButton ) - drag_scroll = FListBox::scrollUpSelect; - else - drag_scroll = FListBox::scrollUp; - } - - if ( current == 1 ) - { - delOwnTimer(); - drag_scroll = FListBox::noScroll; - } - } - else if ( mouse_y >= getHeight() ) - { - // drag down - if ( drag_scroll != FListBox::noScroll - && scroll_distance < getHeight()-2 ) - scroll_distance++; - - if ( ! scroll_timer && current < int(count()) ) - { - scroll_timer = true; - addTimer(scroll_repeat); - - if ( ev->getButton() == fc::RightButton ) - drag_scroll = FListBox::scrollDownSelect; - else - drag_scroll = FListBox::scrollDown; - } - - if ( current == int(count()) ) - { - delOwnTimer(); - drag_scroll = FListBox::noScroll; - } - } - else - { - // no dragging - delOwnTimer(); - scroll_timer = false; - scroll_distance = 1; - drag_scroll = FListBox::noScroll; - } -} - -//---------------------------------------------------------------------- -void FListBox::onMouseDoubleClick (FMouseEvent* ev) -{ - int mouse_x, mouse_y; - - if ( ev->getButton() != fc::LeftButton ) - return; - - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( mouse_x > 1 && mouse_x < getWidth() - && mouse_y > 1 && mouse_y < getHeight() ) - { - if ( yoffset + mouse_y - 1 > int(count()) ) - return; - - processClick(); - } -} - -//---------------------------------------------------------------------- -void FListBox::onTimer (FTimerEvent*) -{ - int element_count = int(count()); - int current_before = current; - int yoffset_before = yoffset; - - switch ( int(drag_scroll) ) - { - case FListBox::noScroll: - return; - - case FListBox::scrollUp: - case FListBox::scrollUpSelect: - if ( current_before == 1) - { - drag_scroll = FListBox::noScroll; - return; - } - - current -= scroll_distance; - - if ( current < 1 ) - current=1; - - if ( current <= yoffset ) - yoffset -= scroll_distance; - - if ( yoffset < 0 ) - yoffset=0; - break; - - case FListBox::scrollDown: - case FListBox::scrollDownSelect: - if ( current_before == element_count ) - { - drag_scroll = FListBox::noScroll; - return; - } - - current += scroll_distance; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset >= getHeight() - 1 ) - yoffset += scroll_distance; - - if ( yoffset > element_count - getHeight() + 2 ) - yoffset = element_count - getHeight() + 2; - - break; - - default: - break; - } - - // handle multiple selections - if ( drag_scroll == FListBox::scrollUpSelect - || drag_scroll == FListBox::scrollDownSelect ) - { - if ( isMultiSelection() && current_before != current ) - { - int from, to; - - if ( secect_from_item > current ) - { - from = current; - to = secect_from_item - 1; - } - else - { - from = secect_from_item + 1; - to = current; - } - - for (int i=from; i <= to; i++) - { - if ( mouse_select ) - { - selectItem(i); - processSelect(); - } - else - { - unselectItem(i); - processSelect(); - } - } - - secect_from_item = current; - } - } - - if ( isVisible() ) - drawList(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - updateTerminal(); - flush_out(); -} - -//---------------------------------------------------------------------- -void FListBox::onWheel (FWheelEvent* ev) -{ - int element_count, current_before, yoffset_before, yoffset_end, wheel; - element_count = int(count()); - current_before = current; - yoffset_before = yoffset; - yoffset_end = element_count - getHeight() + 2; - - if ( yoffset_end < 0 ) - yoffset_end = 0; - - wheel = ev->getWheel(); - - if ( drag_scroll != FListBox::noScroll ) - { - delOwnTimer(); - scroll_timer = false; - scroll_distance = 1; - drag_scroll = FListBox::noScroll; - } - - switch ( wheel ) - { - case fc::WheelUp: - if ( yoffset == 0 ) - break; - - yoffset -= 4; - - if ( yoffset < 0 ) - { - current -= 4+yoffset; - yoffset=0; - } - else - current -= 4; - - if ( current < 1 ) - current=1; - - inc_search.clear(); - break; - - case fc::WheelDown: - if ( yoffset == yoffset_end ) - break; - - yoffset += 4; - - if ( yoffset > yoffset_end ) - { - current += 4 - (yoffset - yoffset_end); - yoffset = yoffset_end; - } - else - current += 4; - - if ( current > element_count ) - current = element_count; - - inc_search.clear(); - break; - - default: - break; - } - - if ( current_before != current ) - { - processChanged(); - - if ( ! isMultiSelection() ) - processSelect(); - } - - if ( isVisible() ) - drawList(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - updateTerminal(); - flush_out(); -} - -//---------------------------------------------------------------------- -void FListBox::onFocusIn (FFocusEvent*) -{ - if ( statusBar() ) - statusBar()->drawMessage(); - - inc_search.clear(); -} - -//---------------------------------------------------------------------- -void FListBox::onFocusOut (FFocusEvent*) -{ - if ( statusBar() ) - { - statusBar()->clearMessage(); - statusBar()->drawMessage(); - } - - delOwnTimer(); - inc_search.clear(); -} - -//---------------------------------------------------------------------- -void FListBox::cb_VBarChange (FWidget*, void*) -{ - int distance = 1; - int element_count = int(count()); - int yoffset_before = yoffset; - int scrollType = vbar->getScrollType(); - - switch ( scrollType ) - { - case FScrollbar::scrollPageBackward: - distance = getHeight()-2; - // fall through - case FScrollbar::scrollStepBackward: - current -= distance; - - if ( current < 1 ) - current=1; - - if ( current <= yoffset ) - yoffset -= distance; - - if ( yoffset < 0 ) - yoffset = 0; - - break; - - case FScrollbar::scrollPageForward: - distance = getHeight()-2; - // fall through - case FScrollbar::scrollStepForward: - current += distance; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset >= getHeight() - 1 ) - yoffset += distance; - - if ( yoffset > element_count - getHeight() + 2 ) - yoffset = element_count - getHeight() + 2; - - break; - - case FScrollbar::scrollJump: - { - int val = vbar->getValue(); - - if ( yoffset == val ) - break; - - int c = current - yoffset; - yoffset = val; - - if ( yoffset > element_count - getHeight() + 2 ) - yoffset = element_count - getHeight() + 2; - - if ( yoffset < 0 ) - yoffset = 0; - - current = yoffset + c; - - if ( current < yoffset ) - current = yoffset; - - if ( current > element_count ) - current = element_count; - - break; - } - - case FScrollbar::scrollWheelUp: - { - FWheelEvent wheel_ev (fc::MouseWheel_Event, FPoint(2,2), fc::WheelUp); - onWheel(&wheel_ev); - } - break; - - case FScrollbar::scrollWheelDown: - { - FWheelEvent wheel_ev (fc::MouseWheel_Event, FPoint(2,2), fc::WheelDown); - onWheel(&wheel_ev); - } - break; - - default: - break; - } - - if ( isVisible() ) - drawList(); - - if ( scrollType >= FScrollbar::scrollStepBackward - && scrollType <= FScrollbar::scrollPageForward ) - { - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - updateTerminal(); - flush_out(); - } -} - -//---------------------------------------------------------------------- -void FListBox::cb_HBarChange (FWidget*, void*) -{ - int distance = 1; - int xoffset_before = xoffset; - int xoffset_end = max_line_width - getWidth() + nf_offset + 4; - int scrollType = hbar->getScrollType(); - - switch ( scrollType ) - { - case FScrollbar::scrollPageBackward: - distance = getWidth() - nf_offset - 4; - // fall through - case FScrollbar::scrollStepBackward: - xoffset -= distance; - - if ( xoffset < 0 ) - xoffset = 0; - break; - - case FScrollbar::scrollPageForward: - distance = getWidth() - nf_offset - 4; - // fall through - case FScrollbar::scrollStepForward: - xoffset += distance; - - if ( xoffset > max_line_width - getWidth() + nf_offset + 4 ) - xoffset = max_line_width - getWidth() + nf_offset + 4; - - if ( xoffset < 0 ) - xoffset = 0; - - break; - - case FScrollbar::scrollJump: - { - int val = hbar->getValue(); - - if ( xoffset == val ) - break; - - xoffset = val; - - if ( xoffset > max_line_width - getWidth() + nf_offset + 4 ) - xoffset = max_line_width - getWidth() + nf_offset + 4; - - if ( xoffset < 0 ) - xoffset = 0; - - break; - } - - case FScrollbar::scrollWheelUp: - if ( xoffset == 0 ) - break; - - xoffset -= 4; - - if ( xoffset < 0 ) - xoffset=0; - - break; - - case FScrollbar::scrollWheelDown: - if ( xoffset == xoffset_end ) - break; - - xoffset += 4; - - if ( xoffset > xoffset_end ) - xoffset = xoffset_end; - - break; - - default: - break; - } - - if ( isVisible() ) - { - drawList(); - updateTerminal(); - flush_out(); - } - - if ( scrollType >= FScrollbar::scrollStepBackward - && scrollType <= FScrollbar::scrollWheelDown ) - { - hbar->setValue (xoffset); - - if ( hbar->isVisible() && xoffset_before != xoffset ) - hbar->drawBar(); - - updateTerminal(); - flush_out(); - } -} - -//---------------------------------------------------------------------- -void FListBox::insert ( FString item - , fc::brackets_type b - , bool s ) -{ - int len, element_count; - - len = int(item.getLength()); - - if ( b ) - len += 2; - - if ( len > max_line_width ) - { - max_line_width = len; - - if ( len >= getWidth() - nf_offset - 3 ) - { - hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); - hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); - hbar->calculateSliderValues(); - - if ( ! hbar->isVisible() ) - hbar->setVisible(); - } - } - FListBoxItem listItem (item); - listItem.brackets = b; - listItem.selected = s; - data.push_back (listItem); - - element_count = int(count()); - vbar->setMaximum(element_count - getHeight() + 2); - vbar->setPageSize(element_count, getHeight() - 2); - vbar->calculateSliderValues(); - - if ( ! vbar->isVisible() && element_count >= getHeight() - 1 ) - vbar->setVisible(); -} - -//---------------------------------------------------------------------- -void FListBox::insert ( long item - , fc::brackets_type b - , bool s ) -{ - insert (FString().setNumber(item), b, s); -} - -//---------------------------------------------------------------------- -void FListBox::remove (int item) -{ - int element_count; - - if ( int(count()) < item ) - return; - - data.erase (data.begin() + item - 1); - element_count = int(count()); - max_line_width = 0; - - for (int i=0; i < element_count; i++) - { - int len = int(data[uInt(i)].getText().getLength()); - - if ( len > max_line_width ) - max_line_width = len; - } - - hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4); - hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4); - - if ( hbar->isVisible() && max_line_width < getWidth() - nf_offset - 3 ) - hbar->hide(); - - vbar->setMaximum(element_count - getHeight() + 2); - vbar->setPageSize(element_count, getHeight() - 2); - - if ( vbar->isVisible() && element_count < getHeight() - 1 ) - vbar->hide(); - - if ( current >= item && current > 1 ) - current--; - - if ( current > element_count ) - current = element_count; - - if ( yoffset > element_count - getHeight() + 2 ) - yoffset = element_count - getHeight() + 2; - - if ( yoffset < 0 ) - yoffset = 0; -} - -//---------------------------------------------------------------------- -void FListBox::clear() -{ - int size; - char* blank; - - data.clear(); - - current = 0; - xoffset = 0; - yoffset = 0; - max_line_width = 0; - last_current = -1; - last_yoffset = -1; - - vbar->setMinimum(0); - vbar->setValue(0); - vbar->hide(); - - hbar->setMinimum(0); - hbar->setValue(0); - hbar->hide(); - - // clear list from screen - setColor (wc.list_fg, wc.list_bg); - size = getWidth() - 2; - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset (blank, ' ', uLong(size)); - blank[size] = '\0'; - - for (int y=0; y < getHeight()-2; y++) - { - setPrintPos (2, 2 + y); - print (blank); - } - - delete[] blank; -} - -//---------------------------------------------------------------------- -void FListBox::setText (FString txt) -{ - text = txt; -} diff --git a/src/flistbox.h b/src/flistbox.h index 6ca59ab7..630bac11 100644 --- a/src/flistbox.h +++ b/src/flistbox.h @@ -44,20 +44,17 @@ class FListBoxItem { - private: - FString text; - fc::brackets_type brackets; - bool selected; - public: // Constructors FListBoxItem (); explicit FListBoxItem (FString&); explicit FListBoxItem (const std::string&); explicit FListBoxItem (const char*); + // Destructor virtual ~FListBoxItem(); + // Accessors virtual FString getText() const; protected: @@ -66,10 +63,17 @@ class FListBoxItem void setText (const char*); private: + // Friend classes friend class FListBox; + + // Data Members + FString text; + fc::brackets_type brackets; + bool selected; }; #pragma pack(pop) + // FListBoxItem inline functions //---------------------------------------------------------------------- inline FString FListBoxItem::getText() const @@ -97,7 +101,83 @@ inline void FListBoxItem::setText (const char* txt) class FListBox : public FWidget { + public: + // Using-declaration + using FWidget::setGeometry; + + // Constructor + explicit FListBox (FWidget* = 0); + + // Destructor + ~FListBox(); + + // Accessors + const char* getClassName() const; + uInt getCount() const; + FListBoxItem getItem (int) const; + int currentItem() const; + FString& getText(); + + // Mutators + void setCurrentItem (int); + void selectItem (int); + void unselectItem (int); + void showInsideBrackets (int, fc::brackets_type); + void showNoBrackets (int); + void setGeometry (int, int, int, int, bool = true); + void setMultiSelection (bool); + void setMultiSelection (); + void unsetMultiSelection (); + bool setEnable (bool); + bool setEnable(); + bool unsetEnable(); + bool setDisable(); + bool setFocus (bool); + bool setFocus(); + bool unsetFocus(); + void setText (const FString); + + // Inquiries + bool isSelected (int) const; + bool isMultiSelection() const; + bool hasBrackets (int) const; + + // Methods + void hide(); + void insert ( FString + , fc::brackets_type = fc::NoBrackets + , bool = false ); + void insert ( long + , fc::brackets_type = fc::NoBrackets + , bool = false ); + void remove (int); + void clear(); + + // Event handlers + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onMouseDoubleClick (FMouseEvent*); + void onWheel (FWheelEvent*); + void onTimer (FTimerEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); + + // Callback methods + void cb_VBarChange (FWidget*, void*); + void cb_HBarChange (FWidget*, void*); + + protected: + // Methods + void adjustYOffset(); + void adjustSize(); + private: + // Typedef + typedef std::vector listBoxItem; + + // Enumeration enum dragScroll { noScroll = 0, @@ -107,7 +187,23 @@ class FListBox : public FWidget scrollDownSelect = 4 }; - std::vector data; + // Disable copy constructor + FListBox (const FListBox&); + + // Disable assignment operator (=) + FListBox& operator = (const FListBox&); + + // Methods + void init(); + void draw(); + void drawLabel(); + void drawList(); + void processClick(); + void processSelect(); + void processChanged(); + + // Data Members + listBoxItem data; FScrollbar* vbar; FScrollbar* hbar; FString text; @@ -126,86 +222,6 @@ class FListBox : public FWidget int last_yoffset; int nf_offset; int max_line_width; - - private: - // Disable copy constructor - FListBox (const FListBox&); - // Disable assignment operator (=) - FListBox& operator = (const FListBox&); - - void init(); - void draw(); - void drawLabel(); - void drawList(); - void processClick(); - void processSelect(); - void processChanged(); - - protected: - void adjustYOffset(); - void adjustSize(); - - public: - // Constructor - explicit FListBox (FWidget* = 0); - // Destructor - ~FListBox(); - - const char* getClassName() const; - void hide(); - - // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onMouseDoubleClick (FMouseEvent*); - void onWheel (FWheelEvent*); - void onTimer (FTimerEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); - - // Callback methods - void cb_VBarChange (FWidget*, void*); - void cb_HBarChange (FWidget*, void*); - - uInt count() const; - FListBoxItem Item (int) const; - int currentItem() const; - void setCurrentItem (int); - void selectItem (int); - void unselectItem (int); - bool isSelected (int) const; - void showInsideBrackets (int, fc::brackets_type); - void showNoBrackets (int); - bool hasBrackets (int) const; - // make every setGeometry from FWidget available - using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - - void setMultiSelection (bool); - void setMultiSelection (); - void unsetMultiSelection (); - bool isMultiSelection() const; - bool setEnable (bool); - bool setEnable(); - bool unsetEnable(); - bool setDisable(); - bool setFocus (bool); - bool setFocus(); - bool unsetFocus(); - - void insert ( FString - , fc::brackets_type = fc::NoBrackets - , bool = false ); - void insert ( long - , fc::brackets_type = fc::NoBrackets - , bool = false ); - void remove ( int); - void clear(); - - void setText (const FString); - FString& getText(); }; #pragma pack(pop) @@ -216,17 +232,21 @@ inline const char* FListBox::getClassName() const { return "FListBox"; } //---------------------------------------------------------------------- -inline uInt FListBox::count() const +inline uInt FListBox::getCount() const { return uInt(data.size()); } //---------------------------------------------------------------------- -inline FListBoxItem FListBox::Item(int index) const +inline FListBoxItem FListBox::getItem (int index) const { return data[uInt(index-1)]; } //---------------------------------------------------------------------- inline int FListBox::currentItem() const { return current; } +//---------------------------------------------------------------------- +inline FString& FListBox::getText() +{ return text; } + //---------------------------------------------------------------------- inline void FListBox::selectItem (int index) { data[uInt(index-1)].selected = true; } @@ -235,18 +255,10 @@ inline void FListBox::selectItem (int index) inline void FListBox::unselectItem (int index) { data[uInt(index-1)].selected = false; } -//---------------------------------------------------------------------- -inline bool FListBox::isSelected(int index) const -{ return data[uInt(index-1)].selected; } - //---------------------------------------------------------------------- inline void FListBox::showNoBrackets(int index) { data[uInt(index-1)].brackets = fc::NoBrackets; } -//---------------------------------------------------------------------- -inline bool FListBox::hasBrackets(int index) const -{ return bool(data[uInt(index-1)].brackets > 0); } - //---------------------------------------------------------------------- inline void FListBox::setMultiSelection (bool on) { multi_select = on; } @@ -259,10 +271,6 @@ inline void FListBox::setMultiSelection() inline void FListBox::unsetMultiSelection() { setMultiSelection(false); } -//---------------------------------------------------------------------- -inline bool FListBox::isMultiSelection() const -{ return multi_select; } - //---------------------------------------------------------------------- inline bool FListBox::setEnable() { return setEnable(true); } @@ -284,7 +292,15 @@ inline bool FListBox::unsetFocus() { return setFocus(false); } //---------------------------------------------------------------------- -inline FString& FListBox::getText() -{ return text; } +inline bool FListBox::isSelected(int index) const +{ return data[uInt(index-1)].selected; } + +//---------------------------------------------------------------------- +inline bool FListBox::isMultiSelection() const +{ return multi_select; } + +//---------------------------------------------------------------------- +inline bool FListBox::hasBrackets(int index) const +{ return bool(data[uInt(index-1)].brackets > 0); } #endif // _FLISTBOX_H diff --git a/src/fmenu.cpp b/src/fmenu.cpp index 0cbb4963..3a58cc87 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -76,7 +76,697 @@ FMenu::~FMenu() } +// public methods of FMenu +//---------------------------------------------------------------------- +bool FMenu::setMenuWidget (bool on) +{ + if ( isMenuWidget() == on ) + return true; + + if ( on ) + flags |= fc::menu_widget; + else + flags &= ~fc::menu_widget; + + return on; +} + +//---------------------------------------------------------------------- +void FMenu::setStatusbarMessage(FString msg) +{ + FWidget::setStatusbarMessage(msg); + + if ( item ) + item->setStatusbarMessage(msg); +} + +//---------------------------------------------------------------------- +void FMenu::show() +{ + if ( ! isVisible() ) + return; + + FWindow::show(); +} + +//---------------------------------------------------------------------- +void FMenu::hide() +{ + if ( isVisible() ) + { + FWindow::hide(); + const FRect& t_geometry = getTermGeometryWithShadow(); + restoreVTerm (t_geometry); + updateTerminal(); + flush_out(); + + if ( ! isSubMenu() ) + { + FMenu* open_menu = static_cast(getOpenMenu()); + + if ( open_menu && open_menu != this ) + open_menu->hide(); + + setOpenMenu(0); + } + + mouse_down = false; + } +} + +//---------------------------------------------------------------------- +void FMenu::onKeyPress (FKeyEvent* ev) +{ + FWidget* menubar; + + // looking for menu hotkey + if ( hotkeyMenu(ev) ) + return; + + // looking for menu bar hotkey + menubar = getMenuBar(); + + if ( menubar ) + { + FMenuBar* mbar = reinterpret_cast(menubar); + + if ( mbar->hotkeyMenu(ev) ) + return; + } + + switch ( ev->key() ) + { + case fc::Fkey_return: + case fc::Fkey_enter: + if ( hasSelectedItem() ) + { + FMenuItem* sel_item = getSelectedItem(); + + if ( sel_item->hasMenu() ) + openSubMenu (sel_item->getMenu()); + else + { + unselectItem(); + hide(); + hideSuperMenus(); + sel_item->processClicked(); + } + } + break; + + case fc::Fkey_up: + selectPrevItem(); + break; + + case fc::Fkey_down: + selectNextItem(); + break; + + case fc::Fkey_left: + if ( isSubMenu() ) + { + FMenu* smenu = reinterpret_cast(getSuperMenu()); + hideSubMenus(); + hide(); + + if ( smenu->getSelectedItem() ) + smenu->getSelectedItem()->setFocus(); + + smenu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); + } + else + keypressMenuBar(ev); // select previous menu + break; + + case fc::Fkey_right: + if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) + { + FMenu* sub_menu = getSelectedItem()->getMenu(); + + if ( ! sub_menu->isVisible() ) + openSubMenu (sub_menu); + else + keypressMenuBar(ev); // select next menu + } + else + keypressMenuBar(ev); // select next menu + break; + + case fc::Fkey_escape: + case fc::Fkey_escape_mintty: + unselectItem(); + hideSubMenus(); + hide(); + + if ( isSubMenu() ) + { + FMenu* smenu = reinterpret_cast(getSuperMenu()); + + if ( smenu->getSelectedItem() ) + smenu->getSelectedItem()->setFocus(); + + smenu->redraw(); + } + else + { + FWidget* super = getSuperMenu(); + hideSuperMenus(); + + if ( getStatusBar() ) + getStatusBar()->clearMessage(); + + if ( ! (super && isWindowsMenu(super)) ) + switchToPrevWindow(); + } + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); + break; + + case fc::Fmkey_1: + case fc::Fmkey_2: + case fc::Fmkey_3: + case fc::Fmkey_4: + case fc::Fmkey_5: + case fc::Fmkey_6: + case fc::Fmkey_7: + case fc::Fmkey_8: + case fc::Fmkey_9: + // do nothing: + // handle the dialog switch accelerator in FApplication + return; + + default: + break; + } + + // always accept key event -> no forwarding to the parent widget + ev->accept(); +} + +//---------------------------------------------------------------------- +void FMenu::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + { + if ( open_sub_menu ) + { + // close open sub menu + open_sub_menu->hideSubMenus(); + open_sub_menu->hide(); + open_sub_menu = 0; + + if ( getSelectedItem() ) + getSelectedItem()->setFocus(); + + redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); + } + + return; + } + + if ( mouse_down ) + return; + + if ( ! isWindowActive() ) + setActiveWindow(this); + + mouse_down = true; + + if ( ! item_list.empty() ) + { + std::vector::const_iterator iter, end; + FMenu* show_sub_menu = 0; + bool focus_changed = false; + FPoint mouse_pos; + + iter = item_list.begin(); + end = item_list.end(); + mouse_pos = ev->getPos(); + mouse_pos -= FPoint(getRightPadding(),getTopPadding()); + + while ( iter != end ) + { + int x1, x2, y, mouse_x, mouse_y; + x1 = (*iter)->getX(); + x2 = (*iter)->getX() + (*iter)->getWidth(); + y = (*iter)->getY(); + mouse_x = mouse_pos.getX(); + mouse_y = mouse_pos.getY(); + + if ( mouse_x >= x1 + && mouse_x < x2 + && mouse_y == y ) + { + // Mouse pointer over item + if ( hasSelectedItem() ) + { + FMenuItem* sel_item = getSelectedItem(); + if ( sel_item + && sel_item->hasMenu() + && sel_item->getMenu() == open_sub_menu ) + { + if ( sel_item != *iter ) + hideSubMenus(); + else + { + open_sub_menu->unselectItem(); + raiseWindow (open_sub_menu); + open_sub_menu->redraw(); + sel_item->setFocus(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); + } + } + } + + if ( ! (*iter)->isSelected() ) + { + unselectItem(); + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + (*iter)->setSelected(); + setSelectedItem(*iter); + (*iter)->setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + if ( (*iter)->hasMenu() ) + { + FMenu* sub_menu = (*iter)->getMenu(); + if ( ! sub_menu->isVisible() ) + show_sub_menu = sub_menu; + } + + focus_changed = true; + } + } + + ++iter; + } + + if ( focus_changed ) + redraw(); + + if ( show_sub_menu ) + { + // open sub menu + show_sub_menu->setVisible(); + show_sub_menu->show(); + open_sub_menu = show_sub_menu; + raiseWindow (show_sub_menu); + show_sub_menu->redraw(); + updateTerminal(); + flush_out(); + } + } +} + +//---------------------------------------------------------------------- +void FMenu::onMouseUp (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( mouse_down ) + { + mouse_down = false; + + if ( ! item_list.empty() ) + { + std::vector::const_iterator iter, end; + FPoint mouse_pos; + iter = item_list.begin(); + end = item_list.end(); + mouse_pos = ev->getPos(); + mouse_pos -= FPoint(getRightPadding(),getTopPadding()); + + while ( iter != end ) + { + int x1, x2, y; + x1 = (*iter)->getX(); + x2 = (*iter)->getX() + (*iter)->getWidth(); + y = (*iter)->getY(); + + if ( (*iter)->isSelected() ) + { + int mouse_x = mouse_pos.getX(); + int mouse_y = mouse_pos.getY(); + + if ( mouse_x >= x1 + && mouse_x < x2 + && mouse_y == y ) + { + // Mouse pointer over item + if ( (*iter)->hasMenu() ) + { + FMenu* sub_menu = (*iter)->getMenu(); + if ( ! sub_menu->isVisible() ) + openSubMenu (sub_menu); + else if ( open_sub_menu ) + { + open_sub_menu->selectFirstItem(); + + if ( open_sub_menu->hasSelectedItem() ) + open_sub_menu->getSelectedItem()->setFocus(); + + open_sub_menu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + updateTerminal(); + flush_out(); + } + + return; + } + else + { + unselectItem(); + hide(); + hideSuperMenus(); + (*iter)->processClicked(); + } + } + } + + ++iter; + } + + // Click on a non-FMenuItem (border or separator line) + unselectItem(); + hide(); + hideSuperMenus(); + } + } +} + +//---------------------------------------------------------------------- +void FMenu::onMouseMove (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( ! isWindowActive() ) + setActiveWindow(this); + + if ( mouse_down && ! item_list.empty() ) + { + std::vector::const_iterator iter, end; + FMenu* smenu = 0; + bool focus_changed = false; + bool mouse_over_menu = false; + bool mouse_over_submenu = false; + bool mouse_over_supermenu = false; + bool mouse_over_menubar = false; + bool hide_sub_menu = false; + FMenu* show_sub_menu = 0; + FPoint mouse_pos; + + iter = item_list.begin(); + end = item_list.end(); + mouse_pos = ev->getPos(); + mouse_pos -= FPoint(getRightPadding(),getTopPadding()); + + if ( getTermGeometry().contains(ev->getTermPos()) ) + mouse_over_menu = true; + + if ( open_sub_menu ) + { + const FRect& submenu_geometry = open_sub_menu->getTermGeometry(); + if ( submenu_geometry.contains(ev->getTermPos()) ) + mouse_over_submenu = true; + } + + if ( isSubMenu() ) + { + smenu = superMenuAt (ev->getTermPos()); + + if ( smenu ) + mouse_over_supermenu = true; + } + + if ( getMenuBar() + && isMenuBar(getMenuBar()) + && getMenuBar()->getTermGeometry().contains(ev->getTermPos()) ) + { + mouse_over_menubar = true; + } + + while ( iter != end ) + { + int x1, x2, y, mouse_x, mouse_y; + x1 = (*iter)->getX(); + x2 = (*iter)->getX() + (*iter)->getWidth(); + y = (*iter)->getY(); + mouse_x = mouse_pos.getX(); + mouse_y = mouse_pos.getY(); + + if ( mouse_x >= x1 + && mouse_x < x2 + && mouse_y == y ) + { + if ( (*iter)->isEnabled() + && ! (*iter)->isSelected() + && ! (*iter)->isSeparator() ) + { + // Mouse pointer over item + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + (*iter)->setSelected(); + setSelectedItem(*iter); + (*iter)->setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + // sub menu handling + if ( (*iter)->hasMenu() ) + { + FMenu* sub_menu = (*iter)->getMenu(); + + if ( ! sub_menu->isVisible() ) + show_sub_menu = sub_menu; + } + else if ( open_sub_menu ) + hide_sub_menu = true; + + focus_changed = true; + } + } + else + { + if ( mouse_over_menu + && (*iter)->isEnabled() + && (*iter)->isSelected() + && ! mouse_over_submenu ) + { + // Unselect selected item without mouse focus + (*iter)->unsetSelected(); + + if ( getSelectedItem() == *iter ) + setSelectedItem(0); + + focus_changed = true; + } + } + + ++iter; + } + + if ( mouse_over_submenu ) + { + // Mouse event handover to sub-menu + const FPoint& t = ev->getTermPos(); + const FPoint& p = open_sub_menu->termToWidgetPos(t); + int b = ev->getButton(); + FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); + open_sub_menu->mouse_down = true; + setClickedWidget(open_sub_menu); + open_sub_menu->onMouseMove(_ev); + delete _ev; + return; + } + else if ( ! mouse_over_menu && mouse_over_supermenu ) + { + // Mouse event handover to super-menu + const FPoint& t = ev->getTermPos(); + const FPoint& p = smenu->termToWidgetPos(t); + int b = ev->getButton(); + FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); + smenu->mouse_down = true; + setClickedWidget(smenu); + smenu->onMouseMove(_ev); + delete _ev; + return; + } + else if ( mouse_over_menubar ) + { + // Mouse event handover to the menu bar + FWidget* menubar = getMenuBar(); + const FPoint& t = ev->getTermPos(); + const FPoint& p = menubar->termToWidgetPos(t); + int b = ev->getButton(); + FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); + setClickedWidget(menubar); + FMenuBar* mbar = reinterpret_cast(menubar); + mbar->mouse_down = true; + mbar->onMouseMove(_ev); + delete _ev; + return; + } + else if ( ! hasSelectedItem() && mouse_over_menu ) + { + // Mouse is over border or separator + if ( getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + if ( curMsg != msg ) + { + getStatusBar()->setMessage(msg); + getStatusBar()->drawMessage(); + } + } + + if ( open_sub_menu ) + hide_sub_menu = true; + } + + if ( focus_changed ) + redraw(); + + if ( show_sub_menu ) + { + // close open sub menu + if ( open_sub_menu ) + { + open_sub_menu->hideSubMenus(); + open_sub_menu->hide(); + } + + // open sub menu + show_sub_menu->setVisible(); + show_sub_menu->show(); + open_sub_menu = show_sub_menu; + raiseWindow (show_sub_menu); + show_sub_menu->redraw(); + updateTerminal(); + flush_out(); + } + else if ( hide_sub_menu ) + { + open_sub_menu->hideSubMenus(); + open_sub_menu->hide(); + open_sub_menu = 0; + updateTerminal(); + flush_out(); + } + } +} + +//---------------------------------------------------------------------- +void FMenu::cb_menuitem_toggled (FWidget* widget, void*) +{ + FMenuItem* menuitem = static_cast(widget); + std::vector::const_iterator iter, end; + + if ( ! has_checkable_items ) + return; + + if ( ! menuitem->isChecked() ) + return; + + if ( item_list.empty() ) + return; + + iter = item_list.begin(); + end = item_list.end(); + + while ( iter != end ) + { + if ( (*iter) != menuitem + && (*iter)->isChecked() + && isRadioMenuItem(*iter) ) + { + (*iter)->unsetChecked(); + } + + ++iter; + } +} + + // private methods of FMenu +//---------------------------------------------------------------------- +bool FMenu::isWindowsMenu (FWidget* w) const +{ + return w->isDialogWidget(); +} + +//---------------------------------------------------------------------- +bool FMenu::isMenuBar (FWidget* w) const +{ + return bool ( std::strcmp ( w->getClassName() + , const_cast("FMenuBar") ) == 0 ); +} + +//---------------------------------------------------------------------- +bool FMenu::isMenu (FWidget* w) const +{ + return bool ( std::strcmp ( w->getClassName() + , const_cast("FMenu") ) == 0 ); +} + +//---------------------------------------------------------------------- +bool FMenu::isRadioMenuItem (FWidget* w) const +{ + return bool ( std::strcmp ( w->getClassName() + , const_cast("FRadioMenuItem") ) == 0 ); +} + +//---------------------------------------------------------------------- +bool FMenu::isSubMenu() const +{ + FWidget* super = getSuperMenu(); + + if ( super && isMenu(super) ) + return true; + else + return false; +} + //---------------------------------------------------------------------- void FMenu::init(FWidget* parent) { @@ -156,7 +846,7 @@ void FMenu::calculateDimensions() adjust_X = adjustX(getX()); // set widget geometry - setGeometry (adjust_X, getY(), int(max_item_width + 2), int(count() + 2)); + setGeometry (adjust_X, getY(), int(max_item_width + 2), int(getCount() + 2)); // set geometry of all items iter = item_list.begin(); @@ -202,7 +892,7 @@ void FMenu::adjustItems() menu->setPos (menu_X, menu_Y); // call sub-menu adjustItems() - if ( menu->count() > 0 ) + if ( menu->getCount() > 0 ) menu->adjustItems(); } @@ -225,44 +915,6 @@ int FMenu::adjustX (int x_pos) return x_pos; } -//---------------------------------------------------------------------- -bool FMenu::isWindowsMenu (FWidget* w) const -{ - return w->isDialogWidget(); -} - -//---------------------------------------------------------------------- -bool FMenu::isMenuBar (FWidget* w) const -{ - return bool ( std::strcmp ( w->getClassName() - , const_cast("FMenuBar") ) == 0 ); -} - -//---------------------------------------------------------------------- -bool FMenu::isMenu (FWidget* w) const -{ - return bool ( std::strcmp ( w->getClassName() - , const_cast("FMenu") ) == 0 ); -} - -//---------------------------------------------------------------------- -bool FMenu::isRadioMenuItem (FWidget* w) const -{ - return bool ( std::strcmp ( w->getClassName() - , const_cast("FRadioMenuItem") ) == 0 ); -} - -//---------------------------------------------------------------------- -bool FMenu::isSubMenu() const -{ - FWidget* super = getSuperMenu(); - - if ( super && isMenu(super) ) - return true; - else - return false; -} - //---------------------------------------------------------------------- void FMenu::openSubMenu (FMenu* sub_menu) { @@ -281,8 +933,8 @@ void FMenu::openSubMenu (FMenu* sub_menu) raiseWindow (sub_menu); sub_menu->redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); @@ -406,8 +1058,8 @@ bool FMenu::selectNextItem() redraw(); next->setFocus(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); @@ -457,8 +1109,8 @@ bool FMenu::selectPrevItem() setSelectedItem(prev); prev->setFocus(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); redraw(); updateTerminal(); @@ -474,7 +1126,7 @@ bool FMenu::selectPrevItem() //---------------------------------------------------------------------- void FMenu::keypressMenuBar (FKeyEvent*& ev) { - FMenuBar* mbar = menuBar(); + FMenuBar* mbar = getMenuBar(); if ( mbar ) mbar->onKeyPress(ev); @@ -828,655 +1480,3 @@ void FMenu::processActivate() { emitCallback("activate"); } - - -// public methods of FMenu -//---------------------------------------------------------------------- -void FMenu::onKeyPress (FKeyEvent* ev) -{ - FWidget* menubar; - - // looking for menu hotkey - if ( hotkeyMenu(ev) ) - return; - - // looking for menu bar hotkey - menubar = menuBar(); - - if ( menubar ) - { - FMenuBar* mbar = reinterpret_cast(menubar); - - if ( mbar->hotkeyMenu(ev) ) - return; - } - - switch ( ev->key() ) - { - case fc::Fkey_return: - case fc::Fkey_enter: - if ( hasSelectedItem() ) - { - FMenuItem* sel_item = getSelectedItem(); - - if ( sel_item->hasMenu() ) - openSubMenu (sel_item->getMenu()); - else - { - unselectItem(); - hide(); - hideSuperMenus(); - sel_item->processClicked(); - } - } - break; - - case fc::Fkey_up: - selectPrevItem(); - break; - - case fc::Fkey_down: - selectNextItem(); - break; - - case fc::Fkey_left: - if ( isSubMenu() ) - { - FMenu* smenu = reinterpret_cast(getSuperMenu()); - hideSubMenus(); - hide(); - - if ( smenu->getSelectedItem() ) - smenu->getSelectedItem()->setFocus(); - - smenu->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); - } - else - keypressMenuBar(ev); // select previous menu - break; - - case fc::Fkey_right: - if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) - { - FMenu* sub_menu = getSelectedItem()->getMenu(); - - if ( ! sub_menu->isVisible() ) - openSubMenu (sub_menu); - else - keypressMenuBar(ev); // select next menu - } - else - keypressMenuBar(ev); // select next menu - break; - - case fc::Fkey_escape: - case fc::Fkey_escape_mintty: - unselectItem(); - hideSubMenus(); - hide(); - - if ( isSubMenu() ) - { - FMenu* smenu = reinterpret_cast(getSuperMenu()); - - if ( smenu->getSelectedItem() ) - smenu->getSelectedItem()->setFocus(); - - smenu->redraw(); - } - else - { - FWidget* super = getSuperMenu(); - hideSuperMenus(); - - if ( statusBar() ) - statusBar()->clearMessage(); - - if ( ! (super && isWindowsMenu(super)) ) - switchToPrevWindow(); - } - - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); - break; - - case fc::Fmkey_1: - case fc::Fmkey_2: - case fc::Fmkey_3: - case fc::Fmkey_4: - case fc::Fmkey_5: - case fc::Fmkey_6: - case fc::Fmkey_7: - case fc::Fmkey_8: - case fc::Fmkey_9: - // do nothing: - // handle the dialog switch accelerator in FApplication - return; - - default: - break; - } - - // always accept key event -> no forwarding to the parent widget - ev->accept(); -} - -//---------------------------------------------------------------------- -void FMenu::onMouseDown (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - { - if ( open_sub_menu ) - { - // close open sub menu - open_sub_menu->hideSubMenus(); - open_sub_menu->hide(); - open_sub_menu = 0; - - if ( getSelectedItem() ) - getSelectedItem()->setFocus(); - - redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); - } - - return; - } - - if ( mouse_down ) - return; - - if ( ! isWindowActive() ) - setActiveWindow(this); - - mouse_down = true; - - if ( ! item_list.empty() ) - { - std::vector::const_iterator iter, end; - FMenu* show_sub_menu = 0; - bool focus_changed = false; - FPoint mouse_pos; - - iter = item_list.begin(); - end = item_list.end(); - mouse_pos = ev->getPos(); - mouse_pos -= FPoint(getRightPadding(),getTopPadding()); - - while ( iter != end ) - { - int x1, x2, y, mouse_x, mouse_y; - x1 = (*iter)->getX(); - x2 = (*iter)->getX() + (*iter)->getWidth(); - y = (*iter)->getY(); - mouse_x = mouse_pos.getX(); - mouse_y = mouse_pos.getY(); - - if ( mouse_x >= x1 - && mouse_x < x2 - && mouse_y == y ) - { - // Mouse pointer over item - if ( hasSelectedItem() ) - { - FMenuItem* sel_item = getSelectedItem(); - if ( sel_item - && sel_item->hasMenu() - && sel_item->getMenu() == open_sub_menu ) - { - if ( sel_item != *iter ) - hideSubMenus(); - else - { - open_sub_menu->unselectItem(); - raiseWindow (open_sub_menu); - open_sub_menu->redraw(); - sel_item->setFocus(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); - } - } - } - - if ( ! (*iter)->isSelected() ) - { - unselectItem(); - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - (*iter)->setSelected(); - setSelectedItem(*iter); - (*iter)->setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - if ( (*iter)->hasMenu() ) - { - FMenu* sub_menu = (*iter)->getMenu(); - if ( ! sub_menu->isVisible() ) - show_sub_menu = sub_menu; - } - - focus_changed = true; - } - } - - ++iter; - } - - if ( focus_changed ) - redraw(); - - if ( show_sub_menu ) - { - // open sub menu - show_sub_menu->setVisible(); - show_sub_menu->show(); - open_sub_menu = show_sub_menu; - raiseWindow (show_sub_menu); - show_sub_menu->redraw(); - updateTerminal(); - flush_out(); - } - } -} - -//---------------------------------------------------------------------- -void FMenu::onMouseUp (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( mouse_down ) - { - mouse_down = false; - - if ( ! item_list.empty() ) - { - std::vector::const_iterator iter, end; - FPoint mouse_pos; - iter = item_list.begin(); - end = item_list.end(); - mouse_pos = ev->getPos(); - mouse_pos -= FPoint(getRightPadding(),getTopPadding()); - - while ( iter != end ) - { - int x1, x2, y; - x1 = (*iter)->getX(); - x2 = (*iter)->getX() + (*iter)->getWidth(); - y = (*iter)->getY(); - - if ( (*iter)->isSelected() ) - { - int mouse_x = mouse_pos.getX(); - int mouse_y = mouse_pos.getY(); - - if ( mouse_x >= x1 - && mouse_x < x2 - && mouse_y == y ) - { - // Mouse pointer over item - if ( (*iter)->hasMenu() ) - { - FMenu* sub_menu = (*iter)->getMenu(); - if ( ! sub_menu->isVisible() ) - openSubMenu (sub_menu); - else if ( open_sub_menu ) - { - open_sub_menu->selectFirstItem(); - - if ( open_sub_menu->hasSelectedItem() ) - open_sub_menu->getSelectedItem()->setFocus(); - - open_sub_menu->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - updateTerminal(); - flush_out(); - } - - return; - } - else - { - unselectItem(); - hide(); - hideSuperMenus(); - (*iter)->processClicked(); - } - } - } - - ++iter; - } - - // Click on a non-FMenuItem (border or separator line) - unselectItem(); - hide(); - hideSuperMenus(); - } - } -} - -//---------------------------------------------------------------------- -void FMenu::onMouseMove (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( ! isWindowActive() ) - setActiveWindow(this); - - if ( mouse_down && ! item_list.empty() ) - { - std::vector::const_iterator iter, end; - FMenu* smenu = 0; - bool focus_changed = false; - bool mouse_over_menu = false; - bool mouse_over_submenu = false; - bool mouse_over_supermenu = false; - bool mouse_over_menubar = false; - bool hide_sub_menu = false; - FMenu* show_sub_menu = 0; - FPoint mouse_pos; - - iter = item_list.begin(); - end = item_list.end(); - mouse_pos = ev->getPos(); - mouse_pos -= FPoint(getRightPadding(),getTopPadding()); - - if ( getTermGeometry().contains(ev->getTermPos()) ) - mouse_over_menu = true; - - if ( open_sub_menu ) - { - const FRect& submenu_geometry = open_sub_menu->getTermGeometry(); - if ( submenu_geometry.contains(ev->getTermPos()) ) - mouse_over_submenu = true; - } - - if ( isSubMenu() ) - { - smenu = superMenuAt (ev->getTermPos()); - - if ( smenu ) - mouse_over_supermenu = true; - } - - if ( menuBar() - && isMenuBar(menuBar()) - && menuBar()->getTermGeometry().contains(ev->getTermPos()) ) - { - mouse_over_menubar = true; - } - - while ( iter != end ) - { - int x1, x2, y, mouse_x, mouse_y; - x1 = (*iter)->getX(); - x2 = (*iter)->getX() + (*iter)->getWidth(); - y = (*iter)->getY(); - mouse_x = mouse_pos.getX(); - mouse_y = mouse_pos.getY(); - - if ( mouse_x >= x1 - && mouse_x < x2 - && mouse_y == y ) - { - if ( (*iter)->isEnabled() - && ! (*iter)->isSelected() - && ! (*iter)->isSeparator() ) - { - // Mouse pointer over item - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - (*iter)->setSelected(); - setSelectedItem(*iter); - (*iter)->setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - // sub menu handling - if ( (*iter)->hasMenu() ) - { - FMenu* sub_menu = (*iter)->getMenu(); - - if ( ! sub_menu->isVisible() ) - show_sub_menu = sub_menu; - } - else if ( open_sub_menu ) - hide_sub_menu = true; - - focus_changed = true; - } - } - else - { - if ( mouse_over_menu - && (*iter)->isEnabled() - && (*iter)->isSelected() - && ! mouse_over_submenu ) - { - // Unselect selected item without mouse focus - (*iter)->unsetSelected(); - - if ( getSelectedItem() == *iter ) - setSelectedItem(0); - - focus_changed = true; - } - } - - ++iter; - } - - if ( mouse_over_submenu ) - { - // Mouse event handover to sub-menu - const FPoint& t = ev->getTermPos(); - const FPoint& p = open_sub_menu->termToWidgetPos(t); - int b = ev->getButton(); - FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); - open_sub_menu->mouse_down = true; - setClickedWidget(open_sub_menu); - open_sub_menu->onMouseMove(_ev); - delete _ev; - return; - } - else if ( ! mouse_over_menu && mouse_over_supermenu ) - { - // Mouse event handover to super-menu - const FPoint& t = ev->getTermPos(); - const FPoint& p = smenu->termToWidgetPos(t); - int b = ev->getButton(); - FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); - smenu->mouse_down = true; - setClickedWidget(smenu); - smenu->onMouseMove(_ev); - delete _ev; - return; - } - else if ( mouse_over_menubar ) - { - // Mouse event handover to the menu bar - FWidget* menubar = menuBar(); - const FPoint& t = ev->getTermPos(); - const FPoint& p = menubar->termToWidgetPos(t); - int b = ev->getButton(); - FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); - setClickedWidget(menubar); - FMenuBar* mbar = reinterpret_cast(menubar); - mbar->mouse_down = true; - mbar->onMouseMove(_ev); - delete _ev; - return; - } - else if ( ! hasSelectedItem() && mouse_over_menu ) - { - // Mouse is over border or separator - if ( statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) - if ( curMsg != msg ) - { - statusBar()->setMessage(msg); - statusBar()->drawMessage(); - } - } - - if ( open_sub_menu ) - hide_sub_menu = true; - } - - if ( focus_changed ) - redraw(); - - if ( show_sub_menu ) - { - // close open sub menu - if ( open_sub_menu ) - { - open_sub_menu->hideSubMenus(); - open_sub_menu->hide(); - } - - // open sub menu - show_sub_menu->setVisible(); - show_sub_menu->show(); - open_sub_menu = show_sub_menu; - raiseWindow (show_sub_menu); - show_sub_menu->redraw(); - updateTerminal(); - flush_out(); - } - else if ( hide_sub_menu ) - { - open_sub_menu->hideSubMenus(); - open_sub_menu->hide(); - open_sub_menu = 0; - updateTerminal(); - flush_out(); - } - } -} - -//---------------------------------------------------------------------- -void FMenu::show() -{ - if ( ! isVisible() ) - return; - - FWindow::show(); -} - -//---------------------------------------------------------------------- -void FMenu::hide() -{ - if ( isVisible() ) - { - FWindow::hide(); - const FRect& t_geometry = getTermGeometryWithShadow(); - restoreVTerm (t_geometry); - updateTerminal(); - flush_out(); - - if ( ! isSubMenu() ) - { - FMenu* open_menu = static_cast(getOpenMenu()); - - if ( open_menu && open_menu != this ) - open_menu->hide(); - - setOpenMenu(0); - } - - mouse_down = false; - } -} - -//---------------------------------------------------------------------- -void FMenu::setStatusbarMessage(FString msg) -{ - FWidget::setStatusbarMessage(msg); - - if ( item ) - item->setStatusbarMessage(msg); -} - -//---------------------------------------------------------------------- -void FMenu::cb_menuitem_toggled (FWidget* widget, void*) -{ - FMenuItem* menuitem = static_cast(widget); - std::vector::const_iterator iter, end; - - if ( ! has_checkable_items ) - return; - - if ( ! menuitem->isChecked() ) - return; - - if ( item_list.empty() ) - return; - - iter = item_list.begin(); - end = item_list.end(); - - while ( iter != end ) - { - if ( (*iter) != menuitem - && (*iter)->isChecked() - && isRadioMenuItem(*iter) ) - { - (*iter)->unsetChecked(); - } - - ++iter; - } -} - -//---------------------------------------------------------------------- -bool FMenu::setMenuWidget (bool on) -{ - if ( isMenuWidget() == on ) - return true; - - if ( on ) - flags |= fc::menu_widget; - else - flags &= ~fc::menu_widget; - - return on; -} diff --git a/src/fmenu.h b/src/fmenu.h index a802cd6b..7c97faef 100644 --- a/src/fmenu.h +++ b/src/fmenu.h @@ -40,6 +40,7 @@ #include "fmenulist.h" #include "fmenuitem.h" + //---------------------------------------------------------------------- // class FMenu //---------------------------------------------------------------------- @@ -49,31 +50,82 @@ class FMenu : public FWindow, public FMenuList { - private: - FMenuItem* item; - FWidget* super_menu; - FMenu* open_sub_menu; - uInt max_item_width; - bool mouse_down; - bool has_checkable_items; + public: + // Constructor + explicit FMenu (FWidget* = 0); + FMenu (FString&, FWidget* = 0); + FMenu (const std::string&, FWidget* = 0); + FMenu (const char*, FWidget* = 0); + + // Destructor + virtual ~FMenu(); + + // Accessors + virtual const char* getClassName() const; + FString getText() const; + FMenuItem* getItem() const; + + // Mutators + bool setEnable(bool); + bool setEnable(); + bool unsetEnable(); + bool setDisable(); + void setSelected(); + void unsetSelected(); + bool setMenuWidget (bool); + bool setMenuWidget(); + bool unsetMenuWidget(); + void setStatusbarMessage (FString); + void setMenu (FMenu*); + void setText (FString&); + void setText (const std::string&); + void setText (const char*); + + // Inquiries + bool isEnabled() const; + bool isSelected() const; + bool hasHotkey() const; + bool hasMenu() const; + + // Methods + void show(); + void hide(); + + // Event handlers + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onAccel (FAccelEvent*); + + // Callback method + void cb_menuitem_toggled (FWidget*, void*); private: // Disable copy constructor FMenu (const FMenu&); + // Disable assignment operator (=) FMenu& operator = (const FMenu&); - void init(FWidget*); - void calculateDimensions(); - void adjustItems(); - int adjustX(int); + // Accessors + FWidget* getSuperMenu() const; + + // Mutators + void setSuperMenu (FWidget*); + + // Inquiries bool isWindowsMenu (FWidget*) const; bool isMenuBar (FWidget*) const; bool isMenu (FWidget*) const; bool isRadioMenuItem (FWidget*) const; - FWidget* getSuperMenu() const; - void setSuperMenu (FWidget*); bool isSubMenu() const; + + // Methods + void init(FWidget*); + void calculateDimensions(); + void adjustItems(); + int adjustX(int); void openSubMenu (FMenu*); void hideSubMenus(); void hideSuperMenus(); @@ -91,94 +143,38 @@ class FMenu : public FWindow, public FMenuList void drawSeparator(int); void processActivate(); - public: - // Constructor - explicit FMenu (FWidget* = 0); - FMenu (FString&, FWidget* = 0); - FMenu (const std::string&, FWidget* = 0); - FMenu (const char*, FWidget* = 0); - // Destructor - virtual ~FMenu(); - - virtual const char* getClassName() const; - - // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onAccel (FAccelEvent*); - - void show(); - void hide(); - void setStatusbarMessage (FString); - FMenuItem* getItem() const; - FString getText() const; - bool setEnable(bool); - bool setEnable(); - bool unsetEnable(); - bool setDisable(); - bool isEnabled() const; - void setSelected(); - void unsetSelected(); - bool isSelected() const; - bool setMenuWidget (bool); - bool setMenuWidget(); - bool unsetMenuWidget(); - bool hasHotkey() const; - void setMenu (FMenu*); - bool hasMenu() const; - void setText (FString&); - void setText (const std::string&); - void setText (const char*); - - // Callback method - void cb_menuitem_toggled (FWidget*, void*); - - private: + // Friend classes friend class FApplication; friend class FCheckMenuItem; friend class FDialog; friend class FMenuBar; friend class FMenuItem; friend class FRadioMenuItem; + + // Data Members + FMenuItem* item; + FWidget* super_menu; + FMenu* open_sub_menu; + uInt max_item_width; + bool mouse_down; + bool has_checkable_items; }; #pragma pack(pop) // FMenu inline functions -//---------------------------------------------------------------------- -inline FWidget* FMenu::getSuperMenu() const -{ return super_menu; } - -//---------------------------------------------------------------------- -inline void FMenu::setSuperMenu (FWidget* smenu) -{ super_menu = smenu; } - -//---------------------------------------------------------------------- -inline bool FMenu::containsMenuStructure (const FPoint& p) -{ return containsMenuStructure (p.getX(), p.getY()); } - -//---------------------------------------------------------------------- -inline FMenu* FMenu::superMenuAt (const FPoint& p) -{ return superMenuAt (p.getX(), p.getY()); } - //---------------------------------------------------------------------- inline const char* FMenu::getClassName() const { return "FMenu"; } //---------------------------------------------------------------------- -inline void FMenu::onAccel (FAccelEvent* ev) -{ item->onAccel(ev); } +inline FString FMenu::getText() const +{ return item->getText(); } //---------------------------------------------------------------------- inline FMenuItem* FMenu::getItem() const { return item; } -//---------------------------------------------------------------------- -inline FString FMenu::getText() const -{ return item->getText(); } - //---------------------------------------------------------------------- inline bool FMenu::setEnable(bool on) { return item->setEnable(on); } @@ -195,10 +191,6 @@ inline bool FMenu::unsetEnable() inline bool FMenu::setDisable() { return item->setDisable(); } -//---------------------------------------------------------------------- -inline bool FMenu::isEnabled() const -{ return item->isEnabled(); } - //---------------------------------------------------------------------- inline void FMenu::setSelected() { item->setSelected(); } @@ -207,9 +199,6 @@ inline void FMenu::setSelected() inline void FMenu::unsetSelected() { item->unsetSelected(); } -//---------------------------------------------------------------------- -inline bool FMenu::isSelected() const -{ return item->isSelected(); } //---------------------------------------------------------------------- inline bool FMenu::setMenuWidget() { return setMenuWidget(true); } @@ -218,18 +207,10 @@ inline bool FMenu::setMenuWidget() inline bool FMenu::unsetMenuWidget() { return setMenuWidget(false); } -//---------------------------------------------------------------------- -inline bool FMenu::hasHotkey() const -{ return item->hasHotkey(); } - //---------------------------------------------------------------------- inline void FMenu::setMenu (FMenu* m) { item->setMenu(m); } -//---------------------------------------------------------------------- -inline bool FMenu::hasMenu() const -{ return item->hasMenu(); } - //---------------------------------------------------------------------- inline void FMenu::setText (FString& txt) { item->setText(txt); } @@ -242,5 +223,41 @@ inline void FMenu::setText (const std::string& txt) inline void FMenu::setText (const char* txt) { item->setText(txt); } +//---------------------------------------------------------------------- +inline bool FMenu::isEnabled() const +{ return item->isEnabled(); } + +//---------------------------------------------------------------------- +inline bool FMenu::isSelected() const +{ return item->isSelected(); } + +//---------------------------------------------------------------------- +inline bool FMenu::hasHotkey() const +{ return item->hasHotkey(); } + +//---------------------------------------------------------------------- +inline bool FMenu::hasMenu() const +{ return item->hasMenu(); } + +//---------------------------------------------------------------------- +inline FWidget* FMenu::getSuperMenu() const +{ return super_menu; } + +//---------------------------------------------------------------------- +inline void FMenu::setSuperMenu (FWidget* smenu) +{ super_menu = smenu; } + +//---------------------------------------------------------------------- +inline bool FMenu::containsMenuStructure (const FPoint& p) +{ return containsMenuStructure (p.getX(), p.getY()); } + +//---------------------------------------------------------------------- +inline FMenu* FMenu::superMenuAt (const FPoint& p) +{ return superMenuAt (p.getX(), p.getY()); } + +//---------------------------------------------------------------------- +inline void FMenu::onAccel (FAccelEvent* ev) +{ item->onAccel(ev); } + #endif // _FMENU_H diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index c0e65d6b..e0baa079 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -26,6 +26,443 @@ FMenuBar::~FMenuBar() } +// public methods of FMenuBar +//---------------------------------------------------------------------- +void FMenuBar::hide() +{ + int screenWidth; + short fg, bg; + char* blank; + + FWindow::hide(); + fg = wc.term_fg; + bg = wc.term_bg; + setColor (fg, bg); + screenWidth = getColumnNumber(); + + if ( screenWidth < 0 ) + return; + + blank = new char[screenWidth+1]; + std::memset(blank, ' ', uLong(screenWidth)); + blank[screenWidth] = '\0'; + setPrintPos (1,1); + print (blank); + delete[] blank; +} + +//---------------------------------------------------------------------- +void FMenuBar::resetMenu() +{ + unselectItem(); + drop_down = false; +} + +//---------------------------------------------------------------------- +void FMenuBar::adjustSize() +{ + setGeometry (1, 1, getColumnNumber(), 1, false); + adjustItems(); +} + +//---------------------------------------------------------------------- +void FMenuBar::onKeyPress (FKeyEvent* ev) +{ + switch ( ev->key() ) + { + case fc::Fkey_return: + case fc::Fkey_enter: + case fc::Fkey_up: + case fc::Fkey_down: + if ( hasSelectedItem() ) + { + FMenuItem* sel_item = getSelectedItem(); + + if ( sel_item->hasMenu() ) + { + FMenuItem* first_item; + FMenu* menu = sel_item->getMenu(); + sel_item->openMenu(); + menu->selectFirstItem(); + first_item = menu->getSelectedItem(); + + if ( first_item ) + first_item->setFocus(); + + menu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + redraw(); + drop_down = true; + } + else if ( ev->key() == fc::Fkey_return + || ev->key() == fc::Fkey_enter ) + { + unselectItem(); + redraw(); + sel_item->processClicked(); + } + } + + ev->accept(); + break; + + case fc::Fkey_left: + selectPrevItem(); + ev->accept(); + break; + + case fc::Fkey_right: + selectNextItem(); + ev->accept(); + break; + + case fc::Fkey_escape: + case fc::Fkey_escape_mintty: + leaveMenuBar(); + ev->accept(); + break; + + default: + break; + } +} + +//---------------------------------------------------------------------- +void FMenuBar::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + { + mouse_down = false; + + if ( ! item_list.empty() && hasSelectedItem() ) + leaveMenuBar(); + else + return; + + if ( getStatusBar() ) + getStatusBar()->clearMessage(); + + return; + } + + if ( mouse_down ) + return; + + mouse_down = true; + + if ( ! isWindowActive() ) + setActiveWindow(this); + + if ( ! item_list.empty() ) + { + std::vector::const_iterator iter, end; + int mouse_x, mouse_y; + bool focus_changed = false; + + iter = item_list.begin(); + end = item_list.end(); + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + while ( iter != end ) + { + int x1, x2; + x1 = (*iter)->getX(); + x2 = (*iter)->getX() + (*iter)->getWidth(); + + if ( mouse_y == 1 ) + { + if ( mouse_x >= x1 && mouse_x < x2 ) + { + // Mouse pointer over item + if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) + { + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + (*iter)->setSelected(); + (*iter)->setFocus(); + + if ( focused_widget && ! focused_widget->isWindowWidget() ) + focused_widget->redraw(); + + (*iter)->openMenu(); + setSelectedItem(*iter); + focus_changed = true; + + if ( (*iter)->hasMenu() ) + { + FMenu* menu = (*iter)->getMenu(); + + if ( menu->hasSelectedItem() ) + { + menu->unselectItem(); + menu->redraw(); + drop_down = true; + } + } + } + } + else if ( (*iter)->isEnabled() && (*iter)->isSelected() ) + { + (*iter)->unsetSelected(); + + if ( getSelectedItem() == *iter ) + setSelectedItem(0); + + focus_changed = true; + } + } + + ++iter; + } + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + if ( focus_changed ) + { + redraw(); + updateTerminal(); + } + } +} + +//---------------------------------------------------------------------- +void FMenuBar::onMouseUp (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( mouse_down ) + { + mouse_down = false; + + if ( ! item_list.empty() ) + { + int mouse_x, mouse_y; + std::vector::const_iterator iter, end; + iter = item_list.begin(); + end = item_list.end(); + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + while ( iter != end ) + { + int x1, x2; + x1 = (*iter)->getX(); + x2 = (*iter)->getX() + (*iter)->getWidth(); + + if ( mouse_y == 1 ) + { + if ( (*iter)->isEnabled() && (*iter)->isSelected() ) + { + if ( mouse_x >= x1 && mouse_x < x2 ) + { + // Mouse pointer over item + if ( (*iter)->hasMenu() ) + { + FMenu* menu = (*iter)->getMenu(); + + if ( ! menu->hasSelectedItem() ) + { + FMenuItem* first_item; + menu->selectFirstItem(); + first_item = menu->getSelectedItem(); + + if ( first_item ) + first_item->setFocus(); + + menu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + redraw(); + drop_down = true; + } + } + else + { + (*iter)->unsetSelected(); + + if ( getSelectedItem() == *iter ) + { + setSelectedItem(0); + leaveMenuBar(); + drop_down = false; + (*iter)->processClicked(); + return; + } + } + } + else + { + (*iter)->unsetSelected(); + + if ( getSelectedItem() == *iter ) + setSelectedItem(0); + + redraw(); + } + } + } + + ++iter; + } + + if ( ! hasSelectedItem() ) + leaveMenuBar(); + } + } +} + +//---------------------------------------------------------------------- +void FMenuBar::onMouseMove (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( ! isWindowActive() ) + setActiveWindow(this); + + if ( mouse_down && ! item_list.empty() ) + { + std::vector::const_iterator iter, end; + int mouse_x, mouse_y; + bool mouse_over_menubar = false; + bool focus_changed = false; + iter = item_list.begin(); + end = item_list.end(); + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( getTermGeometry().contains(ev->getTermPos()) ) + mouse_over_menubar = true; + + while ( iter != end ) + { + int x1, x2; + x1 = (*iter)->getX(); + x2 = (*iter)->getX() + (*iter)->getWidth(); + + if ( mouse_x >= x1 + && mouse_x < x2 + && mouse_y == 1 ) + { + // Mouse pointer over item + if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) + { + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + (*iter)->setSelected(); + (*iter)->setFocus(); + + if ( focused_widget && ! focused_widget->isWindowWidget() ) + focused_widget->redraw(); + + (*iter)->openMenu(); + setSelectedItem(*iter); + focus_changed = true; + + if ( (*iter)->hasMenu() ) + { + FMenu* menu = (*iter)->getMenu(); + + if ( menu->hasSelectedItem() ) + { + menu->unselectItem(); + menu->redraw(); + drop_down = true; + } + } + } + else if ( getStatusBar() ) + getStatusBar()->clearMessage(); + } + else + { + if ( mouse_over_menubar + && (*iter)->isEnabled() + && (*iter)->isSelected() ) + { + // Unselect selected item without mouse focus + (*iter)->unsetSelected(); + + if ( getSelectedItem() == *iter ) + setSelectedItem(0); + + focus_changed = true; + drop_down = false; + } + else if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) + { + // Mouse event handover to the menu + FMenu* menu = getSelectedItem()->getMenu(); + const FRect& menu_geometry = menu->getTermGeometry(); + + if ( menu->getCount() > 0 + && menu_geometry.contains(ev->getTermPos()) ) + { + FMouseEvent* _ev; + const FPoint& t = ev->getTermPos(); + const FPoint& p = menu->termToWidgetPos(t); + int b = ev->getButton(); + _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); + menu->mouse_down = true; + setClickedWidget(menu); + menu->onMouseMove(_ev); + delete _ev; + } + } + } + + ++iter; + } + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + if ( focus_changed ) + { + redraw(); + updateTerminal(); + } + } +} + +//---------------------------------------------------------------------- +void FMenuBar::onAccel (FAccelEvent* ev) +{ + unselectItem(); + selectFirstItem(); + getSelectedItem()->setFocus(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + redraw(); + ev->accept(); +} + +//---------------------------------------------------------------------- +void FMenuBar::cb_item_deactivated (FWidget* widget, void*) +{ + FMenuItem* menuitem = static_cast(widget); + + if ( menuitem->hasMenu() ) + { + FMenu* menu = menuitem->getMenu(); + menu->hide(); + menu->hideSubMenus(); + } +} + + // private methods of FMenuBar //---------------------------------------------------------------------- void FMenuBar::init() @@ -76,12 +513,6 @@ void FMenuBar::calculateDimensions() } } -//---------------------------------------------------------------------- -bool FMenuBar::isMenu (FMenuItem* mi) const -{ - return mi->hasMenu(); -} - //---------------------------------------------------------------------- bool FMenuBar::selectNextItem() { @@ -132,8 +563,8 @@ bool FMenuBar::selectNextItem() menu->redraw(); } - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); redraw(); break; @@ -196,8 +627,8 @@ bool FMenuBar::selectPrevItem() menu->redraw(); } - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); setSelectedItem(prev); redraw(); @@ -248,8 +679,8 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev) menu->redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); redraw(); drop_down = true; @@ -494,452 +925,15 @@ void FMenuBar::leaveMenuBar() resetMenu(); redraw(); - if ( statusBar() ) - statusBar()->clearMessage(); + if ( getStatusBar() ) + getStatusBar()->clearMessage(); switchToPrevWindow(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); mouse_down = false; } - -// public methods of FMenuBar -//---------------------------------------------------------------------- -void FMenuBar::onKeyPress (FKeyEvent* ev) -{ - switch ( ev->key() ) - { - case fc::Fkey_return: - case fc::Fkey_enter: - case fc::Fkey_up: - case fc::Fkey_down: - if ( hasSelectedItem() ) - { - FMenuItem* sel_item = getSelectedItem(); - - if ( sel_item->hasMenu() ) - { - FMenuItem* first_item; - FMenu* menu = sel_item->getMenu(); - sel_item->openMenu(); - menu->selectFirstItem(); - first_item = menu->getSelectedItem(); - - if ( first_item ) - first_item->setFocus(); - - menu->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - redraw(); - drop_down = true; - } - else if ( ev->key() == fc::Fkey_return - || ev->key() == fc::Fkey_enter ) - { - unselectItem(); - redraw(); - sel_item->processClicked(); - } - } - - ev->accept(); - break; - - case fc::Fkey_left: - selectPrevItem(); - ev->accept(); - break; - - case fc::Fkey_right: - selectNextItem(); - ev->accept(); - break; - - case fc::Fkey_escape: - case fc::Fkey_escape_mintty: - leaveMenuBar(); - ev->accept(); - break; - - default: - break; - } -} - -//---------------------------------------------------------------------- -void FMenuBar::onMouseDown (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - { - mouse_down = false; - - if ( ! item_list.empty() && hasSelectedItem() ) - leaveMenuBar(); - else - return; - - if ( statusBar() ) - statusBar()->clearMessage(); - - return; - } - - if ( mouse_down ) - return; - - mouse_down = true; - - if ( ! isWindowActive() ) - setActiveWindow(this); - - if ( ! item_list.empty() ) - { - std::vector::const_iterator iter, end; - int mouse_x, mouse_y; - bool focus_changed = false; - - iter = item_list.begin(); - end = item_list.end(); - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - while ( iter != end ) - { - int x1, x2; - x1 = (*iter)->getX(); - x2 = (*iter)->getX() + (*iter)->getWidth(); - - if ( mouse_y == 1 ) - { - if ( mouse_x >= x1 && mouse_x < x2 ) - { - // Mouse pointer over item - if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) - { - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - (*iter)->setSelected(); - (*iter)->setFocus(); - - if ( focused_widget && ! focused_widget->isWindowWidget() ) - focused_widget->redraw(); - - (*iter)->openMenu(); - setSelectedItem(*iter); - focus_changed = true; - - if ( (*iter)->hasMenu() ) - { - FMenu* menu = (*iter)->getMenu(); - - if ( menu->hasSelectedItem() ) - { - menu->unselectItem(); - menu->redraw(); - drop_down = true; - } - } - } - } - else if ( (*iter)->isEnabled() && (*iter)->isSelected() ) - { - (*iter)->unsetSelected(); - - if ( getSelectedItem() == *iter ) - setSelectedItem(0); - - focus_changed = true; - } - } - - ++iter; - } - - if ( statusBar() ) - statusBar()->drawMessage(); - - if ( focus_changed ) - { - redraw(); - updateTerminal(); - } - } -} - -//---------------------------------------------------------------------- -void FMenuBar::onMouseUp (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( mouse_down ) - { - mouse_down = false; - - if ( ! item_list.empty() ) - { - int mouse_x, mouse_y; - std::vector::const_iterator iter, end; - iter = item_list.begin(); - end = item_list.end(); - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - while ( iter != end ) - { - int x1, x2; - x1 = (*iter)->getX(); - x2 = (*iter)->getX() + (*iter)->getWidth(); - - if ( mouse_y == 1 ) - { - if ( (*iter)->isEnabled() && (*iter)->isSelected() ) - { - if ( mouse_x >= x1 && mouse_x < x2 ) - { - // Mouse pointer over item - if ( (*iter)->hasMenu() ) - { - FMenu* menu = (*iter)->getMenu(); - - if ( ! menu->hasSelectedItem() ) - { - FMenuItem* first_item; - menu->selectFirstItem(); - first_item = menu->getSelectedItem(); - - if ( first_item ) - first_item->setFocus(); - - menu->redraw(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - redraw(); - drop_down = true; - } - } - else - { - (*iter)->unsetSelected(); - - if ( getSelectedItem() == *iter ) - { - setSelectedItem(0); - leaveMenuBar(); - drop_down = false; - (*iter)->processClicked(); - return; - } - } - } - else - { - (*iter)->unsetSelected(); - - if ( getSelectedItem() == *iter ) - setSelectedItem(0); - - redraw(); - } - } - } - - ++iter; - } - - if ( ! hasSelectedItem() ) - leaveMenuBar(); - } - } -} - -//---------------------------------------------------------------------- -void FMenuBar::onMouseMove (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( ! isWindowActive() ) - setActiveWindow(this); - - if ( mouse_down && ! item_list.empty() ) - { - std::vector::const_iterator iter, end; - int mouse_x, mouse_y; - bool mouse_over_menubar = false; - bool focus_changed = false; - iter = item_list.begin(); - end = item_list.end(); - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( getTermGeometry().contains(ev->getTermPos()) ) - mouse_over_menubar = true; - - while ( iter != end ) - { - int x1, x2; - x1 = (*iter)->getX(); - x2 = (*iter)->getX() + (*iter)->getWidth(); - - if ( mouse_x >= x1 - && mouse_x < x2 - && mouse_y == 1 ) - { - // Mouse pointer over item - if ( (*iter)->isEnabled() && ! (*iter)->isSelected() ) - { - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - (*iter)->setSelected(); - (*iter)->setFocus(); - - if ( focused_widget && ! focused_widget->isWindowWidget() ) - focused_widget->redraw(); - - (*iter)->openMenu(); - setSelectedItem(*iter); - focus_changed = true; - - if ( (*iter)->hasMenu() ) - { - FMenu* menu = (*iter)->getMenu(); - - if ( menu->hasSelectedItem() ) - { - menu->unselectItem(); - menu->redraw(); - drop_down = true; - } - } - } - else if ( statusBar() ) - statusBar()->clearMessage(); - } - else - { - if ( mouse_over_menubar - && (*iter)->isEnabled() - && (*iter)->isSelected() ) - { - // Unselect selected item without mouse focus - (*iter)->unsetSelected(); - - if ( getSelectedItem() == *iter ) - setSelectedItem(0); - - focus_changed = true; - drop_down = false; - } - else if ( hasSelectedItem() && getSelectedItem()->hasMenu() ) - { - // Mouse event handover to the menu - FMenu* menu = getSelectedItem()->getMenu(); - const FRect& menu_geometry = menu->getTermGeometry(); - - if ( menu->count() > 0 - && menu_geometry.contains(ev->getTermPos()) ) - { - FMouseEvent* _ev; - const FPoint& t = ev->getTermPos(); - const FPoint& p = menu->termToWidgetPos(t); - int b = ev->getButton(); - _ev = new FMouseEvent (fc::MouseMove_Event, p, t, b); - menu->mouse_down = true; - setClickedWidget(menu); - menu->onMouseMove(_ev); - delete _ev; - } - } - } - - ++iter; - } - - if ( statusBar() ) - statusBar()->drawMessage(); - - if ( focus_changed ) - { - redraw(); - updateTerminal(); - } - } -} - -//---------------------------------------------------------------------- -void FMenuBar::onAccel (FAccelEvent* ev) -{ - unselectItem(); - selectFirstItem(); - getSelectedItem()->setFocus(); - - if ( statusBar() ) - statusBar()->drawMessage(); - - redraw(); - ev->accept(); -} - -//---------------------------------------------------------------------- -void FMenuBar::hide() -{ - int screenWidth; - short fg, bg; - char* blank; - - FWindow::hide(); - fg = wc.term_fg; - bg = wc.term_bg; - setColor (fg, bg); - screenWidth = getColumnNumber(); - - if ( screenWidth < 0 ) - return; - - blank = new char[screenWidth+1]; - std::memset(blank, ' ', uLong(screenWidth)); - blank[screenWidth] = '\0'; - setPrintPos (1,1); - print (blank); - delete[] blank; -} - -//---------------------------------------------------------------------- -void FMenuBar::resetMenu() -{ - unselectItem(); - drop_down = false; -} - -//---------------------------------------------------------------------- -void FMenuBar::adjustSize() -{ - setGeometry (1, 1, getColumnNumber(), 1, false); - adjustItems(); -} - -//---------------------------------------------------------------------- -void FMenuBar::cb_item_deactivated (FWidget* widget, void*) -{ - FMenuItem* menuitem = static_cast(widget); - - if ( menuitem->hasMenu() ) - { - FMenu* menu = menuitem->getMenu(); - menu->hide(); - menu->hideSubMenus(); - } -} - diff --git a/src/fmenubar.h b/src/fmenubar.h index 8bcd807d..72fdf399 100644 --- a/src/fmenubar.h +++ b/src/fmenubar.h @@ -49,53 +49,60 @@ class FMenuBar : public FWindow, public FMenuList { - private: - bool mouse_down; - bool drop_down; + public: + // Constructor + explicit FMenuBar (FWidget* = 0); + + // Destructor + virtual ~FMenuBar(); + + // Accessors + virtual const char* getClassName() const; + + // Methods + void hide(); + void resetMenu(); + void adjustSize(); + + // Event handlers + void onKeyPress (FKeyEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onAccel (FAccelEvent*); + + // Callback methods + void cb_item_deactivated (FWidget*, void*); private: // Disable copy constructor FMenuBar (const FMenuBar&); + // Disable assignment operator (=) - FMenuBar& operator = (const FMenuBar&); + FMenuBar& operator = (const FMenuBar&); - void init(); - void calculateDimensions(); - bool isMenu (FMenuItem*) const; - bool selectNextItem(); - bool selectPrevItem(); - bool hotkeyMenu (FKeyEvent*&); - int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); - void draw(); - void drawItems(); - void adjustItems(); - void leaveMenuBar(); + // Inquiry + bool isMenu (FMenuItem*) const; - public: - // Constructor - explicit FMenuBar (FWidget* = 0); - // Destructor - virtual ~FMenuBar(); + // Methods + void init(); + void calculateDimensions(); + bool selectNextItem(); + bool selectPrevItem(); + bool hotkeyMenu (FKeyEvent*&); + int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); + void draw(); + void drawItems(); + void adjustItems(); + void leaveMenuBar(); - virtual const char* getClassName() const; - - // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onAccel (FAccelEvent*); - - void hide(); - void resetMenu(); - void adjustSize(); - - // Callback methods - void cb_item_deactivated (FWidget*, void*); - - private: + // Friend classes friend class FMenu; friend class FMenuItem; + + // Data Members + bool mouse_down; + bool drop_down; }; #pragma pack(pop) @@ -105,4 +112,8 @@ class FMenuBar : public FWindow, public FMenuList inline const char* FMenuBar::getClassName() const { return "FMenuBar"; } +//---------------------------------------------------------------------- +inline bool FMenuBar::isMenu (FMenuItem* mi) const +{ return mi->hasMenu(); } + #endif // _FMENUBAR_H diff --git a/src/fmenuitem.cpp b/src/fmenuitem.cpp index addb8564..b662c890 100644 --- a/src/fmenuitem.cpp +++ b/src/fmenuitem.cpp @@ -165,218 +165,143 @@ FMenuItem::~FMenuItem() // destructor } -// private methods of FMenuItem +// public methods of FMenuItem //---------------------------------------------------------------------- -void FMenuItem::init (FWidget* parent) +bool FMenuItem::setEnable (bool on) { + FWidget::setEnable(on); + FWidget* super = getSuperMenu(); + + if ( on ) + { + flags |= fc::active; + + if ( super && isMenuBar(super) ) + { + // Meta + hotkey + super->addAccelerator (fc::Fmkey_meta + std::tolower(hotkey), this); + } + } + else + { + flags &= ~fc::active; + + if ( super && isMenuBar(super) ) + super->delAccelerator (this); + } + + return on; +} + +//---------------------------------------------------------------------- +bool FMenuItem::setFocus (bool on) +{ + FWidget::setFocus(on); + + if ( on ) + { + flags |= fc::focus; + + if ( isEnabled() ) + { + if ( ! selected ) + { + FMenuList* menu_list = dynamic_cast(getSuperMenu()); + setSelected(); + + if ( menu_list ) + { + menu_list->unselectItem(); + menu_list->setSelectedItem(this); + } + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + FWidget* parent = getSuperMenu(); + + if ( isMenuBar(parent) ) + { + FMenuBar* menubar_ptr = dynamic_cast(parent); + + if ( menubar_ptr ) + menubar_ptr->redraw(); + } + else if ( isMenu(parent) ) + { + FMenu* menu_ptr = dynamic_cast(parent); + + if ( menu_ptr ) + menu_ptr->redraw(); + } + } + + if ( getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + getStatusBar()->setMessage(msg); + } + } + } + else + { + flags &= ~fc::focus; + + if ( isEnabled() && getStatusBar() ) + getStatusBar()->clearMessage(); + } + + return on; +} + +//---------------------------------------------------------------------- +void FMenuItem::setSelected() +{ + if ( isEnabled() ) + { + selected = true; + processActivate(); + } +} + +//---------------------------------------------------------------------- +void FMenuItem::unsetSelected() +{ + selected = false; + processDeactivate(); +} + +//---------------------------------------------------------------------- +void FMenuItem::setText (FString& txt) +{ + text = txt; text_length = text.getLength(); hotkey = hotKey(); if ( hotkey ) text_length--; - setGeometry (1,1,int(text_length+2),1, false); - - if ( parent ) - { - FMenuList* menu_list; - setSuperMenu (parent); - - if ( accel_key ) - addAccelerator (accel_key); - - menu_list = dynamic_cast(parent); - - if ( menu_list ) - menu_list->insert(this); - - if ( isMenuBar(parent) ) // Parent is menubar - { - FMenuBar* menubar_ptr = dynamic_cast(parent); - - if ( menubar_ptr ) - { - menubar_ptr->calculateDimensions(); - - if ( hotkey ) // Meta + hotkey - menubar_ptr->addAccelerator (fc::Fmkey_meta + std::tolower(hotkey), this); - } - - this->addCallback - ( - "deactivate", - _METHOD_CALLBACK (parent, &FMenuBar::cb_item_deactivated) - ); - } - else if ( isMenu(parent) ) // Parent is menu - { - FMenu* menu_ptr = dynamic_cast(parent); - - if ( menu_ptr ) - menu_ptr->calculateDimensions(); - } - } - - if ( hasFocus() ) - flags = fc::focus; - - if ( isEnabled() ) - flags |= fc::active; + setWidth(int(text_length)); } //---------------------------------------------------------------------- -uChar FMenuItem::hotKey() +void FMenuItem::setText (const std::string& txt) { - uInt length; - - if ( text.isEmpty() ) - return 0; - - length = text.getLength(); - - for (uInt i=0; i < length; i++) - { - try - { - if ( (i+1 < length) && (text[i] == '&') ) - return uChar(text[++i]); - } - catch (const std::out_of_range&) - { - return 0;; - } - } - - return 0; + FString s = FString(txt); + setText (s); } //---------------------------------------------------------------------- -void FMenuItem::processActivate() +void FMenuItem::setText (const char* txt) { - emitCallback("activate"); + FString s = FString(txt); + setText (s); } - //---------------------------------------------------------------------- -void FMenuItem::processDeactivate() -{ - emitCallback("deactivate"); -} -//---------------------------------------------------------------------- -void FMenuItem::createDialogList (FMenu* winmenu) -{ - winmenu->clear(); - - if ( dialog_list && ! dialog_list->empty() ) - { - widgetList::const_iterator iter, begin; - iter = begin = dialog_list->begin(); - - while ( iter != dialog_list->end() && *iter ) - { - FDialog* win = dynamic_cast(*iter); - - if ( win ) - { - int n = int(std::distance(begin, iter)); - // get the dialog title - FString name = win->getText(); - // create a new dialog list item - FMenuItem* win_item = new FMenuItem (name, winmenu); - - if ( n < 9 ) - win_item->addAccelerator (fc::Fmkey_1 + n); // Meta + 1..9 - - win_item->addCallback - ( - "clicked", - _METHOD_CALLBACK (win_item, &FMenuItem::cb_switchToDialog), - dynamic_cast(win) - ); - - win->addCallback - ( - "destroy", - _METHOD_CALLBACK (win_item, &FMenuItem::cb_destroyDialog) - ); - - win_item->associated_window = win; - } - - ++iter; - } - } - - winmenu->calculateDimensions(); -} - -//---------------------------------------------------------------------- -void FMenuItem::cb_switchToDialog (FWidget*, void* data_ptr) -{ - FDialog* win = static_cast(data_ptr); - - if ( win ) - { - FWidget* focus_widget = getFocusWidget(); - FAccelEvent a_ev (fc::Accelerator_Event, focus_widget); - FApplication::sendEvent (win, &a_ev); - } -} - -//---------------------------------------------------------------------- -void FMenuItem::cb_destroyDialog (FWidget* widget, void*) -{ - FDialog* win = static_cast(widget); - FApplication* fapp = static_cast(getRootWidget()); - - if ( win && fapp ) - { - delAccelerator(win); - delCallback(win); - associated_window = 0; - } -} - -//---------------------------------------------------------------------- -void FMenuItem::processClicked() -{ - emitCallback("clicked"); -} - - -// protected methods of FMenuItem -//---------------------------------------------------------------------- -bool FMenuItem::isWindowsMenu (FWidget* w) const -{ - return ( ! w ) ? false : w->isDialogWidget(); -} - -//---------------------------------------------------------------------- -bool FMenuItem::isMenuBar (FWidget* w) const -{ - if ( ! w ) - return false; - else - return bool( std::strcmp ( w->getClassName() - , const_cast("FMenuBar") ) == 0 ); -} - -//---------------------------------------------------------------------- -bool FMenuItem::isMenu (FWidget* w) const -{ - if ( ! w ) - return false; - - bool m1 = ( std::strcmp ( w->getClassName() - , const_cast("FMenu") ) == 0 ); - bool m2 = ( std::strcmp ( w->getClassName() - , const_cast("FDialogListMenu") ) == 0 ); - return bool( m1 || m2 ); -} - - -// public methods of FMenuItem -//---------------------------------------------------------------------- void FMenuItem::addAccelerator (int key, FWidget* obj) { FWidget* root = getRootWidget(); @@ -430,6 +355,40 @@ void FMenuItem::delAccelerator (FWidget* obj) } } +//---------------------------------------------------------------------- +void FMenuItem::openMenu() +{ + FMenu* dd_menu; // Drop-down menu + FMenu* open_menu; + + if ( ! hasMenu() ) + return; + + dd_menu = getMenu(); // Drop-down menu + + if ( dd_menu->isVisible() ) + return; + + open_menu = static_cast(getOpenMenu()); + + if ( open_menu && open_menu != dd_menu ) + { + open_menu->hide(); + open_menu->hideSubMenus(); + } + + if ( dialog_index ) + createDialogList (dd_menu); + + setOpenMenu(dd_menu); + dd_menu->setVisible(); + dd_menu->show(); + dd_menu->raiseWindow(dd_menu); + dd_menu->redraw(); + updateTerminal(); + flush_out(); +} + //---------------------------------------------------------------------- void FMenuItem::onKeyPress (FKeyEvent* ev) { @@ -696,8 +655,8 @@ void FMenuItem::onAccel (FAccelEvent* ev) menu->redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); mbar->redraw(); mbar->drop_down = true; @@ -716,8 +675,8 @@ void FMenuItem::onAccel (FAccelEvent* ev) //---------------------------------------------------------------------- void FMenuItem::onFocusIn (FFocusEvent*) { - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); } //---------------------------------------------------------------------- @@ -733,178 +692,219 @@ void FMenuItem::onFocusOut (FFocusEvent*) mbar->redraw(); } - if ( statusBar() ) + if ( getStatusBar() ) { - statusBar()->clearMessage(); - statusBar()->drawMessage(); + getStatusBar()->clearMessage(); + getStatusBar()->drawMessage(); } } + +// protected methods of FMenuItem //---------------------------------------------------------------------- -bool FMenuItem::setEnable (bool on) +bool FMenuItem::isWindowsMenu (FWidget* w) const { - FWidget::setEnable(on); - FWidget* super = getSuperMenu(); + return ( ! w ) ? false : w->isDialogWidget(); +} - if ( on ) - { - flags |= fc::active; - - if ( super && isMenuBar(super) ) - { - // Meta + hotkey - super->addAccelerator (fc::Fmkey_meta + std::tolower(hotkey), this); - } - } +//---------------------------------------------------------------------- +bool FMenuItem::isMenuBar (FWidget* w) const +{ + if ( ! w ) + return false; else - { - flags &= ~fc::active; - - if ( super && isMenuBar(super) ) - super->delAccelerator (this); - } - - return on; + return bool( std::strcmp ( w->getClassName() + , const_cast("FMenuBar") ) == 0 ); } //---------------------------------------------------------------------- -bool FMenuItem::setFocus (bool on) +bool FMenuItem::isMenu (FWidget* w) const { - FWidget::setFocus(on); + if ( ! w ) + return false; - if ( on ) - { - flags |= fc::focus; - - if ( isEnabled() ) - { - if ( ! selected ) - { - FMenuList* menu_list = dynamic_cast(getSuperMenu()); - setSelected(); - - if ( menu_list ) - { - menu_list->unselectItem(); - menu_list->setSelectedItem(this); - } - - if ( statusBar() ) - statusBar()->drawMessage(); - - FWidget* parent = getSuperMenu(); - - if ( isMenuBar(parent) ) - { - FMenuBar* menubar_ptr = dynamic_cast(parent); - - if ( menubar_ptr ) - menubar_ptr->redraw(); - } - else if ( isMenu(parent) ) - { - FMenu* menu_ptr = dynamic_cast(parent); - - if ( menu_ptr ) - menu_ptr->redraw(); - } - } - - if ( statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) - statusBar()->setMessage(msg); - } - } - } - else - { - flags &= ~fc::focus; - - if ( isEnabled() && statusBar() ) - statusBar()->clearMessage(); - } - - return on; + bool m1 = ( std::strcmp ( w->getClassName() + , const_cast("FMenu") ) == 0 ); + bool m2 = ( std::strcmp ( w->getClassName() + , const_cast("FDialogListMenu") ) == 0 ); + return bool( m1 || m2 ); } + +// private methods of FMenuItem //---------------------------------------------------------------------- -void FMenuItem::setSelected() +void FMenuItem::init (FWidget* parent) { - if ( isEnabled() ) - { - selected = true; - processActivate(); - } -} - -//---------------------------------------------------------------------- -void FMenuItem::unsetSelected() -{ - selected = false; - processDeactivate(); -} - -//---------------------------------------------------------------------- -void FMenuItem::openMenu() -{ - FMenu* dd_menu; // Drop-down menu - FMenu* open_menu; - - if ( ! hasMenu() ) - return; - - dd_menu = getMenu(); // Drop-down menu - - if ( dd_menu->isVisible() ) - return; - - open_menu = static_cast(getOpenMenu()); - - if ( open_menu && open_menu != dd_menu ) - { - open_menu->hide(); - open_menu->hideSubMenus(); - } - - if ( dialog_index ) - createDialogList (dd_menu); - - setOpenMenu(dd_menu); - dd_menu->setVisible(); - dd_menu->show(); - dd_menu->raiseWindow(dd_menu); - dd_menu->redraw(); - updateTerminal(); - flush_out(); -} - -//---------------------------------------------------------------------- -void FMenuItem::setText (FString& txt) -{ - text = txt; text_length = text.getLength(); hotkey = hotKey(); if ( hotkey ) text_length--; - setWidth(int(text_length)); + setGeometry (1,1,int(text_length+2),1, false); + + if ( parent ) + { + FMenuList* menu_list; + setSuperMenu (parent); + + if ( accel_key ) + addAccelerator (accel_key); + + menu_list = dynamic_cast(parent); + + if ( menu_list ) + menu_list->insert(this); + + if ( isMenuBar(parent) ) // Parent is menubar + { + FMenuBar* menubar_ptr = dynamic_cast(parent); + + if ( menubar_ptr ) + { + menubar_ptr->calculateDimensions(); + + if ( hotkey ) // Meta + hotkey + menubar_ptr->addAccelerator (fc::Fmkey_meta + std::tolower(hotkey), this); + } + + this->addCallback + ( + "deactivate", + _METHOD_CALLBACK (parent, &FMenuBar::cb_item_deactivated) + ); + } + else if ( isMenu(parent) ) // Parent is menu + { + FMenu* menu_ptr = dynamic_cast(parent); + + if ( menu_ptr ) + menu_ptr->calculateDimensions(); + } + } + + if ( hasFocus() ) + flags = fc::focus; + + if ( isEnabled() ) + flags |= fc::active; } //---------------------------------------------------------------------- -void FMenuItem::setText (const std::string& txt) +uChar FMenuItem::hotKey() { - FString s = FString(txt); - setText (s); + uInt length; + + if ( text.isEmpty() ) + return 0; + + length = text.getLength(); + + for (uInt i=0; i < length; i++) + { + try + { + if ( (i+1 < length) && (text[i] == '&') ) + return uChar(text[++i]); + } + catch (const std::out_of_range&) + { + return 0;; + } + } + + return 0; } //---------------------------------------------------------------------- -void FMenuItem::setText (const char* txt) +void FMenuItem::processActivate() { - FString s = FString(txt); - setText (s); + emitCallback("activate"); +} + +//---------------------------------------------------------------------- +void FMenuItem::processDeactivate() +{ + emitCallback("deactivate"); +} + +//---------------------------------------------------------------------- +void FMenuItem::createDialogList (FMenu* winmenu) +{ + winmenu->clear(); + + if ( dialog_list && ! dialog_list->empty() ) + { + widgetList::const_iterator iter, begin; + iter = begin = dialog_list->begin(); + + while ( iter != dialog_list->end() && *iter ) + { + FDialog* win = dynamic_cast(*iter); + + if ( win ) + { + int n = int(std::distance(begin, iter)); + // get the dialog title + FString name = win->getText(); + // create a new dialog list item + FMenuItem* win_item = new FMenuItem (name, winmenu); + + if ( n < 9 ) + win_item->addAccelerator (fc::Fmkey_1 + n); // Meta + 1..9 + + win_item->addCallback + ( + "clicked", + _METHOD_CALLBACK (win_item, &FMenuItem::cb_switchToDialog), + dynamic_cast(win) + ); + + win->addCallback + ( + "destroy", + _METHOD_CALLBACK (win_item, &FMenuItem::cb_destroyDialog) + ); + + win_item->associated_window = win; + } + + ++iter; + } + } + + winmenu->calculateDimensions(); +} + +//---------------------------------------------------------------------- +void FMenuItem::cb_switchToDialog (FWidget*, void* data_ptr) +{ + FDialog* win = static_cast(data_ptr); + + if ( win ) + { + FWidget* focus_widget = getFocusWidget(); + FAccelEvent a_ev (fc::Accelerator_Event, focus_widget); + FApplication::sendEvent (win, &a_ev); + } +} + +//---------------------------------------------------------------------- +void FMenuItem::cb_destroyDialog (FWidget* widget, void*) +{ + FDialog* win = static_cast(widget); + FApplication* fapp = static_cast(getRootWidget()); + + if ( win && fapp ) + { + delAccelerator(win); + delCallback(win); + associated_window = 0; + } +} + +//---------------------------------------------------------------------- +void FMenuItem::processClicked() +{ + emitCallback("clicked"); } diff --git a/src/fmenuitem.h b/src/fmenuitem.h index 355dd823..24303d0b 100644 --- a/src/fmenuitem.h +++ b/src/fmenuitem.h @@ -48,47 +48,12 @@ class FMenuList; class FMenuItem : public FWidget { - protected: - FString text; - bool selected; - bool separator; - bool checkable; - bool checked; - bool radio_button; - bool dialog_index; - uInt text_length; - int hotkey; - int accel_key; - FMenu* menu; - FWidget* super_menu; - FDialog* associated_window; - - private: - // Disable copy constructor - FMenuItem (const FMenuItem&); - // Disable assignment operator (=) - FMenuItem& operator = (const FMenuItem&); - - void init (FWidget*); - uChar hotKey(); - void processActivate(); - void processDeactivate(); - void createDialogList (FMenu*); - - // Callback methods - void cb_switchToDialog (FWidget*, void*); - void cb_destroyDialog (FWidget*, void*); - - virtual void processClicked(); - - protected: - bool isWindowsMenu (FWidget*) const; - bool isMenuBar (FWidget*) const; - bool isMenu (FWidget*) const; - FWidget* getSuperMenu() const; - void setSuperMenu (FWidget*); - public: + // Using-declarations + using FWidget::addAccelerator; + using FWidget::delAccelerator; + using FWidget::setEnable; + // Constructor explicit FMenuItem (FWidget* = 0); FMenuItem (FString&, FWidget* = 0); @@ -97,55 +62,103 @@ class FMenuItem : public FWidget FMenuItem (int, FString&, FWidget* = 0); FMenuItem (int, const std::string&, FWidget* = 0); FMenuItem (int, const char*, FWidget* = 0); + // Destructor virtual ~FMenuItem(); + // Accessors const char* getClassName() const; + int getHotkey() const; + FMenu* getMenu() const; + uInt getTextLength() const; + FString getText() const; - // make every addAccelerator from FWidget available - using FWidget::addAccelerator; - void addAccelerator (int, FWidget*); - // make every delAccelerator from FWidget available - using FWidget::delAccelerator; - void delAccelerator (FWidget*); + // Mutators + bool setEnable (bool); + bool setFocus (bool); + bool setFocus(); + bool unsetFocus(); + void setSelected(); + void unsetSelected(); + void setSeparator(); + void unsetSeparator(); + void setChecked(); + void unsetChecked(); + void setMenu (FMenu*); + void setText (FString&); + void setText (const std::string&); + void setText (const char*); + + // Inquiries + bool isSelected() const; + bool isSeparator() const; + bool isChecked() const; + bool hasHotkey() const; + bool hasMenu() const; + + // Methods + void addAccelerator (int, FWidget*); + void delAccelerator (FWidget*); + void openMenu(); // Event handlers - void onKeyPress (FKeyEvent*); - void onMouseDoubleClick (FMouseEvent*); - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onAccel (FAccelEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); - // make every setEnable from FWidget available - using FWidget::setEnable; - bool setEnable(bool); - bool setFocus(bool); - bool setFocus(); - bool unsetFocus(); - void setSelected(); - void unsetSelected(); - bool isSelected() const; - void setSeparator(); - void unsetSeparator(); - bool isSeparator() const; - void setChecked(); - void unsetChecked(); - bool isChecked() const; - int getHotkey() const; - bool hasHotkey() const; - FMenu* getMenu() const; - void setMenu(FMenu*); - bool hasMenu() const; - void openMenu(); - uInt getTextLength() const; - FString getText() const; - void setText (FString&); - void setText (const std::string&); - void setText (const char*); + void onKeyPress (FKeyEvent*); + void onMouseDoubleClick (FMouseEvent*); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onAccel (FAccelEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); + + protected: + // Accessor + FWidget* getSuperMenu() const; + + // Mutator + void setSuperMenu (FWidget*); + + // Inquiries + bool isWindowsMenu (FWidget*) const; + bool isMenuBar (FWidget*) const; + bool isMenu (FWidget*) const; + + // Data Members + FString text; + bool selected; + bool separator; + bool checkable; + bool checked; + bool radio_button; + bool dialog_index; + uInt text_length; + int hotkey; + int accel_key; + FMenu* menu; + FWidget* super_menu; + FDialog* associated_window; private: + // Disable copy constructor + FMenuItem (const FMenuItem&); + + // Disable assignment operator (=) + FMenuItem& operator = (const FMenuItem&); + + // Methods + void init (FWidget*); + uChar hotKey(); + void processActivate(); + void processDeactivate(); + void createDialogList (FMenu*); + + // Callback methods + void cb_switchToDialog (FWidget*, void*); + void cb_destroyDialog (FWidget*, void*); + + virtual void processClicked(); + + // Friend classes friend class FDialogListMenu; friend class FMenuList; friend class FMenuBar; @@ -160,12 +173,20 @@ inline const char* FMenuItem::getClassName() const { return "FMenuItem"; } //---------------------------------------------------------------------- -inline FWidget* FMenuItem::getSuperMenu() const -{ return super_menu; } +inline int FMenuItem::getHotkey() const +{ return hotkey; } //---------------------------------------------------------------------- -inline void FMenuItem::setSuperMenu (FWidget* smenu) -{ super_menu = smenu; } +inline FMenu* FMenuItem::getMenu() const +{ return menu; } + +//---------------------------------------------------------------------- +inline uInt FMenuItem::getTextLength() const +{ return text_length; } + +//---------------------------------------------------------------------- +inline FString FMenuItem::getText() const +{ return text; } //---------------------------------------------------------------------- inline bool FMenuItem::setFocus() @@ -175,10 +196,6 @@ inline bool FMenuItem::setFocus() inline bool FMenuItem::unsetFocus() { return setFocus(false); } -//---------------------------------------------------------------------- -inline bool FMenuItem::isSelected() const -{ return selected; } - //---------------------------------------------------------------------- inline void FMenuItem::setSeparator() { @@ -193,10 +210,6 @@ inline void FMenuItem::unsetSeparator() setFocusable(); } -//---------------------------------------------------------------------- -inline bool FMenuItem::isSeparator() const -{ return separator; } - //---------------------------------------------------------------------- inline void FMenuItem::setChecked() { checked = true; } @@ -206,35 +219,35 @@ inline void FMenuItem::unsetChecked() { checked = false; } //---------------------------------------------------------------------- -inline bool FMenuItem::isChecked() const -{ return checked; } +inline void FMenuItem::setMenu(FMenu* m) +{ menu = m; } //---------------------------------------------------------------------- -inline int FMenuItem::getHotkey() const -{ return hotkey; } +inline bool FMenuItem::isSelected() const +{ return selected; } + +//---------------------------------------------------------------------- +inline bool FMenuItem::isSeparator() const +{ return separator; } + +//---------------------------------------------------------------------- +inline bool FMenuItem::isChecked() const +{ return checked; } //---------------------------------------------------------------------- inline bool FMenuItem::hasHotkey() const { return bool(hotkey != 0); } -//---------------------------------------------------------------------- -inline FMenu* FMenuItem::getMenu() const -{ return menu; } - -//---------------------------------------------------------------------- -inline void FMenuItem::setMenu(FMenu* m) -{ menu = m; } - //---------------------------------------------------------------------- inline bool FMenuItem::hasMenu() const { return bool(menu != 0); } //---------------------------------------------------------------------- -inline uInt FMenuItem::getTextLength() const -{ return text_length; } +inline FWidget* FMenuItem::getSuperMenu() const +{ return super_menu; } //---------------------------------------------------------------------- -inline FString FMenuItem::getText() const -{ return text; } +inline void FMenuItem::setSuperMenu (FWidget* smenu) +{ super_menu = smenu; } #endif // _FMENUITEM_H diff --git a/src/fmenulist.cpp b/src/fmenulist.cpp index 798cdca7..4716e852 100644 --- a/src/fmenulist.cpp +++ b/src/fmenulist.cpp @@ -33,6 +33,50 @@ FMenuList::~FMenuList() // destructor // public methods of FMenuList +//---------------------------------------------------------------------- +void FMenuList::insert (FMenuItem* i) +{ + item_list.push_back(i); +} + +//---------------------------------------------------------------------- +void FMenuList::remove (FMenuItem* i) +{ + std::vector::iterator iter; + + if ( item_list.empty() ) + return; + + iter = item_list.begin(); + + while ( iter != item_list.end() ) + { + if ( (*iter) == i ) + { + iter = item_list.erase(iter); + i->setSuperMenu(0); + break; + } + else + ++iter; + } +} + +//---------------------------------------------------------------------- +void FMenuList::remove (int pos) +{ + if ( int(getCount()) < pos ) + return; + + item_list.erase (item_list.begin() + pos - 1); +} + +//---------------------------------------------------------------------- +void FMenuList::clear() +{ + item_list.clear(); +} + //---------------------------------------------------------------------- void FMenuList::selectFirstItem() { @@ -68,47 +112,3 @@ void FMenuList::unselectItem() setSelectedItem(0); } - -//---------------------------------------------------------------------- -void FMenuList::insert (FMenuItem* i) -{ - item_list.push_back(i); -} - -//---------------------------------------------------------------------- -void FMenuList::remove (FMenuItem* i) -{ - std::vector::iterator iter; - - if ( item_list.empty() ) - return; - - iter = item_list.begin(); - - while ( iter != item_list.end() ) - { - if ( (*iter) == i ) - { - iter = item_list.erase(iter); - i->setSuperMenu(0); - break; - } - else - ++iter; - } -} - -//---------------------------------------------------------------------- -void FMenuList::remove (int pos) -{ - if ( int(count()) < pos ) - return; - - item_list.erase (item_list.begin() + pos - 1); -} - -//---------------------------------------------------------------------- -void FMenuList::clear() -{ - item_list.clear(); -} diff --git a/src/fmenulist.h b/src/fmenulist.h index 901cdb83..8284f25d 100644 --- a/src/fmenulist.h +++ b/src/fmenulist.h @@ -32,6 +32,36 @@ class FMenuList { + public: + // Constructor + explicit FMenuList(); + + // Destructor + virtual ~FMenuList(); + + // Accessors + virtual const char* getClassName() const; + uInt getCount() const; + FMenuItem* getItem (int) const; + FMenuItem* getSelectedItem() const; + + // Mutators + void enableItem (int); + void disableItem (int); + void setSelectedItem (FMenuItem*); + + // Inquiries + bool isSelected (int) const; + bool hasSelectedItem() const; + + // Methods + virtual void insert (FMenuItem*); + virtual void remove (FMenuItem*); + void remove (int); + void clear(); + void selectFirstItem(); + void unselectItem(); + protected: FMenuItem* selected_item; std::vector item_list; @@ -39,30 +69,9 @@ class FMenuList private: // Disable copy constructor FMenuList (const FMenuList&); + // Disable assignment operator (=) FMenuList& operator = (const FMenuList&); - - public: - // Constructor - explicit FMenuList(); - // Destructor - virtual ~FMenuList(); - - virtual const char* getClassName() const; - uInt count() const; - FMenuItem* item (int) const; - void enableItem (int); - void disableItem (int); - bool isSelected (int) const; - void selectFirstItem(); - void unselectItem(); - FMenuItem* getSelectedItem() const; - void setSelectedItem (FMenuItem*); - bool hasSelectedItem() const; - virtual void insert (FMenuItem*); - virtual void remove (FMenuItem*); - void remove (int); - void clear(); }; #pragma pack(pop) @@ -73,13 +82,17 @@ inline const char* FMenuList::getClassName() const { return "FMenuList"; } //---------------------------------------------------------------------- -inline uInt FMenuList::count() const +inline uInt FMenuList::getCount() const { return uInt(item_list.size()); } //---------------------------------------------------------------------- -inline FMenuItem* FMenuList::item (int index) const +inline FMenuItem* FMenuList::getItem (int index) const { return (index > 0) ? item_list[uInt(index-1)] : 0; } +//---------------------------------------------------------------------- +inline FMenuItem* FMenuList::getSelectedItem() const +{ return selected_item; } + //---------------------------------------------------------------------- inline void FMenuList::enableItem (int index) { item_list[uInt(index-1)]->setEnable(); } @@ -88,18 +101,14 @@ inline void FMenuList::enableItem (int index) inline void FMenuList::disableItem (int index) { item_list[uInt(index-1)]->unsetEnable(); } -//---------------------------------------------------------------------- -inline bool FMenuList::isSelected(int index) const -{ return (index > 0) ? item_list[uInt(index-1)]->isSelected() : false; } - -//---------------------------------------------------------------------- -inline FMenuItem* FMenuList::getSelectedItem() const -{ return selected_item; } - //---------------------------------------------------------------------- inline void FMenuList::setSelectedItem (FMenuItem* menuitem) { selected_item = menuitem; } +//---------------------------------------------------------------------- +inline bool FMenuList::isSelected(int index) const +{ return (index > 0) ? item_list[uInt(index-1)]->isSelected() : false; } + //---------------------------------------------------------------------- inline bool FMenuList::hasSelectedItem() const { return selected_item; } diff --git a/src/fmessagebox.cpp b/src/fmessagebox.cpp index d0e5e31f..ac8477b8 100644 --- a/src/fmessagebox.cpp +++ b/src/fmessagebox.cpp @@ -99,9 +99,198 @@ FMessageBox::~FMessageBox() // destructor } +// public methods of FMessageBox +//---------------------------------------------------------------------- +FMessageBox& FMessageBox::operator = (const FMessageBox& mbox) +{ + if ( &mbox == this ) + { + return *this; + } + else + { + for (uInt n=0; n < num_buttons; n++) + delete button[n]; + + delete button_digit[2]; + delete button_digit[1]; + delete button_digit[0]; + + if ( mbox.getParentWidget() ) + mbox.getParentWidget()->addChild (this); + + headline_text = mbox.headline_text; + text = mbox.text; + text_components = mbox.text_components; + text_split = mbox.text_split; + max_line_width = mbox.max_line_width; + center_text = mbox.center_text; + emphasis_color = mbox.emphasis_color; + num_buttons = mbox.num_buttons; + text_num_lines = mbox.text_num_lines; + + setTitlebarText (mbox.getTitlebarText()); + init ( *mbox.button_digit[0] + , *mbox.button_digit[1] + , *mbox.button_digit[2] ); + + return *this; + } +} + +//---------------------------------------------------------------------- +void FMessageBox::setHeadline (const FString& headline) +{ + headline_text = headline; + setHeight(getHeight() + 2, true); + + for (uInt n=0; n < num_buttons; n++) + button[n]->setY(getHeight()-4, false); + + uInt len = headline_text.getLength(); + + if ( len > max_line_width ) + max_line_width = len; +} + +//---------------------------------------------------------------------- +void FMessageBox::setHeadline (const std::string& headline) +{ + FString headline_txt(headline); + setHeadline( headline_txt ); +} + +//---------------------------------------------------------------------- +void FMessageBox::setHeadline (const char* headline) +{ + FString headline_txt(headline); + setHeadline( headline_txt ); +} + +//---------------------------------------------------------------------- +void FMessageBox::setText (const FString& txt) +{ + text = txt; + calculateDimensions(); + button[0]->setY(getHeight()-4, false); + + if ( *button_digit[1] != 0 ) + button[1]->setY(getHeight()-4, false); + + if ( *button_digit[2] != 0 ) + button[2]->setY(getHeight()-4, false); + + adjustButtons(); +} + +//---------------------------------------------------------------------- +void FMessageBox::setText (const std::string& txt) +{ + FString message_text(txt); + setText( message_text ); +} + +//---------------------------------------------------------------------- +void FMessageBox::setText (const char* txt) +{ + FString message_text(txt); + setText( message_text ); +} + +//---------------------------------------------------------------------- +int FMessageBox::info ( FWidget* parent + , const FString& caption + , const FString& message + , int button0 + , int button1 + , int button2 ) +{ + int reply; + FMessageBox* mbox = new FMessageBox ( caption, message + , button0, button1, button2 + , parent ); + reply = mbox->exec(); + delete mbox; + return reply; +} + +//---------------------------------------------------------------------- +int FMessageBox::info ( FWidget* parent + , const FString& caption + , int num + , int button0 + , int button1 + , int button2 ) +{ + int reply; + FMessageBox* mbox = new FMessageBox ( caption + , FString().setNumber(num) + , button0, button1, button2 + , parent ); + reply = mbox->exec(); + delete mbox; + return reply; +} + +//---------------------------------------------------------------------- +int FMessageBox::error ( FWidget* parent + , const FString& message + , int button0 + , int button1 + , int button2 ) +{ + int reply; + const FString caption = "Error message"; + FMessageBox* mbox = new FMessageBox ( caption, message + , button0, button1, button2 + , parent ); + mbox->beep(); + mbox->setHeadline("Warning:"); + mbox->setCenterText(); + mbox->setForegroundColor(mbox->wc.error_box_fg); + mbox->setBackgroundColor(mbox->wc.error_box_bg); + mbox->emphasis_color = mbox->wc.error_box_emphasis_fg; + reply = mbox->exec(); + delete mbox; + return reply; +} + + +// protected methods of FMessageBox +//---------------------------------------------------------------------- +void FMessageBox::adjustSize() +{ + int X, Y, max_width, max_height; + FWidget* root_widget = getRootWidget(); + + if ( root_widget ) + { + max_width = root_widget->getClientWidth(); + max_height = root_widget->getClientHeight(); + } + else + { + max_width = 80; + max_height = 24; + } + + X = 1 + int((max_width-getWidth())/2); + Y = 1 + int((max_height-getHeight())/3); + setPos(X, Y, false); + FDialog::adjustSize(); +} + +//---------------------------------------------------------------------- +void FMessageBox::cb_processClick (FWidget*, void* data_ptr) +{ + int* reply = static_cast(data_ptr); + done (*reply); +} + + // private methods of FMessageBox //---------------------------------------------------------------------- -void FMessageBox::init(int button0, int button1, int button2) +void FMessageBox::init (int button0, int button1, int button2) { calculateDimensions(); @@ -336,192 +525,3 @@ void FMessageBox::adjustButtons() } } } - -//---------------------------------------------------------------------- -void FMessageBox::cb_processClick (FWidget*, void* data_ptr) -{ - int* reply = static_cast(data_ptr); - done (*reply); -} - - -// protected methods of FMessageBox -//---------------------------------------------------------------------- -void FMessageBox::adjustSize() -{ - int X, Y, max_width, max_height; - FWidget* root_widget = getRootWidget(); - - if ( root_widget ) - { - max_width = root_widget->getClientWidth(); - max_height = root_widget->getClientHeight(); - } - else - { - max_width = 80; - max_height = 24; - } - - X = 1 + int((max_width-getWidth())/2); - Y = 1 + int((max_height-getHeight())/3); - setPos(X, Y, false); - FDialog::adjustSize(); -} - - -// public methods of FMessageBox -//---------------------------------------------------------------------- -FMessageBox& FMessageBox::operator = (const FMessageBox& mbox) -{ - if ( &mbox == this ) - { - return *this; - } - else - { - for (uInt n=0; n < num_buttons; n++) - delete button[n]; - - delete button_digit[2]; - delete button_digit[1]; - delete button_digit[0]; - - if ( mbox.getParentWidget() ) - mbox.getParentWidget()->addChild (this); - - headline_text = mbox.headline_text; - text = mbox.text; - text_components = mbox.text_components; - text_split = mbox.text_split; - max_line_width = mbox.max_line_width; - center_text = mbox.center_text; - emphasis_color = mbox.emphasis_color; - num_buttons = mbox.num_buttons; - text_num_lines = mbox.text_num_lines; - - setTitlebarText (mbox.getTitlebarText()); - init ( *mbox.button_digit[0] - , *mbox.button_digit[1] - , *mbox.button_digit[2] ); - - return *this; - } -} - -//---------------------------------------------------------------------- -void FMessageBox::setHeadline (const FString& headline) -{ - headline_text = headline; - setHeight(getHeight() + 2, true); - - for (uInt n=0; n < num_buttons; n++) - button[n]->setY(getHeight()-4, false); - - uInt len = headline_text.getLength(); - - if ( len > max_line_width ) - max_line_width = len; -} - -//---------------------------------------------------------------------- -void FMessageBox::setHeadline (const std::string& headline) -{ - FString headline_txt(headline); - setHeadline( headline_txt ); -} - -//---------------------------------------------------------------------- -void FMessageBox::setHeadline (const char* headline) -{ - FString headline_txt(headline); - setHeadline( headline_txt ); -} - -//---------------------------------------------------------------------- -void FMessageBox::setText (const FString& txt) -{ - text = txt; - calculateDimensions(); - button[0]->setY(getHeight()-4, false); - - if ( *button_digit[1] != 0 ) - button[1]->setY(getHeight()-4, false); - - if ( *button_digit[2] != 0 ) - button[2]->setY(getHeight()-4, false); - - adjustButtons(); -} - -//---------------------------------------------------------------------- -void FMessageBox::setText (const std::string& txt) -{ - FString message_text(txt); - setText( message_text ); -} - -//---------------------------------------------------------------------- -void FMessageBox::setText (const char* txt) -{ - FString message_text(txt); - setText( message_text ); -} - -//---------------------------------------------------------------------- -int FMessageBox::info ( FWidget* parent - , const FString& caption - , const FString& message - , int button0 - , int button1 - , int button2 ) -{ - int reply; - FMessageBox* mbox = new FMessageBox ( caption, message - , button0, button1, button2 - , parent ); - reply = mbox->exec(); - delete mbox; - return reply; -} - -//---------------------------------------------------------------------- -int FMessageBox::info ( FWidget* parent - , const FString& caption - , int num - , int button0 - , int button1 - , int button2 ) -{ - int reply; - FMessageBox* mbox = new FMessageBox ( caption - , FString().setNumber(num) - , button0, button1, button2 - , parent ); - reply = mbox->exec(); - delete mbox; - return reply; -} - -//---------------------------------------------------------------------- -int FMessageBox::error ( FWidget* parent - , const FString& message - , int button0 - , int button1 - , int button2 ) -{ - int reply; - const FString caption = "Error message"; - FMessageBox* mbox = new FMessageBox ( caption, message - , button0, button1, button2 - , parent ); - mbox->beep(); - mbox->setHeadline("Warning:"); - mbox->setCenterText(); - mbox->setForegroundColor(mbox->wc.error_box_fg); - mbox->setBackgroundColor(mbox->wc.error_box_bg); - mbox->emphasis_color = mbox->wc.error_box_emphasis_fg; - reply = mbox->exec(); - delete mbox; - return reply; -} diff --git a/src/fmessagebox.h b/src/fmessagebox.h index b766d379..d8bfa42f 100644 --- a/src/fmessagebox.h +++ b/src/fmessagebox.h @@ -55,6 +55,7 @@ class FMessageBox : public FDialog { public: + // Enumeration enum { Reject = 0, @@ -67,33 +68,6 @@ class FMessageBox : public FDialog Ignore = 7 }; - private: - FString headline_text; - FString text; - FString* text_components; - std::vector text_split; - uInt max_line_width; - bool center_text; - short emphasis_color; - uInt num_buttons; - uInt text_num_lines; - int* button_digit[3]; - FButton* button[3]; - - protected: - void adjustSize(); - - private: - void init(int, int, int); - void calculateDimensions(); - virtual void draw(); - void resizeButtons(); - void adjustButtons(); - - // Callback method - void cb_processClick (FWidget*, void*); - - public: // Constructors explicit FMessageBox (FWidget* = 0); FMessageBox (const FMessageBox&); // copy constructor @@ -106,43 +80,74 @@ class FMessageBox : public FDialog // Assignment operator (=) FMessageBox& operator = (const FMessageBox&); - const char* getClassName() const; + // Accessor + const char* getClassName() const; const FString getTitlebarText() const; - void setTitlebarText (const FString&); - const FString getHeadline() const; - void setHeadline (const FString&); - void setHeadline (const std::string&); - void setHeadline (const char*); - const FString getText() const; - void setText (const FString&); - void setText (const std::string&); - void setText (const char*); - bool setCenterText(bool); - bool setCenterText(); - bool unsetCenterText(); + // Mutator + void setTitlebarText (const FString&); + void setHeadline (const FString&); + void setHeadline (const std::string&); + void setHeadline (const char*); + bool setCenterText(bool); + bool setCenterText(); + bool unsetCenterText(); + void setText (const FString&); + void setText (const std::string&); + void setText (const char*); - static int info ( FWidget* - , const FString& - , const FString& - , int = FMessageBox::Ok - , int = 0 - , int = 0 ); + // Methods + static int info ( FWidget* + , const FString& + , const FString& + , int = FMessageBox::Ok + , int = 0 + , int = 0 ); - static int info ( FWidget* - , const FString& - , int - , int = FMessageBox::Ok - , int = 0 - , int = 0 ); + static int info ( FWidget* + , const FString& + , int + , int = FMessageBox::Ok + , int = 0 + , int = 0 ); - static int error ( FWidget* - , const FString& - , int = FMessageBox::Ok - , int = 0 - , int = 0 ); + static int error ( FWidget* + , const FString& + , int = FMessageBox::Ok + , int = 0 + , int = 0 ); + protected: + // Method + void adjustSize(); + + // Callback method + void cb_processClick (FWidget*, void*); + + private: + // Typedef + typedef std::vector textLines; + + // Methods + void init (int, int, int); + void calculateDimensions(); + virtual void draw(); + void resizeButtons(); + void adjustButtons(); + + // Data Members + FString headline_text; + FString text; + FString* text_components; + textLines text_split; + uInt max_line_width; + bool center_text; + short emphasis_color; + uInt num_buttons; + uInt text_num_lines; + int* button_digit[3]; + FButton* button[3]; }; #pragma pack(pop) @@ -156,10 +161,6 @@ inline const char* FMessageBox::getClassName() const inline const FString FMessageBox::getTitlebarText() const { return FDialog::getText(); } -//---------------------------------------------------------------------- -inline void FMessageBox::setTitlebarText (const FString& txt) -{ return FDialog::setText(txt); } - //---------------------------------------------------------------------- inline const FString FMessageBox::getHeadline() const { return headline_text; } @@ -168,6 +169,10 @@ inline const FString FMessageBox::getHeadline() const inline const FString FMessageBox::getText() const { return text; } +//---------------------------------------------------------------------- +inline void FMessageBox::setTitlebarText (const FString& txt) +{ return FDialog::setText(txt); } + //---------------------------------------------------------------------- inline bool FMessageBox::setCenterText(bool on) { return center_text = on; } diff --git a/src/fobject.cpp b/src/fobject.cpp index dc692b86..975e727a 100644 --- a/src/fobject.cpp +++ b/src/fobject.cpp @@ -242,6 +242,7 @@ bool FObject::delAllTimer() return true; } + // protected methods of FObject //---------------------------------------------------------------------- bool FObject::event (FEvent* ev) diff --git a/src/fobject.h b/src/fobject.h index d360e1c9..4acc89ee 100644 --- a/src/fobject.h +++ b/src/fobject.h @@ -48,8 +48,6 @@ typedef long double lDouble; class FObject { public: - typedef std::list object_list; - struct timer_data { int id; @@ -58,38 +56,41 @@ class FObject FObject* object; }; + // Typedef + typedef std::list object_list; typedef std::vector TimerList; - static TimerList* timer_list; - private: - FObject* parent_obj; - object_list children_list; - bool has_parent; - static bool timer_modify_lock; - - public: // Constructor explicit FObject (FObject* = 0); + // Destructor virtual ~FObject(); + // Accessors virtual const char* getClassName() const; + FObject* getParent() const; + object_list getChildren() const; + int numOfChildren() const; + + // Inquiries + bool hasParent() const; + bool hasChildren() const; + bool isTimerInUpdating() const; + + // Methods + void removeParent(); + void addChild (FObject*); + void delChild (FObject*); - FObject* getParent() const; - bool hasParent() const; - void removeParent(); - object_list getChildren() const; - bool hasChildren() const; - void addChild (FObject*); - void delChild (FObject*); - int numOfChildren() const; // Timer methods - static void getCurrentTime (timeval&); - int addTimer (int); - bool delTimer (int); - bool delOwnTimer(); - bool delAllTimer(); - bool isTimerInUpdating() const; + static void getCurrentTime (timeval&); + int addTimer (int); + bool delTimer (int); + bool delOwnTimer(); + bool delAllTimer(); + + // Data Members + static TimerList* timer_list; protected: // Event handler @@ -99,8 +100,15 @@ class FObject private: // Disable copy constructor FObject (const FObject&); + // Disable assignment operator (=) FObject& operator = (const FObject&); + + // Data Members + FObject* parent_obj; + object_list children_list; + bool has_parent; + static bool timer_modify_lock; }; #pragma pack(pop) @@ -113,30 +121,30 @@ inline const char* FObject::getClassName() const inline FObject* FObject::getParent() const { return parent_obj; } -//---------------------------------------------------------------------- -inline bool FObject::hasParent() const -{ return has_parent; } - -//---------------------------------------------------------------------- -inline void FObject::removeParent() -{ parent_obj = 0; } - //---------------------------------------------------------------------- inline FObject::object_list FObject::getChildren() const { return children_list; } -//---------------------------------------------------------------------- -inline bool FObject::hasChildren() const -{ return bool( ! children_list.empty() ); } - //---------------------------------------------------------------------- inline int FObject::numOfChildren() const { return int(children_list.size()); } +//---------------------------------------------------------------------- +inline bool FObject::hasParent() const +{ return has_parent; } + +//---------------------------------------------------------------------- +inline bool FObject::hasChildren() const +{ return bool( ! children_list.empty() ); } + //---------------------------------------------------------------------- inline bool FObject::isTimerInUpdating() const { return timer_modify_lock; } +//---------------------------------------------------------------------- +inline void FObject::removeParent() +{ parent_obj = 0; } + //---------------------------------------------------------------------- // Operator functions for timeval diff --git a/src/foptiattr.cpp b/src/foptiattr.cpp index 6a4c7266..268f003f 100644 --- a/src/foptiattr.cpp +++ b/src/foptiattr.cpp @@ -46,6 +46,8 @@ FOptiAttr::FOptiAttr() , F_set_color_pair() , F_orig_pair() , F_orig_colors() + , on() + , off() , max_color(1) , attr_without_color(0) , ansi_default_color(false) @@ -53,8 +55,6 @@ FOptiAttr::FOptiAttr() , fake_reverse(false) , cygwin_terminal(false) , attr_ptr(attr_buf) - , on() - , off() { attr_buf[0] = '\0'; } @@ -64,872 +64,7 @@ FOptiAttr::~FOptiAttr() // destructor { } -// private methods of FApplication -//---------------------------------------------------------------------- -inline bool FOptiAttr::hasColor (char_data*& attr) -{ - if ( attr && attr->fg_color < 0 && attr->bg_color < 0 ) - return false; - else - return true; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::colorChange (char_data*& term, char_data*& next) -{ - if ( term && next ) - { - return bool ( fake_reverse - || term->fg_color != next->fg_color - || term->bg_color != next->bg_color ); - } - - return false; -} - -//---------------------------------------------------------------------- -inline void FOptiAttr::resetColor (char_data*& attr) -{ - if ( attr ) - { - attr->fg_color = Default; - attr->bg_color = Default; - } -} - -//---------------------------------------------------------------------- -inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr) -{ - // ignore attributes which can not combined with a color - - enum attr_modes - { - standout_mode = 1, - underline_mode = 2, - reverse_mode = 4, - blink_mode = 8, - dim_mode = 16, - bold_mode = 32, - invisible_mode = 64, - protected_mode = 128, - alt_charset_mode = 256, - horizontal_mode = 512, - left_mode = 1024, - low_mode = 2048, - right_mode = 4096, - top_mode = 8192, - vertical_mode = 16384, - italic_mode = 32768, - no_mode = 65536 - }; - - if ( hasColor(attr) && attr_without_color > 0 ) - { - for (int bit=1; bit < no_mode; bit <<= 1) - { - switch ( bit & attr_without_color ) - { - case standout_mode: - if ( attr->standout ) - attr->standout = false; - break; - - case underline_mode: - if ( attr->underline ) - attr->underline = false; - break; - - case reverse_mode: - if ( attr->reverse ) - { - attr->reverse = false; - - if ( attr->fg_color != attr->bg_color ) - fake_reverse = true; - } - break; - - case blink_mode: - if ( attr->blink ) - attr->blink = false; - break; - - case dim_mode: - if ( attr->dim ) - attr->dim = false; - break; - - case bold_mode: - if ( attr->bold ) - attr->bold = false; - break; - - case invisible_mode: - if ( attr->invisible ) - attr->invisible = false; - break; - - case protected_mode: - if ( attr->protect ) - attr->protect = false; - break; - - case alt_charset_mode: - if ( attr->alt_charset ) - attr->alt_charset = false; - break; - - case italic_mode: - if ( attr->italic ) - attr->italic = false; - break; - - default: - break; - } - } - } -} - -//---------------------------------------------------------------------- -void FOptiAttr::change_color (char_data*& term, char_data*& next) -{ - char* color_str; - char* AF = F_set_a_foreground.cap; - char* AB = F_set_a_background.cap; - char* Sf = F_set_foreground.cap; - char* Sb = F_set_background.cap; - char* sp = F_set_color_pair.cap; - short fg, bg; - - if ( monochron || ! (term && next) ) - return; - - fg = next->fg_color; - bg = next->bg_color; - - if ( fg == Default || bg == Default ) - { - if ( ansi_default_color ) - { - if ( fg == Default && term->fg_color != Default - && bg == Default && term->bg_color != Default ) - { - setTermDefaultColor(term); - } - else if ( fg == Default && term->fg_color != Default ) - { - char* sgr_39 = const_cast(CSI "39m"); - append_sequence (sgr_39); - term->fg_color = Default; - } - else if ( bg == Default && term->bg_color != Default ) - { - char* sgr_49; - char* op = F_orig_pair.cap; - - if ( op && std::strncmp (op, CSI "39;49;25m", 11) == 0 ) - sgr_49 = const_cast(CSI "49;25m"); - else - sgr_49 = const_cast(CSI "49m"); - - append_sequence (sgr_49); - term->bg_color = Default; - } - } - else if ( ! setTermDefaultColor(term) ) - { - // fallback to gray on black - fg = next->fg_color = LightGray; - bg = next->bg_color = Black; - } - } - - if ( ! fake_reverse && fg < 0 && bg < 0 ) - return; - - if ( fake_reverse ) - { - std::swap (fg, bg); - - if ( fg == Default || bg == Default ) - setTermDefaultColor(term); - } - - if ( AF && AB ) - { - short ansi_fg = vga2ansi(fg); - short ansi_bg = vga2ansi(bg); - - if ( cygwin_terminal ) - { - // reset blink and bold mode from colors > 7 - char* rst = const_cast(CSI "m"); - append_sequence (rst); - reset(term); - - if ( ansi_fg != Default ) - { - color_str = tparm(AF, ansi_fg); - - if ( color_str ) - append_sequence (color_str); - } - - if ( ansi_bg != Default ) - { - color_str = tparm(AB, ansi_bg); - if ( color_str ) - append_sequence (color_str); - } - } - else - { - if ( term->fg_color != fg && (color_str = tparm(AF, ansi_fg)) ) - append_sequence (color_str); - - if ( term->bg_color != bg && (color_str = tparm(AB, ansi_bg)) ) - append_sequence (color_str); - } - } - else if ( Sf && Sb ) - { - if ( term->fg_color != fg && (color_str = tparm(Sf, fg)) ) - append_sequence (color_str); - - if ( term->bg_color != bg && (color_str = tparm(Sb, bg)) ) - append_sequence (color_str); - } - else if ( sp ) - { - fg = vga2ansi(fg); - bg = vga2ansi(bg); - - if ( (color_str = tparm(sp, fg, bg)) ) - append_sequence (color_str); - } - - term->fg_color = next->fg_color; - term->bg_color = next->bg_color; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::hasAttribute (char_data*& attr) -{ - if ( attr ) - { - return attr->bold == true - || attr->dim == true - || attr->italic == true - || attr->underline == true - || attr->blink == true - || attr->reverse == true - || attr->standout == true - || attr->invisible == true - || attr->protect == true - || attr->crossed_out == true - || attr->dbl_underline == true - || attr->alt_charset == true - || attr->pc_charset == true; - } - - return false; -} - -//---------------------------------------------------------------------- -inline void FOptiAttr::resetAttribute (char_data*& attr) -{ - if ( attr ) - { - attr->bold = \ - attr->dim = \ - attr->italic = \ - attr->underline = \ - attr->blink = \ - attr->reverse = \ - attr->standout = \ - attr->invisible = \ - attr->protect = \ - attr->crossed_out = \ - attr->dbl_underline = \ - attr->alt_charset = \ - attr->pc_charset = false; - } -} - -//---------------------------------------------------------------------- -inline void FOptiAttr::reset (char_data*& attr) -{ - if ( attr ) - { - resetAttribute(attr); - resetColor(attr); - } -} - -//---------------------------------------------------------------------- -bool FOptiAttr::caused_reset_attributes (char*& cap, uChar test) -{ - // test if "cap" reset all attributes - char* ue = F_exit_underline_mode.cap; - char* se = F_exit_standout_mode.cap; - char* me = F_exit_attribute_mode.cap; - - if ( cap ) - { - if ( (test & test_ansi_reset) && std::strncmp (cap, CSI "m", 3) == 0 ) - return true; - - if ( (test & test_adm3_reset) && std::strncmp (cap, ESC "G0", 3) == 0 ) - return true; - - if ( (test & same_like_ue) && ue && std::strcmp (cap, ue) == 0 ) - return true; - - if ( (test & same_like_se) && se && std::strcmp (cap, se) == 0 ) - return true; - - if ( (test & same_like_me) && me && std::strcmp (cap, me) == 0 ) - return true; - } - - return false; -} - -//---------------------------------------------------------------------- -inline void FOptiAttr::detectSwitchOn (char_data*& term, char_data*& next) -{ - if ( ! (term && next) ) - return; - - on.bold = ! term->bold && next->bold; - on.dim = ! term->dim && next->dim; - on.italic = ! term->italic && next->italic; - on.underline = ! term->underline && next->underline; - on.blink = ! term->blink && next->blink; - on.reverse = ! term->reverse && next->reverse; - on.standout = ! term->standout && next->standout; - on.invisible = ! term->invisible && next->invisible; - on.protect = ! term->protect && next->protect; - on.crossed_out = ! term->crossed_out && next->crossed_out; - on.dbl_underline = ! term->dbl_underline && next->dbl_underline; - on.alt_charset = ! term->alt_charset && next->alt_charset; - on.pc_charset = ! term->pc_charset && next->pc_charset; -} - -//---------------------------------------------------------------------- -inline void FOptiAttr::detectSwitchOff (char_data*& term, char_data*& next) -{ - if ( ! (term && next) ) - return; - - off.bold = term->bold && ! next->bold; - off.dim = term->dim && ! next->dim; - off.italic = term->italic && ! next->italic; - off.underline = term->underline && ! next->underline; - off.blink = term->blink && ! next->blink; - off.reverse = term->reverse && ! next->reverse; - off.standout = term->standout && ! next->standout; - off.invisible = term->invisible && ! next->invisible; - off.protect = term->protect && ! next->protect; - off.crossed_out = term->crossed_out && ! next->crossed_out; - off.dbl_underline = term->dbl_underline && ! next->dbl_underline; - off.alt_charset = term->alt_charset && ! next->alt_charset; - off.pc_charset = term->pc_charset && ! next->pc_charset; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::switchOn() -{ - char_data* on_ptr = &on; - return hasAttribute(on_ptr); -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::switchOff() -{ - char_data* off_ptr = &off; - return hasAttribute(off_ptr); -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::append_sequence (char*& seq) -{ - if ( seq ) - { - std::strncat (attr_ptr, seq, sizeof(attr_buf) - std::strlen(attr_ptr) - 1 ); - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::replace_sequence (char*& seq) -{ - if ( seq ) - { - std::strncpy (attr_ptr, seq, sizeof(attr_buf) - 1); - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermBold (char_data*& term) -{ - if ( term && append_sequence(F_enter_bold_mode.cap) ) - return (term->bold = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermBold (char_data*& term) -{ - // Back to normal intensity (turns off bold + dim) - if ( append_sequence(F_exit_bold_mode.cap) ) - { - if ( F_exit_bold_mode.caused_reset ) - reset(term); - else - { - term->bold = false; - term->dim = false; - } - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermDim (char_data*& term) -{ - if ( term && append_sequence(F_enter_dim_mode.cap) ) - return (term->dim = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermDim (char_data*& term) -{ - // Back to normal intensity (turns off bold + dim) - if ( term && append_sequence(F_exit_dim_mode.cap) ) - { - if ( F_exit_dim_mode.caused_reset ) - reset(term); - else - { - term->bold = false; - term->dim = false; - } - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermItalic (char_data*& term) -{ - if ( term && append_sequence(F_enter_italics_mode.cap) ) - return (term->italic = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermItalic (char_data*& term) -{ - if ( term && append_sequence(F_exit_italics_mode.cap) ) - { - if ( F_exit_italics_mode.caused_reset ) - reset(term); - else - term->italic = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermUnderline (char_data*& term) -{ - if ( term && append_sequence(F_enter_underline_mode.cap) ) - return (term->underline = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermUnderline (char_data*& term) -{ - // Turns off every underlining - if ( term && append_sequence(F_exit_underline_mode.cap) ) - { - if ( F_exit_underline_mode.caused_reset ) - reset(term); - else - { - term->underline = false; - term->dbl_underline = false; - } - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermBlink (char_data*& term) -{ - if ( term && append_sequence(F_enter_blink_mode.cap) ) - return (term->blink = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermBlink (char_data*& term) -{ - if ( term && append_sequence(F_exit_blink_mode.cap) ) - { - if ( F_exit_blink_mode.caused_reset ) - reset(term); - else - term->blink = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermReverse (char_data*& term) -{ - if ( term && append_sequence(F_enter_reverse_mode.cap) ) - return (term->reverse = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermReverse (char_data*& term) -{ - if ( term && append_sequence(F_exit_reverse_mode.cap) ) - { - if ( F_exit_reverse_mode.caused_reset ) - reset(term); - else - term->reverse = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermStandout (char_data*& term) -{ - if ( term && append_sequence(F_enter_standout_mode.cap) ) - return (term->standout = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermStandout (char_data*& term) -{ - if ( term && append_sequence(F_exit_standout_mode.cap) ) - { - if ( F_exit_standout_mode.caused_reset ) - reset(term); - else - term->standout = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermInvisible (char_data*& term) -{ - if ( term && append_sequence(F_enter_secure_mode.cap) ) - return (term->invisible = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermInvisible (char_data*& term) -{ - if ( term && append_sequence(F_exit_secure_mode.cap) ) - { - if ( F_exit_secure_mode.caused_reset ) - reset(term); - else - term->invisible = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermProtected (char_data*& term) -{ - if ( term && append_sequence(F_enter_protected_mode.cap) ) - return (term->protect = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermProtected (char_data*& term) -{ - if ( term && append_sequence(F_exit_protected_mode.cap) ) - { - if ( F_exit_protected_mode.caused_reset ) - reset(term); - else - term->protect = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermCrossedOut (char_data*& term) -{ - if ( term && append_sequence(F_enter_crossed_out_mode.cap) ) - return (term->crossed_out = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermCrossedOut (char_data*& term) -{ - if ( term && append_sequence(F_exit_crossed_out_mode.cap) ) - { - if ( F_exit_crossed_out_mode.caused_reset ) - reset(term); - else - term->crossed_out = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermDoubleUnderline (char_data*& term) -{ - if ( term && append_sequence(F_enter_dbl_underline_mode.cap) ) - return (term->dbl_underline = true); - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermDoubleUnderline (char_data*& term) -{ - // Turns off every underlining - if ( term && append_sequence(F_exit_dbl_underline_mode.cap) ) - { - if ( F_exit_dbl_underline_mode.caused_reset ) - reset(term); - else - { - term->underline = false; - term->dbl_underline = false; - } - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -bool FOptiAttr::setTermAttributes ( char_data*& term - , bool p1, bool p2, bool p3 - , bool p4, bool p5, bool p6 - , bool p7, bool p8, bool p9 ) -{ - if ( term && F_set_attributes.cap ) - { - char* sgr = tparm ( F_set_attributes.cap - , p1, p2, p3, p4, p5, p6, p7, p8, p9 ); - - append_sequence (sgr); - - resetColor(term); - term->standout = p1; - term->underline = p2; - term->reverse = p3; - term->blink = p4; - term->dim = p5; - term->bold = p6; - term->invisible = p7; - term->protect = p8; - term->alt_charset = p9; - term->pc_charset = false; - term->italic = false; - term->crossed_out = false; - term->dbl_underline = false; - - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermAttributes (char_data*& term) -{ - if ( term && replace_sequence(F_exit_attribute_mode.cap) ) - { - reset(term); - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermAltCharset (char_data*& term) -{ - if ( term && append_sequence(F_enter_alt_charset_mode.cap) ) - { - term->alt_charset = true; - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermAltCharset (char_data*& term) -{ - if ( term && append_sequence(F_exit_alt_charset_mode.cap) ) - { - term->alt_charset = false; - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::setTermPCcharset (char_data*& term) -{ - if ( term && append_sequence(F_enter_pc_charset_mode.cap) ) - { - term->pc_charset = true; - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -inline bool FOptiAttr::unsetTermPCcharset (char_data*& term) -{ - if ( term && append_sequence(F_exit_pc_charset_mode.cap) ) - { - term->pc_charset = false; - return true; - } - else - return false; -} - -//---------------------------------------------------------------------- -bool FOptiAttr::setTermDefaultColor (char_data*& term) -{ - if ( ! term ) - return false; - - if ( append_sequence(F_orig_pair.cap) ) - { - term->fg_color = Default; - term->bg_color = Default; - return true; - } - else if ( append_sequence(F_orig_colors.cap) ) - { - term->fg_color = Default; - term->bg_color = Default; - return true; - } - else if ( ansi_default_color ) - { - char* sgr_39_49 = const_cast(CSI "39;49m"); - append_sequence (sgr_39_49); - term->fg_color = Default; - term->bg_color = Default; - return true; - } - else - return false; -} - - // public methods of FOptiAttr -//---------------------------------------------------------------------- -short FOptiAttr::vga2ansi (register short color) -{ - // VGA | ANSI - // i R G B | i B G R - //---------+--------- - // 0 0 0 0 | 0 0 0 0 i = intensity bit - // 0 0 0 1 | 0 1 0 0 R = red - // 0 0 1 0 | 0 0 1 0 G = green - // 0 0 1 1 | 0 1 1 0 B = blue - // 0 1 0 0 | 0 0 0 1 - // 0 1 0 1 | 0 1 0 1 - // 0 1 1 0 | 0 0 1 1 - // 0 1 1 1 | 0 1 1 1 - // 1 0 0 0 | 1 0 0 0 - // 1 0 0 1 | 1 1 0 0 - // 1 0 1 0 | 1 0 1 0 - // 1 0 1 1 | 1 1 1 0 - // 1 1 0 0 | 1 0 0 1 - // 1 1 0 1 | 1 1 0 1 - // 1 1 1 0 | 1 0 1 1 - // 1 1 1 1 | 1 1 1 1 - - if ( color >= 0 && color < 16 ) - { - static const short lookup_table[] = - { - 0, 4, 2, 6, 1, 5, 3, 7, - 8, 12, 10, 14, 9, 13, 11, 15 - }; - - color = lookup_table[color]; - } - - return color; -} - //---------------------------------------------------------------------- void FOptiAttr::set_enter_bold_mode (char*& cap) { @@ -1324,6 +459,43 @@ void FOptiAttr::init() F_exit_standout_mode.caused_reset = true; } +//---------------------------------------------------------------------- +short FOptiAttr::vga2ansi (register short color) +{ + // VGA | ANSI + // i R G B | i B G R + //---------+--------- + // 0 0 0 0 | 0 0 0 0 i = intensity bit + // 0 0 0 1 | 0 1 0 0 R = red + // 0 0 1 0 | 0 0 1 0 G = green + // 0 0 1 1 | 0 1 1 0 B = blue + // 0 1 0 0 | 0 0 0 1 + // 0 1 0 1 | 0 1 0 1 + // 0 1 1 0 | 0 0 1 1 + // 0 1 1 1 | 0 1 1 1 + // 1 0 0 0 | 1 0 0 0 + // 1 0 0 1 | 1 1 0 0 + // 1 0 1 0 | 1 0 1 0 + // 1 0 1 1 | 1 1 1 0 + // 1 1 0 0 | 1 0 0 1 + // 1 1 0 1 | 1 1 0 1 + // 1 1 1 0 | 1 0 1 1 + // 1 1 1 1 | 1 1 1 1 + + if ( color >= 0 && color < 16 ) + { + static const short lookup_table[] = + { + 0, 4, 2, 6, 1, 5, 3, 7, + 8, 12, 10, 14, 9, 13, 11, 15 + }; + + color = lookup_table[color]; + } + + return color; +} + //---------------------------------------------------------------------- char* FOptiAttr::changeAttribute (char_data*& term, char_data*& next) { @@ -1535,3 +707,833 @@ char* FOptiAttr::changeAttribute (char_data*& term, char_data*& next) return attr_buf; } + + +// private methods of FOptiAttr +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermBold (char_data*& term) +{ + if ( term && append_sequence(F_enter_bold_mode.cap) ) + return (term->bold = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermBold (char_data*& term) +{ + // Back to normal intensity (turns off bold + dim) + if ( append_sequence(F_exit_bold_mode.cap) ) + { + if ( F_exit_bold_mode.caused_reset ) + reset(term); + else + { + term->bold = false; + term->dim = false; + } + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermDim (char_data*& term) +{ + if ( term && append_sequence(F_enter_dim_mode.cap) ) + return (term->dim = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermDim (char_data*& term) +{ + // Back to normal intensity (turns off bold + dim) + if ( term && append_sequence(F_exit_dim_mode.cap) ) + { + if ( F_exit_dim_mode.caused_reset ) + reset(term); + else + { + term->bold = false; + term->dim = false; + } + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermItalic (char_data*& term) +{ + if ( term && append_sequence(F_enter_italics_mode.cap) ) + return (term->italic = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermItalic (char_data*& term) +{ + if ( term && append_sequence(F_exit_italics_mode.cap) ) + { + if ( F_exit_italics_mode.caused_reset ) + reset(term); + else + term->italic = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermUnderline (char_data*& term) +{ + if ( term && append_sequence(F_enter_underline_mode.cap) ) + return (term->underline = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermUnderline (char_data*& term) +{ + // Turns off every underlining + if ( term && append_sequence(F_exit_underline_mode.cap) ) + { + if ( F_exit_underline_mode.caused_reset ) + reset(term); + else + { + term->underline = false; + term->dbl_underline = false; + } + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermBlink (char_data*& term) +{ + if ( term && append_sequence(F_enter_blink_mode.cap) ) + return (term->blink = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermBlink (char_data*& term) +{ + if ( term && append_sequence(F_exit_blink_mode.cap) ) + { + if ( F_exit_blink_mode.caused_reset ) + reset(term); + else + term->blink = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermReverse (char_data*& term) +{ + if ( term && append_sequence(F_enter_reverse_mode.cap) ) + return (term->reverse = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermReverse (char_data*& term) +{ + if ( term && append_sequence(F_exit_reverse_mode.cap) ) + { + if ( F_exit_reverse_mode.caused_reset ) + reset(term); + else + term->reverse = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermStandout (char_data*& term) +{ + if ( term && append_sequence(F_enter_standout_mode.cap) ) + return (term->standout = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermStandout (char_data*& term) +{ + if ( term && append_sequence(F_exit_standout_mode.cap) ) + { + if ( F_exit_standout_mode.caused_reset ) + reset(term); + else + term->standout = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermInvisible (char_data*& term) +{ + if ( term && append_sequence(F_enter_secure_mode.cap) ) + return (term->invisible = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermInvisible (char_data*& term) +{ + if ( term && append_sequence(F_exit_secure_mode.cap) ) + { + if ( F_exit_secure_mode.caused_reset ) + reset(term); + else + term->invisible = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermProtected (char_data*& term) +{ + if ( term && append_sequence(F_enter_protected_mode.cap) ) + return (term->protect = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermProtected (char_data*& term) +{ + if ( term && append_sequence(F_exit_protected_mode.cap) ) + { + if ( F_exit_protected_mode.caused_reset ) + reset(term); + else + term->protect = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermCrossedOut (char_data*& term) +{ + if ( term && append_sequence(F_enter_crossed_out_mode.cap) ) + return (term->crossed_out = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermCrossedOut (char_data*& term) +{ + if ( term && append_sequence(F_exit_crossed_out_mode.cap) ) + { + if ( F_exit_crossed_out_mode.caused_reset ) + reset(term); + else + term->crossed_out = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermDoubleUnderline (char_data*& term) +{ + if ( term && append_sequence(F_enter_dbl_underline_mode.cap) ) + return (term->dbl_underline = true); + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermDoubleUnderline (char_data*& term) +{ + // Turns off every underlining + if ( term && append_sequence(F_exit_dbl_underline_mode.cap) ) + { + if ( F_exit_dbl_underline_mode.caused_reset ) + reset(term); + else + { + term->underline = false; + term->dbl_underline = false; + } + + return true; + } + else + return false; +} +//---------------------------------------------------------------------- +bool FOptiAttr::setTermAttributes ( char_data*& term + , bool p1, bool p2, bool p3 + , bool p4, bool p5, bool p6 + , bool p7, bool p8, bool p9 ) +{ + if ( term && F_set_attributes.cap ) + { + char* sgr = tparm ( F_set_attributes.cap + , p1, p2, p3, p4, p5, p6, p7, p8, p9 ); + + append_sequence (sgr); + + resetColor(term); + term->standout = p1; + term->underline = p2; + term->reverse = p3; + term->blink = p4; + term->dim = p5; + term->bold = p6; + term->invisible = p7; + term->protect = p8; + term->alt_charset = p9; + term->pc_charset = false; + term->italic = false; + term->crossed_out = false; + term->dbl_underline = false; + + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermAttributes (char_data*& term) +{ + if ( term && replace_sequence(F_exit_attribute_mode.cap) ) + { + reset(term); + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermAltCharset (char_data*& term) +{ + if ( term && append_sequence(F_enter_alt_charset_mode.cap) ) + { + term->alt_charset = true; + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermAltCharset (char_data*& term) +{ + if ( term && append_sequence(F_exit_alt_charset_mode.cap) ) + { + term->alt_charset = false; + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::setTermPCcharset (char_data*& term) +{ + if ( term && append_sequence(F_enter_pc_charset_mode.cap) ) + { + term->pc_charset = true; + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::unsetTermPCcharset (char_data*& term) +{ + if ( term && append_sequence(F_exit_pc_charset_mode.cap) ) + { + term->pc_charset = false; + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +bool FOptiAttr::setTermDefaultColor (char_data*& term) +{ + if ( ! term ) + return false; + + if ( append_sequence(F_orig_pair.cap) ) + { + term->fg_color = Default; + term->bg_color = Default; + return true; + } + else if ( append_sequence(F_orig_colors.cap) ) + { + term->fg_color = Default; + term->bg_color = Default; + return true; + } + else if ( ansi_default_color ) + { + char* sgr_39_49 = const_cast(CSI "39;49m"); + append_sequence (sgr_39_49); + term->fg_color = Default; + term->bg_color = Default; + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::hasColor (char_data*& attr) +{ + if ( attr && attr->fg_color < 0 && attr->bg_color < 0 ) + return false; + else + return true; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::hasAttribute (char_data*& attr) +{ + if ( attr ) + { + return attr->bold == 1 + || attr->dim == 1 + || attr->italic == 1 + || attr->underline == 1 + || attr->blink == 1 + || attr->reverse == 1 + || attr->standout == 1 + || attr->invisible == 1 + || attr->protect == 1 + || attr->crossed_out == 1 + || attr->dbl_underline == 1 + || attr->alt_charset == 1 + || attr->pc_charset == 1; + } + + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::colorChange (char_data*& term, char_data*& next) +{ + if ( term && next ) + { + return bool ( fake_reverse + || term->fg_color != next->fg_color + || term->bg_color != next->bg_color ); + } + + return false; +} + +//---------------------------------------------------------------------- +inline void FOptiAttr::resetColor (char_data*& attr) +{ + if ( attr ) + { + attr->fg_color = Default; + attr->bg_color = Default; + } +} + +//---------------------------------------------------------------------- +inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr) +{ + // ignore attributes which can not combined with a color + + enum attr_modes + { + standout_mode = 1, + underline_mode = 2, + reverse_mode = 4, + blink_mode = 8, + dim_mode = 16, + bold_mode = 32, + invisible_mode = 64, + protected_mode = 128, + alt_charset_mode = 256, + horizontal_mode = 512, + left_mode = 1024, + low_mode = 2048, + right_mode = 4096, + top_mode = 8192, + vertical_mode = 16384, + italic_mode = 32768, + no_mode = 65536 + }; + + if ( ! attr ) + return; + + if ( hasColor(attr) && attr_without_color > 0 ) + { + for (int bit=1; bit < no_mode; bit <<= 1) + { + switch ( bit & attr_without_color ) + { + case standout_mode: + if ( attr->standout ) + attr->standout = false; + break; + + case underline_mode: + if ( attr->underline ) + attr->underline = false; + break; + + case reverse_mode: + if ( attr->reverse ) + { + attr->reverse = false; + + if ( attr->fg_color != attr->bg_color ) + fake_reverse = true; + } + break; + + case blink_mode: + if ( attr->blink ) + attr->blink = false; + break; + + case dim_mode: + if ( attr->dim ) + attr->dim = false; + break; + + case bold_mode: + if ( attr->bold ) + attr->bold = false; + break; + + case invisible_mode: + if ( attr->invisible ) + attr->invisible = false; + break; + + case protected_mode: + if ( attr->protect ) + attr->protect = false; + break; + + case alt_charset_mode: + if ( attr->alt_charset ) + attr->alt_charset = false; + break; + + case italic_mode: + if ( attr->italic ) + attr->italic = false; + break; + + default: + break; + } + } + } +} + +//---------------------------------------------------------------------- +void FOptiAttr::change_color (char_data*& term, char_data*& next) +{ + char* color_str; + char* AF = F_set_a_foreground.cap; + char* AB = F_set_a_background.cap; + char* Sf = F_set_foreground.cap; + char* Sb = F_set_background.cap; + char* sp = F_set_color_pair.cap; + short fg, bg; + + if ( monochron || ! (term && next) ) + return; + + fg = next->fg_color; + bg = next->bg_color; + + if ( fg == Default || bg == Default ) + { + if ( ansi_default_color ) + { + if ( fg == Default && term->fg_color != Default + && bg == Default && term->bg_color != Default ) + { + setTermDefaultColor(term); + } + else if ( fg == Default && term->fg_color != Default ) + { + char* sgr_39 = const_cast(CSI "39m"); + append_sequence (sgr_39); + term->fg_color = Default; + } + else if ( bg == Default && term->bg_color != Default ) + { + char* sgr_49; + char* op = F_orig_pair.cap; + + if ( op && std::strncmp (op, CSI "39;49;25m", 11) == 0 ) + sgr_49 = const_cast(CSI "49;25m"); + else + sgr_49 = const_cast(CSI "49m"); + + append_sequence (sgr_49); + term->bg_color = Default; + } + } + else if ( ! setTermDefaultColor(term) ) + { + // fallback to gray on black + fg = next->fg_color = LightGray; + bg = next->bg_color = Black; + } + } + + if ( ! fake_reverse && fg < 0 && bg < 0 ) + return; + + if ( fake_reverse ) + { + std::swap (fg, bg); + + if ( fg == Default || bg == Default ) + setTermDefaultColor(term); + } + + if ( AF && AB ) + { + short ansi_fg = vga2ansi(fg); + short ansi_bg = vga2ansi(bg); + + if ( cygwin_terminal ) + { + // reset blink and bold mode from colors > 7 + char* rst = const_cast(CSI "m"); + append_sequence (rst); + reset(term); + + if ( ansi_fg != Default ) + { + color_str = tparm(AF, ansi_fg); + + if ( color_str ) + append_sequence (color_str); + } + + if ( ansi_bg != Default ) + { + color_str = tparm(AB, ansi_bg); + if ( color_str ) + append_sequence (color_str); + } + } + else + { + if ( term->fg_color != fg && (color_str = tparm(AF, ansi_fg)) ) + append_sequence (color_str); + + if ( term->bg_color != bg && (color_str = tparm(AB, ansi_bg)) ) + append_sequence (color_str); + } + } + else if ( Sf && Sb ) + { + if ( term->fg_color != fg && (color_str = tparm(Sf, fg)) ) + append_sequence (color_str); + + if ( term->bg_color != bg && (color_str = tparm(Sb, bg)) ) + append_sequence (color_str); + } + else if ( sp ) + { + fg = vga2ansi(fg); + bg = vga2ansi(bg); + + if ( (color_str = tparm(sp, fg, bg)) ) + append_sequence (color_str); + } + + term->fg_color = next->fg_color; + term->bg_color = next->bg_color; +} + +//---------------------------------------------------------------------- +inline void FOptiAttr::resetAttribute (char_data*& attr) +{ + if ( attr ) + { + attr->bold = \ + attr->dim = \ + attr->italic = \ + attr->underline = \ + attr->blink = \ + attr->reverse = \ + attr->standout = \ + attr->invisible = \ + attr->protect = \ + attr->crossed_out = \ + attr->dbl_underline = \ + attr->alt_charset = \ + attr->pc_charset = 0; + } +} + +//---------------------------------------------------------------------- +inline void FOptiAttr::reset (char_data*& attr) +{ + if ( attr ) + { + resetAttribute(attr); + resetColor(attr); + } +} + +//---------------------------------------------------------------------- +bool FOptiAttr::caused_reset_attributes (char*& cap, uChar test) +{ + // test if "cap" reset all attributes + char* ue = F_exit_underline_mode.cap; + char* se = F_exit_standout_mode.cap; + char* me = F_exit_attribute_mode.cap; + + if ( cap ) + { + if ( (test & test_ansi_reset) && std::strncmp (cap, CSI "m", 3) == 0 ) + return true; + + if ( (test & test_adm3_reset) && std::strncmp (cap, ESC "G0", 3) == 0 ) + return true; + + if ( (test & same_like_ue) && ue && std::strcmp (cap, ue) == 0 ) + return true; + + if ( (test & same_like_se) && se && std::strcmp (cap, se) == 0 ) + return true; + + if ( (test & same_like_me) && me && std::strcmp (cap, me) == 0 ) + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +inline void FOptiAttr::detectSwitchOn (char_data*& term, char_data*& next) +{ + if ( ! (term && next) ) + return; + + on.bold = ! term->bold && next->bold; + on.dim = ! term->dim && next->dim; + on.italic = ! term->italic && next->italic; + on.underline = ! term->underline && next->underline; + on.blink = ! term->blink && next->blink; + on.reverse = ! term->reverse && next->reverse; + on.standout = ! term->standout && next->standout; + on.invisible = ! term->invisible && next->invisible; + on.protect = ! term->protect && next->protect; + on.crossed_out = ! term->crossed_out && next->crossed_out; + on.dbl_underline = ! term->dbl_underline && next->dbl_underline; + on.alt_charset = ! term->alt_charset && next->alt_charset; + on.pc_charset = ! term->pc_charset && next->pc_charset; +} + +//---------------------------------------------------------------------- +inline void FOptiAttr::detectSwitchOff (char_data*& term, char_data*& next) +{ + if ( ! (term && next) ) + return; + + off.bold = term->bold && ! next->bold; + off.dim = term->dim && ! next->dim; + off.italic = term->italic && ! next->italic; + off.underline = term->underline && ! next->underline; + off.blink = term->blink && ! next->blink; + off.reverse = term->reverse && ! next->reverse; + off.standout = term->standout && ! next->standout; + off.invisible = term->invisible && ! next->invisible; + off.protect = term->protect && ! next->protect; + off.crossed_out = term->crossed_out && ! next->crossed_out; + off.dbl_underline = term->dbl_underline && ! next->dbl_underline; + off.alt_charset = term->alt_charset && ! next->alt_charset; + off.pc_charset = term->pc_charset && ! next->pc_charset; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::switchOn() +{ + char_data* on_ptr = &on; + return hasAttribute(on_ptr); +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::switchOff() +{ + char_data* off_ptr = &off; + return hasAttribute(off_ptr); +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::append_sequence (char*& seq) +{ + if ( seq ) + { + std::strncat (attr_ptr, seq, sizeof(attr_buf) - std::strlen(attr_ptr) - 1 ); + return true; + } + else + return false; +} + +//---------------------------------------------------------------------- +inline bool FOptiAttr::replace_sequence (char*& seq) +{ + if ( seq ) + { + std::strncpy (attr_ptr, seq, sizeof(attr_buf) - 1); + return true; + } + else + return false; +} diff --git a/src/foptiattr.h b/src/foptiattr.h index a61c15f6..8f200490 100644 --- a/src/foptiattr.h +++ b/src/foptiattr.h @@ -20,6 +20,8 @@ #define ESC "\033" // Escape #define CSI ESC "[" // Control sequence introducer (7-bit) +typedef unsigned char uChar; + //---------------------------------------------------------------------- // class FOptiAttr @@ -30,79 +32,8 @@ class FOptiAttr { - private: - typedef unsigned char uChar; - - enum init_reset_tests - { - no_test = 0x00, - test_ansi_reset = 0x01, // ANSI X3.64 terminal - test_adm3_reset = 0x02, // Lear Siegler ADM-3 terminal - same_like_ue = 0x04, - same_like_se = 0x08, - same_like_me = 0x10, - all_tests = 0x1f - }; - - enum default_color - { - Default = -1, - Black = 0, - LightGray = 7 - }; - - typedef struct - { - char* cap; - bool caused_reset; - } capability; - - capability F_enter_bold_mode; - capability F_exit_bold_mode; - capability F_enter_dim_mode; - capability F_exit_dim_mode; - capability F_enter_italics_mode; - capability F_exit_italics_mode; - capability F_enter_underline_mode; - capability F_exit_underline_mode; - capability F_enter_blink_mode; - capability F_exit_blink_mode; - capability F_enter_reverse_mode; - capability F_exit_reverse_mode; - capability F_enter_standout_mode; - capability F_exit_standout_mode; - capability F_enter_secure_mode; - capability F_exit_secure_mode; - capability F_enter_protected_mode; - capability F_exit_protected_mode; - capability F_enter_crossed_out_mode; - capability F_exit_crossed_out_mode; - capability F_enter_dbl_underline_mode; - capability F_exit_dbl_underline_mode; - capability F_set_attributes; - capability F_exit_attribute_mode; - capability F_enter_alt_charset_mode; - capability F_exit_alt_charset_mode; - capability F_enter_pc_charset_mode; - capability F_exit_pc_charset_mode; - capability F_set_a_foreground; - capability F_set_a_background; - capability F_set_foreground; - capability F_set_background; - capability F_set_color_pair; - capability F_orig_pair; - capability F_orig_colors; - - int max_color; - int attr_without_color; - bool ansi_default_color; - bool monochron; - bool fake_reverse; - bool cygwin_terminal; - char attr_buf[8192]; - char* attr_ptr; - public: + // Typedef typedef struct { int code; // character code @@ -126,73 +57,17 @@ class FOptiAttr uChar inherit_bg : 1; // inherit background } char_data; - private: - char_data on; - char_data off; - - private: - // Disable copy constructor - FOptiAttr (const FOptiAttr&); - // Disable assignment operator (=) - FOptiAttr& operator = (const FOptiAttr&); - - bool hasColor (char_data*&); - bool colorChange (char_data*&, char_data*&); - void resetColor (char_data*&); - void prevent_no_color_video_attributes (char_data*&); - void change_color (char_data*&, char_data*&); - bool hasAttribute (char_data*&); - bool hasNoAttribute (char_data*&); - void resetAttribute (char_data*&); - void reset (char_data*&); - bool caused_reset_attributes (char*&, uChar = all_tests); - void detectSwitchOn (char_data*&, char_data*&); - void detectSwitchOff (char_data*&, char_data*&); - bool switchOn(); - bool switchOff(); - bool append_sequence (char*&); - bool replace_sequence (char*&); - bool setTermBold (char_data*&); - bool unsetTermBold (char_data*&); - bool setTermDim (char_data*&); - bool unsetTermDim (char_data*&); - bool setTermItalic (char_data*&); - bool unsetTermItalic (char_data*&); - bool setTermUnderline (char_data*&); - bool unsetTermUnderline (char_data*&); - bool setTermBlink (char_data*&); - bool unsetTermBlink (char_data*&); - bool setTermReverse (char_data*&); - bool unsetTermReverse (char_data*&); - bool setTermStandout (char_data*&); - bool unsetTermStandout (char_data*&); - bool setTermInvisible (char_data*&); - bool unsetTermInvisible (char_data*&); - bool setTermProtected (char_data*&); - bool unsetTermProtected (char_data*&); - bool setTermCrossedOut (char_data*&); - bool unsetTermCrossedOut (char_data*&); - bool setTermDoubleUnderline (char_data*&); - bool unsetTermDoubleUnderline (char_data*&); - bool setTermAttributes ( char_data*& - , bool, bool, bool - , bool, bool, bool - , bool, bool, bool ); - bool unsetTermAttributes (char_data*&); - bool setTermAltCharset (char_data*&); - bool unsetTermAltCharset (char_data*&); - bool setTermPCcharset (char_data*&); - bool unsetTermPCcharset (char_data*&); - bool setTermDefaultColor (char_data*&); - - public: // Constructor explicit FOptiAttr(); + // Destructor ~FOptiAttr(); - static short vga2ansi (register short); + // Friend operator functions + friend bool operator == (const char_data&, const char_data&); + friend bool operator != (const char_data&, const char_data&); + // Mutators void setMaxColor (int&); void setNoColorVideo (int); void setDefaultColorSupport(); @@ -232,37 +107,153 @@ class FOptiAttr void set_term_color_pair (char*&); void set_orig_pair (char*&); void set_orig_orig_colors (char*&); - void init(); - char* changeAttribute (char_data*&, char_data*&); + // Methods + void init(); + static short vga2ansi (register short); + char* changeAttribute (char_data*&, char_data*&); - friend bool operator == (const char_data&, const char_data&); - friend bool operator != (const char_data&, const char_data&); + private: + // Typedefs and Enumerations + typedef unsigned char uChar; + + typedef struct + { + char* cap; + bool caused_reset; + } capability; + + enum init_reset_tests + { + no_test = 0x00, + test_ansi_reset = 0x01, // ANSI X3.64 terminal + test_adm3_reset = 0x02, // Lear Siegler ADM-3 terminal + same_like_ue = 0x04, + same_like_se = 0x08, + same_like_me = 0x10, + all_tests = 0x1f + }; + + enum default_color + { + Default = -1, + Black = 0, + LightGray = 7 + }; + + // Disable copy constructor + FOptiAttr (const FOptiAttr&); + + // Disable assignment operator (=) + FOptiAttr& operator = (const FOptiAttr&); + + // Mutators + bool setTermBold (char_data*&); + bool unsetTermBold (char_data*&); + bool setTermDim (char_data*&); + bool unsetTermDim (char_data*&); + bool setTermItalic (char_data*&); + bool unsetTermItalic (char_data*&); + bool setTermUnderline (char_data*&); + bool unsetTermUnderline (char_data*&); + bool setTermBlink (char_data*&); + bool unsetTermBlink (char_data*&); + bool setTermReverse (char_data*&); + bool unsetTermReverse (char_data*&); + bool setTermStandout (char_data*&); + bool unsetTermStandout (char_data*&); + bool setTermInvisible (char_data*&); + bool unsetTermInvisible (char_data*&); + bool setTermProtected (char_data*&); + bool unsetTermProtected (char_data*&); + bool setTermCrossedOut (char_data*&); + bool unsetTermCrossedOut (char_data*&); + bool setTermDoubleUnderline (char_data*&); + bool unsetTermDoubleUnderline (char_data*&); + bool setTermAttributes ( char_data*& + , bool, bool, bool + , bool, bool, bool + , bool, bool, bool ); + bool unsetTermAttributes (char_data*&); + bool setTermAltCharset (char_data*&); + bool unsetTermAltCharset (char_data*&); + bool setTermPCcharset (char_data*&); + bool unsetTermPCcharset (char_data*&); + bool setTermDefaultColor (char_data*&); + + // Inquiries + bool hasColor (char_data*&); + bool hasAttribute (char_data*&); + bool hasNoAttribute (char_data*&); + + // Methods + bool colorChange (char_data*&, char_data*&); + void resetColor (char_data*&); + void prevent_no_color_video_attributes (char_data*&); + void change_color (char_data*&, char_data*&); + void resetAttribute (char_data*&); + void reset (char_data*&); + bool caused_reset_attributes (char*&, uChar = all_tests); + void detectSwitchOn (char_data*&, char_data*&); + void detectSwitchOff (char_data*&, char_data*&); + bool switchOn(); + bool switchOff(); + bool append_sequence (char*&); + bool replace_sequence (char*&); + + // Data Members + capability F_enter_bold_mode; + capability F_exit_bold_mode; + capability F_enter_dim_mode; + capability F_exit_dim_mode; + capability F_enter_italics_mode; + capability F_exit_italics_mode; + capability F_enter_underline_mode; + capability F_exit_underline_mode; + capability F_enter_blink_mode; + capability F_exit_blink_mode; + capability F_enter_reverse_mode; + capability F_exit_reverse_mode; + capability F_enter_standout_mode; + capability F_exit_standout_mode; + capability F_enter_secure_mode; + capability F_exit_secure_mode; + capability F_enter_protected_mode; + capability F_exit_protected_mode; + capability F_enter_crossed_out_mode; + capability F_exit_crossed_out_mode; + capability F_enter_dbl_underline_mode; + capability F_exit_dbl_underline_mode; + capability F_set_attributes; + capability F_exit_attribute_mode; + capability F_enter_alt_charset_mode; + capability F_exit_alt_charset_mode; + capability F_enter_pc_charset_mode; + capability F_exit_pc_charset_mode; + capability F_set_a_foreground; + capability F_set_a_background; + capability F_set_foreground; + capability F_set_background; + capability F_set_color_pair; + capability F_orig_pair; + capability F_orig_colors; + + char_data on; + char_data off; + + int max_color; + int attr_without_color; + bool ansi_default_color; + bool monochron; + bool fake_reverse; + bool cygwin_terminal; + char attr_buf[8192]; + char* attr_ptr; }; #pragma pack(pop) // FOptiAttr inline functions -//---------------------------------------------------------------------- -inline void FOptiAttr::setMaxColor (int& c) -{ max_color = c; } - -//---------------------------------------------------------------------- -inline void FOptiAttr::setNoColorVideo (int attr) -{ attr_without_color = attr; } - -//---------------------------------------------------------------------- -inline void FOptiAttr::setDefaultColorSupport() -{ ansi_default_color = true; } - -//---------------------------------------------------------------------- -inline void FOptiAttr::setCygwinTerminal() -{ cygwin_terminal = true; } - -//---------------------------------------------------------------------- -inline bool FOptiAttr::hasNoAttribute (char_data*& attr) -{ return ! hasAttribute(attr); } - //---------------------------------------------------------------------- inline bool operator == ( const FOptiAttr::char_data& lhs, const FOptiAttr::char_data& rhs ) @@ -293,5 +284,24 @@ inline bool operator != ( const FOptiAttr::char_data& lhs, const FOptiAttr::char_data& rhs ) { return ! ( lhs == rhs ); } +//---------------------------------------------------------------------- +inline void FOptiAttr::setMaxColor (int& c) +{ max_color = c; } + +//---------------------------------------------------------------------- +inline void FOptiAttr::setNoColorVideo (int attr) +{ attr_without_color = attr; } + +//---------------------------------------------------------------------- +inline void FOptiAttr::setDefaultColorSupport() +{ ansi_default_color = true; } + +//---------------------------------------------------------------------- +inline void FOptiAttr::setCygwinTerminal() +{ cygwin_terminal = true; } + +//---------------------------------------------------------------------- +inline bool FOptiAttr::hasNoAttribute (char_data*& attr) +{ return ! hasAttribute(attr); } #endif // _FOPTIATTR_H diff --git a/src/foptimove.cpp b/src/foptimove.cpp index 9f1e1009..d1ce5c76 100644 --- a/src/foptimove.cpp +++ b/src/foptimove.cpp @@ -45,64 +45,32 @@ FOptiMove::~FOptiMove() // destructor { } -// private methods of FApplication -//---------------------------------------------------------------------- -void FOptiMove::calculateCharDuration() -{ - if ( baudrate != 0 ) - { - const int baudbyte = 9; // = 7 bit + 1 parity + 1 stop - char_duration = (baudbyte * 1000 * 10) - / (baudrate > 0 ? baudrate : 9600); // milliseconds - - if ( char_duration <= 0 ) - char_duration = 1; - } - else - char_duration = 1; -} - -//---------------------------------------------------------------------- -int FOptiMove::capDuration (char*& cap, int affcnt) -{ - // calculate the duration in milliseconds of a given operation - // cap - the term capability - // affcnt - the number of lines affected - - if ( ! cap ) - return LONG_DURATION; - - const char* p; - float ms = 0; - - for (p=cap; *p; p++) - { - // check for delay with padding character - if ( p[0] == '$' && p[1] == '<' && std::strchr(p, '>') ) - { - float num=0; - - for (p += 2; *p != '>'; p++) - { - if ( std::isdigit(uChar(*p)) ) - num = num * 10 + float(*p - '0'); - else if ( *p == '*' ) - num *= float(affcnt); - else if ( *p == '.' && *++p != '>' && std::isdigit(uChar(*p)) ) - num += float((*p - '0') / 10.0); - } - - ms += num * 10; - } - else - ms += float(char_duration); - } - - return int(ms); -} - - // public methods of FOptiMove +//---------------------------------------------------------------------- +void FOptiMove::setBaudRate (int baud) +{ + assert ( baud >= 0 ); + + baudrate = baud; + calculateCharDuration(); +} + +//---------------------------------------------------------------------- +void FOptiMove::setTabStop (int t) +{ + assert ( t > 0 ); + tabstop = t; +} + +//---------------------------------------------------------------------- +void FOptiMove::setTermSize (int w, int h) +{ + assert ( w > 0 ); + assert ( h > 0 ); + screen_width = w; + screen_height = h; +} + //---------------------------------------------------------------------- void FOptiMove::set_cursor_home (char*& cap) { @@ -287,28 +255,236 @@ void FOptiMove::set_parm_right_cursor (char*& cap) } //---------------------------------------------------------------------- -void FOptiMove::setBaudRate (int baud) +char* FOptiMove::moveCursor (int xold, int yold, int xnew, int ynew) { - assert ( baud >= 0 ); + char null_result[sizeof(move_buf)]; + char* null_ptr = null_result; + char* move_ptr = move_buf; + char* move_xy; + int method = 0; + int new_time; + int move_time = LONG_DURATION; - baudrate = baud; - calculateCharDuration(); + // Method 0: direct cursor addressing + move_xy = tgoto(F_cursor_address.cap, xnew, ynew); + if ( move_xy ) + { + method = 0; + std::strncpy (move_ptr, move_xy, sizeof(move_buf) - 1); + move_time = F_cursor_address.duration; + + if ( xold < 0 + || yold < 0 + || isTwoDirectionMove (xold, yold, xnew, ynew) + || isWideMove (xold, yold, xnew, ynew) ) + { + return ( move_time < LONG_DURATION ) ? move_buf : 0; + } + } + + // Method 1: local movement + if ( xold >= 0 && yold >= 0 ) + { + new_time = relativeMove (null_ptr, xold, yold, xnew, ynew); + + if ( new_time < LONG_DURATION && new_time < move_time ) + { + method = 1; + move_time = new_time; + } + } + + // Method 2: carriage-return + local movement + if ( yold >= 0 && F_carriage_return.cap ) + { + new_time = relativeMove (null_ptr, 0, yold, xnew, ynew); + + if ( new_time < LONG_DURATION + && F_carriage_return.duration + new_time < move_time ) + { + method = 2; + move_time = F_carriage_return.duration + new_time; + } + } + + // Method 3: home-cursor + local movement + if ( F_cursor_home.cap ) + { + new_time = relativeMove (null_ptr, 0, 0, xnew, ynew); + + if ( new_time < LONG_DURATION + && F_cursor_home.duration + new_time < move_time ) + { + method = 3; + move_time = F_cursor_home.duration + new_time; + } + } + + // Method 4: home-down + local movement + if ( F_cursor_to_ll.cap ) + { + new_time = relativeMove (null_ptr, 0, screen_height-1, xnew, ynew); + + if ( new_time < LONG_DURATION + && F_cursor_to_ll.duration + new_time < move_time ) + { + method = 4; + move_time = F_cursor_to_ll.duration + new_time; + } + } + + // Method 5: left margin for wrap to right-hand side + if ( automatic_left_margin + && ! eat_nl_glitch + && yold > 0 + && F_cursor_left.cap ) + { + new_time = relativeMove (null_ptr, screen_width-1, yold-1, xnew, ynew); + + if ( new_time < LONG_DURATION + && F_carriage_return.cap + && F_carriage_return.duration + + F_cursor_left.duration + new_time < move_time ) + { + method = 5; + move_time = F_carriage_return.duration + + F_cursor_left.duration + new_time; + } + } + + if ( method ) + { + switch ( method ) + { + case 1: + relativeMove (move_ptr, xold, yold, xnew, ynew); + break; + + case 2: + if ( F_carriage_return.cap ) + { + std::strncpy (move_ptr, F_carriage_return.cap, sizeof(move_buf) - 1); + move_ptr += F_carriage_return.length; + relativeMove (move_ptr, 0, yold, xnew, ynew); + } + break; + + case 3: + std::strncpy (move_ptr, F_cursor_home.cap, sizeof(move_buf) - 1); + move_ptr += F_cursor_home.length; + relativeMove (move_ptr, 0, 0, xnew, ynew); + break; + + case 4: + std::strncpy (move_ptr, F_cursor_to_ll.cap, sizeof(move_buf) - 1); + move_ptr += F_cursor_to_ll.length; + relativeMove (move_ptr, 0, screen_height-1, xnew, ynew); + break; + + case 5: + move_buf[0] = '\0'; + + if ( xold >= 0 ) + std::strncat ( move_ptr + , F_carriage_return.cap + , sizeof(move_buf) - std::strlen(move_ptr) - 1 ); + + std::strncat ( move_ptr + , F_cursor_left.cap + , sizeof(move_buf) - std::strlen(move_ptr) - 1 ); + move_ptr += std::strlen(move_buf); + relativeMove (move_ptr, screen_width-1, yold-1, xnew, ynew); + break; + + default: + break; + } + } + + if ( move_time < LONG_DURATION ) + return move_buf; + else + return 0; } //---------------------------------------------------------------------- -void FOptiMove::setTabStop (int t) +void FOptiMove::printDurations() { - assert ( t > 0 ); - tabstop = t; + std::printf (" speed: %d baud\n", baudrate); + std::printf (" char_duration: %d ms\n", char_duration); + std::printf (" cursor_home: %d ms\n", F_cursor_home.duration); + std::printf (" cursor_to_ll: %d ms\n", F_cursor_to_ll.duration); + std::printf (" carriage_return: %d ms\n", F_carriage_return.duration); + std::printf (" tab: %d ms\n", F_tab.duration); + std::printf (" back_tab: %d ms\n", F_back_tab.duration); + std::printf (" cursor_up: %d ms\n", F_cursor_up.duration); + std::printf (" cursor_down: %d ms\n", F_cursor_down.duration); + std::printf (" cursor_left: %d ms\n", F_cursor_left.duration); + std::printf (" cursor_right: %d ms\n", F_cursor_right.duration); + std::printf (" cursor_address: %d ms\n", F_cursor_address.duration); + std::printf (" column_address: %d ms\n", F_column_address.duration); + std::printf (" row_address: %d ms\n", F_row_address.duration); + std::printf (" parm_up_cursor: %d ms\n", F_parm_up_cursor.duration); + std::printf (" parm_down_cursor: %d ms\n", F_parm_down_cursor.duration); + std::printf (" parm_left_cursor: %d ms\n", F_parm_left_cursor.duration); + std::printf ("parm_right_cursor: %d ms\n", F_parm_right_cursor.duration); +} + + +// private methods of FApplication +//---------------------------------------------------------------------- +void FOptiMove::calculateCharDuration() +{ + if ( baudrate != 0 ) + { + const int baudbyte = 9; // = 7 bit + 1 parity + 1 stop + char_duration = (baudbyte * 1000 * 10) + / (baudrate > 0 ? baudrate : 9600); // milliseconds + + if ( char_duration <= 0 ) + char_duration = 1; + } + else + char_duration = 1; } //---------------------------------------------------------------------- -void FOptiMove::setTermSize (int w, int h) +int FOptiMove::capDuration (char*& cap, int affcnt) { - assert ( w > 0 ); - assert ( h > 0 ); - screen_width = w; - screen_height = h; + // calculate the duration in milliseconds of a given operation + // cap - the term capability + // affcnt - the number of lines affected + + if ( ! cap ) + return LONG_DURATION; + + const char* p; + float ms = 0; + + for (p=cap; *p; p++) + { + // check for delay with padding character + if ( p[0] == '$' && p[1] == '<' && std::strchr(p, '>') ) + { + float num=0; + + for (p += 2; *p != '>'; p++) + { + if ( std::isdigit(uChar(*p)) ) + num = num * 10 + float(*p - '0'); + else if ( *p == '*' ) + num *= float(affcnt); + else if ( *p == '.' && *++p != '>' && std::isdigit(uChar(*p)) ) + num += float((*p - '0') / 10.0); + } + + ms += num * 10; + } + else + ms += float(char_duration); + } + + return int(ms); } //---------------------------------------------------------------------- @@ -558,179 +734,3 @@ inline bool FOptiMove::isWideMove ( int xold, int yold && (xnew < screen_width - 1 - MOVE_LIMIT) && (std::abs(xnew-xold) + std::abs(ynew-yold) > MOVE_LIMIT) ); } - -//---------------------------------------------------------------------- -char* FOptiMove::moveCursor (int xold, int yold, int xnew, int ynew) -{ - char null_result[sizeof(move_buf)]; - char* null_ptr = null_result; - char* move_ptr = move_buf; - char* move_xy; - int method = 0; - int new_time; - int move_time = LONG_DURATION; - - // Method 0: direct cursor addressing - move_xy = tgoto(F_cursor_address.cap, xnew, ynew); - if ( move_xy ) - { - method = 0; - std::strncpy (move_ptr, move_xy, sizeof(move_buf) - 1); - move_time = F_cursor_address.duration; - - if ( xold < 0 - || yold < 0 - || isTwoDirectionMove (xold, yold, xnew, ynew) - || isWideMove (xold, yold, xnew, ynew) ) - { - return ( move_time < LONG_DURATION ) ? move_buf : 0; - } - } - - // Method 1: local movement - if ( xold >= 0 && yold >= 0 ) - { - new_time = relativeMove (null_ptr, xold, yold, xnew, ynew); - - if ( new_time < LONG_DURATION && new_time < move_time ) - { - method = 1; - move_time = new_time; - } - } - - // Method 2: carriage-return + local movement - if ( yold >= 0 && F_carriage_return.cap ) - { - new_time = relativeMove (null_ptr, 0, yold, xnew, ynew); - - if ( new_time < LONG_DURATION - && F_carriage_return.duration + new_time < move_time ) - { - method = 2; - move_time = F_carriage_return.duration + new_time; - } - } - - // Method 3: home-cursor + local movement - if ( F_cursor_home.cap ) - { - new_time = relativeMove (null_ptr, 0, 0, xnew, ynew); - - if ( new_time < LONG_DURATION - && F_cursor_home.duration + new_time < move_time ) - { - method = 3; - move_time = F_cursor_home.duration + new_time; - } - } - - // Method 4: home-down + local movement - if ( F_cursor_to_ll.cap ) - { - new_time = relativeMove (null_ptr, 0, screen_height-1, xnew, ynew); - - if ( new_time < LONG_DURATION - && F_cursor_to_ll.duration + new_time < move_time ) - { - method = 4; - move_time = F_cursor_to_ll.duration + new_time; - } - } - - // Method 5: left margin for wrap to right-hand side - if ( automatic_left_margin - && ! eat_nl_glitch - && yold > 0 - && F_cursor_left.cap ) - { - new_time = relativeMove (null_ptr, screen_width-1, yold-1, xnew, ynew); - - if ( new_time < LONG_DURATION - && F_carriage_return.cap - && F_carriage_return.duration - + F_cursor_left.duration + new_time < move_time ) - { - method = 5; - move_time = F_carriage_return.duration - + F_cursor_left.duration + new_time; - } - } - - if ( method ) - { - switch ( method ) - { - case 1: - relativeMove (move_ptr, xold, yold, xnew, ynew); - break; - - case 2: - if ( F_carriage_return.cap ) - { - std::strncpy (move_ptr, F_carriage_return.cap, sizeof(move_buf) - 1); - move_ptr += F_carriage_return.length; - relativeMove (move_ptr, 0, yold, xnew, ynew); - } - break; - - case 3: - std::strncpy (move_ptr, F_cursor_home.cap, sizeof(move_buf) - 1); - move_ptr += F_cursor_home.length; - relativeMove (move_ptr, 0, 0, xnew, ynew); - break; - - case 4: - std::strncpy (move_ptr, F_cursor_to_ll.cap, sizeof(move_buf) - 1); - move_ptr += F_cursor_to_ll.length; - relativeMove (move_ptr, 0, screen_height-1, xnew, ynew); - break; - - case 5: - move_buf[0] = '\0'; - - if ( xold >= 0 ) - std::strncat ( move_ptr - , F_carriage_return.cap - , sizeof(move_buf) - std::strlen(move_ptr) - 1 ); - - std::strncat ( move_ptr - , F_cursor_left.cap - , sizeof(move_buf) - std::strlen(move_ptr) - 1 ); - move_ptr += std::strlen(move_buf); - relativeMove (move_ptr, screen_width-1, yold-1, xnew, ynew); - break; - - default: - break; - } - } - - if ( move_time < LONG_DURATION ) - return move_buf; - else - return 0; -} - -//---------------------------------------------------------------------- -void FOptiMove::printDurations() -{ - std::printf (" speed: %d baud\n", baudrate); - std::printf (" char_duration: %d ms\n", char_duration); - std::printf (" cursor_home: %d ms\n", F_cursor_home.duration); - std::printf (" cursor_to_ll: %d ms\n", F_cursor_to_ll.duration); - std::printf (" carriage_return: %d ms\n", F_carriage_return.duration); - std::printf (" tab: %d ms\n", F_tab.duration); - std::printf (" back_tab: %d ms\n", F_back_tab.duration); - std::printf (" cursor_up: %d ms\n", F_cursor_up.duration); - std::printf (" cursor_down: %d ms\n", F_cursor_down.duration); - std::printf (" cursor_left: %d ms\n", F_cursor_left.duration); - std::printf (" cursor_right: %d ms\n", F_cursor_right.duration); - std::printf (" cursor_address: %d ms\n", F_cursor_address.duration); - std::printf (" column_address: %d ms\n", F_column_address.duration); - std::printf (" row_address: %d ms\n", F_row_address.duration); - std::printf (" parm_up_cursor: %d ms\n", F_parm_up_cursor.duration); - std::printf (" parm_down_cursor: %d ms\n", F_parm_down_cursor.duration); - std::printf (" parm_left_cursor: %d ms\n", F_parm_left_cursor.duration); - std::printf ("parm_right_cursor: %d ms\n", F_parm_right_cursor.duration); -} diff --git a/src/foptimove.h b/src/foptimove.h index 28865aad..16d75c3f 100644 --- a/src/foptimove.h +++ b/src/foptimove.h @@ -23,12 +23,6 @@ #include -// value for a long capability waiting time -#define LONG_DURATION 9999999 - -// maximum character distance to avoid direct cursor addressing -#define MOVE_LIMIT 7 - //---------------------------------------------------------------------- // class FOptiMove //---------------------------------------------------------------------- @@ -38,7 +32,42 @@ class FOptiMove { + public: + // Constructor + explicit FOptiMove (int = 0); + + // Destructor + ~FOptiMove(); + + // Mutators + void setBaudRate (int); + void setTabStop (int); + void setTermSize (int, int); + void set_cursor_home (char*&); + void set_cursor_to_ll (char*&); + void set_carriage_return (char*&); + void set_tabular (char*&); + void set_back_tab (char*&); + void set_cursor_up (char*&); + void set_cursor_down (char*&); + void set_cursor_left (char*&); + void set_cursor_right (char*&); + void set_cursor_address (char*&); + void set_column_address (char*&); + void set_row_address (char*&); + void set_parm_up_cursor (char*&); + void set_parm_down_cursor (char*&); + void set_parm_left_cursor (char*&); + void set_parm_right_cursor (char*&); + void set_auto_left_margin (bool&); + void set_eat_newline_glitch (bool&); + + // Methods + char* moveCursor (int, int, int, int); + void printDurations(); + private: + // Typedefs typedef unsigned char uChar; typedef unsigned int uInt; @@ -49,6 +78,21 @@ class FOptiMove int length; } capability; + // Constants + static const int LONG_DURATION = 9999999; + // value for a long capability waiting time + static const int MOVE_LIMIT = 7; + // maximum character distance to avoid direct cursor addressing + + // Methods + void calculateCharDuration(); + int capDuration (char*&, int); + int repeatedAppend (capability&, int, char*); + int relativeMove (char*&, int, int, int, int); + bool isTwoDirectionMove (int, int, int, int); + bool isWideMove (int, int, int, int); + + // Data Members capability F_cursor_home; capability F_carriage_return; capability F_cursor_to_ll; @@ -66,54 +110,15 @@ class FOptiMove capability F_parm_left_cursor; capability F_parm_right_cursor; - bool automatic_left_margin; - bool eat_nl_glitch; + bool automatic_left_margin; + bool eat_nl_glitch; - char move_buf[512]; - int char_duration; - int baudrate; - int tabstop; - int screen_width; - int screen_height; - - private: - void calculateCharDuration(); - int capDuration (char*&, int); - int repeatedAppend (capability&, int, char*); - int relativeMove (char*&, int, int, int, int); - bool isTwoDirectionMove (int, int, int, int); - bool isWideMove (int, int, int, int); - - public: - // Constructor - explicit FOptiMove (int = 0); - // Destructor - ~FOptiMove(); - - void setBaudRate (int); - void setTabStop (int); - void setTermSize (int, int); - void set_cursor_home (char*&); - void set_cursor_to_ll (char*&); - void set_carriage_return (char*&); - void set_tabular (char*&); - void set_back_tab (char*&); - void set_cursor_up (char*&); - void set_cursor_down (char*&); - void set_cursor_left (char*&); - void set_cursor_right (char*&); - void set_cursor_address (char*&); - void set_column_address (char*&); - void set_row_address (char*&); - void set_parm_up_cursor (char*&); - void set_parm_down_cursor (char*&); - void set_parm_left_cursor (char*&); - void set_parm_right_cursor (char*&); - void set_auto_left_margin (bool&); - void set_eat_newline_glitch (bool&); - - char* moveCursor (int, int, int, int); - void printDurations(); + char move_buf[512]; + int char_duration; + int baudrate; + int tabstop; + int screen_width; + int screen_height; }; #pragma pack(pop) diff --git a/src/fpoint.cpp b/src/fpoint.cpp index ed814246..647b759b 100644 --- a/src/fpoint.cpp +++ b/src/fpoint.cpp @@ -12,31 +12,6 @@ FPoint::~FPoint() // destructor { } // public methods of FPoint -//---------------------------------------------------------------------- -bool FPoint::isNull() const -{ - return xpos == 0 && ypos == 0; -} - -//---------------------------------------------------------------------- -void FPoint::setX (int x) -{ - xpos = short(x); -} - -//---------------------------------------------------------------------- -void FPoint::setY (int y) -{ - ypos = short(y); -} - -//---------------------------------------------------------------------- -void FPoint::setPoint (int x, int y) -{ - xpos = short(x); - ypos = short(y); -} - //---------------------------------------------------------------------- FPoint& FPoint::operator = (const FPoint& p) { @@ -60,3 +35,28 @@ FPoint& FPoint::operator -= (const FPoint& p) ypos = short(ypos - p.ypos); return *this; } + +//---------------------------------------------------------------------- +void FPoint::setX (int x) +{ + xpos = short(x); +} + +//---------------------------------------------------------------------- +void FPoint::setY (int y) +{ + ypos = short(y); +} + +//---------------------------------------------------------------------- +void FPoint::setPoint (int x, int y) +{ + xpos = short(x); + ypos = short(y); +} + +//---------------------------------------------------------------------- +bool FPoint::isNull() const +{ + return xpos == 0 && ypos == 0; +} diff --git a/src/fpoint.h b/src/fpoint.h index ec23ce30..7ce4994b 100644 --- a/src/fpoint.h +++ b/src/fpoint.h @@ -20,29 +20,16 @@ class FPoint { - private: - short xpos; - short ypos; - public: // Constructors FPoint (); FPoint (int, int); + // Destructor virtual ~FPoint(); - virtual const char* getClassName(); - - bool isNull() const; - int getX() const; - int getY() const; - short& x_ref(); - short& y_ref(); - void setX (int); - void setY (int); - void setPoint (int, int); - - FPoint& operator = (const FPoint&); + // Overloaded operators + FPoint& operator = (const FPoint&); FPoint& operator += (const FPoint&); FPoint& operator -= (const FPoint&); @@ -51,6 +38,26 @@ class FPoint friend inline FPoint operator + (const FPoint&, const FPoint&); friend inline FPoint operator - (const FPoint&, const FPoint&); friend inline FPoint operator - (const FPoint&); + + // Accessors + virtual const char* getClassName(); + int getX() const; + int getY() const; + void setX (int); + void setY (int); + void setPoint (int, int); + + // Inquiry + bool isNull() const; + + // Point references + short& x_ref(); + short& y_ref(); + + private: + // Data Members + short xpos; + short ypos; }; #pragma pack(pop) @@ -68,26 +75,6 @@ inline FPoint::FPoint (int x, int y) , ypos(short(y)) { } -//---------------------------------------------------------------------- -inline const char* FPoint::getClassName() -{ return "FPoint"; } - -//---------------------------------------------------------------------- -inline int FPoint::getX() const -{ return xpos; } - -//---------------------------------------------------------------------- -inline int FPoint::getY() const -{ return ypos; } - -//---------------------------------------------------------------------- -inline short& FPoint::x_ref() -{ return xpos; } - -//---------------------------------------------------------------------- -inline short& FPoint::y_ref() -{ return ypos; } - //---------------------------------------------------------------------- inline bool operator == (const FPoint& p1, const FPoint& p2) { return p1.xpos == p2.xpos && p1.ypos == p2.ypos; } @@ -108,4 +95,24 @@ inline FPoint operator - (const FPoint& p1, const FPoint& p2) inline FPoint operator - (const FPoint& p) { return FPoint(-p.xpos, -p.ypos); } +//---------------------------------------------------------------------- +inline const char* FPoint::getClassName() +{ return "FPoint"; } + +//---------------------------------------------------------------------- +inline int FPoint::getX() const +{ return xpos; } + +//---------------------------------------------------------------------- +inline int FPoint::getY() const +{ return ypos; } + +//---------------------------------------------------------------------- +inline short& FPoint::x_ref() +{ return xpos; } + +//---------------------------------------------------------------------- +inline short& FPoint::y_ref() +{ return ypos; } + #endif // _FPOINT_H diff --git a/src/fprogressbar.cpp b/src/fprogressbar.cpp index fc4cf19b..a0211b6f 100644 --- a/src/fprogressbar.cpp +++ b/src/fprogressbar.cpp @@ -22,7 +22,141 @@ FProgressbar::FProgressbar(FWidget* parent) FProgressbar::~FProgressbar() { } + +// public methods of FProgressbar +//---------------------------------------------------------------------- +void FProgressbar::setPercentage (int percentage_value) +{ + if ( percentage_value <= percentage ) + return; + + if ( percentage_value > 100 ) + percentage = 100; + else if ( percentage_value < 0 ) + percentage = 0; + else + percentage = percentage_value; + + updateVTerm(false); + + if ( isVisible() ) + { + drawPercentage(); + drawBar(); + } + + updateVTerm(true); + updateTerminal(); +} + +//---------------------------------------------------------------------- +void FProgressbar::setGeometry (int x, int y, int w, int h, bool adjust) +{ + FWidget::setGeometry (x, y, w, h, adjust); + bar_length = w; +} + +//---------------------------------------------------------------------- +bool FProgressbar::setEnable (bool on) +{ + FWidget::setEnable(on); + + if ( on ) + flags |= fc::active; + else + flags &= ~fc::active; + + return on; +} + +//---------------------------------------------------------------------- +bool FProgressbar::setShadow (bool on) +{ + if ( on + && (Encoding != fc::VT100 || isTeraTerm() ) + && Encoding != fc::ASCII ) + flags |= fc::shadow; + else + flags &= ~fc::shadow; + + return on; +} + +//---------------------------------------------------------------------- +void FProgressbar::hide() +{ + int s, size; + short fg, bg; + char* blank; + FWidget* parent_widget = getParentWidget(); + + FWidget::hide(); + + if ( parent_widget ) + { + fg = parent_widget->getForegroundColor(); + bg = parent_widget->getBackgroundColor(); + } + else + { + fg = wc.dialog_fg; + bg = wc.dialog_bg; + } + + setColor (fg, bg); + s = hasShadow() ? 1 : 0; + size = getWidth() + s; + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset(blank, ' ', uLong(size)); + blank[size] = '\0'; + + for (int y=0; y < getHeight()+s; y++) + { + setPrintPos (1, 1 + y); + print (blank); + } + + delete[] blank; + setPrintPos (getWidth() - 4, 0); + print (" "); // hide percentage +} + +//---------------------------------------------------------------------- +void FProgressbar::reset() +{ + updateVTerm(false); + percentage = -1; + + if ( isVisible() ) + { + drawPercentage(); + drawBar(); + } + + updateVTerm(true); + updateTerminal(); +} + + // private methods of FProgressbar +//---------------------------------------------------------------------- +void FProgressbar::draw() +{ + updateVTerm(false); + drawPercentage(); + drawBar(); + + if ( (flags & fc::shadow) != 0 ) + drawShadow (); + + updateVTerm(true); + flush_out(); +} + //---------------------------------------------------------------------- void FProgressbar::drawPercentage() { @@ -153,138 +287,3 @@ void FProgressbar::drawBar() updateTerminal(); flush_out(); } - - -// protected methods of FProgressbar -//---------------------------------------------------------------------- -void FProgressbar::draw() -{ - updateVTerm(false); - drawPercentage(); - drawBar(); - - if ( (flags & fc::shadow) != 0 ) - drawShadow (); - - updateVTerm(true); - flush_out(); -} - - -// public methods of FProgressbar -//---------------------------------------------------------------------- -void FProgressbar::hide() -{ - int s, size; - short fg, bg; - char* blank; - FWidget* parent_widget = getParentWidget(); - - FWidget::hide(); - - if ( parent_widget ) - { - fg = parent_widget->getForegroundColor(); - bg = parent_widget->getBackgroundColor(); - } - else - { - fg = wc.dialog_fg; - bg = wc.dialog_bg; - } - - setColor (fg, bg); - s = hasShadow() ? 1 : 0; - size = getWidth() + s; - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset(blank, ' ', uLong(size)); - blank[size] = '\0'; - - for (int y=0; y < getHeight()+s; y++) - { - setPrintPos (1, 1 + y); - print (blank); - } - - delete[] blank; - setPrintPos (getWidth() - 4, 0); - print (" "); // hide percentage -} - -//---------------------------------------------------------------------- -void FProgressbar::setPercentage (int percentage_value) -{ - if ( percentage_value <= percentage ) - return; - - if ( percentage_value > 100 ) - percentage = 100; - else if ( percentage_value < 0 ) - percentage = 0; - else - percentage = percentage_value; - - updateVTerm(false); - - if ( isVisible() ) - { - drawPercentage(); - drawBar(); - } - - updateVTerm(true); - updateTerminal(); -} - -//---------------------------------------------------------------------- -void FProgressbar::reset() -{ - updateVTerm(false); - percentage = -1; - - if ( isVisible() ) - { - drawPercentage(); - drawBar(); - } - - updateVTerm(true); - updateTerminal(); -} - -//---------------------------------------------------------------------- -void FProgressbar::setGeometry (int x, int y, int w, int h, bool adjust) -{ - FWidget::setGeometry (x, y, w, h, adjust); - bar_length = w; -} - -//---------------------------------------------------------------------- -bool FProgressbar::setEnable (bool on) -{ - FWidget::setEnable(on); - - if ( on ) - flags |= fc::active; - else - flags &= ~fc::active; - - return on; -} - -//---------------------------------------------------------------------- -bool FProgressbar::setShadow (bool on) -{ - if ( on - && (Encoding != fc::VT100 || isTeraTerm() ) - && Encoding != fc::ASCII ) - flags |= fc::shadow; - else - flags &= ~fc::shadow; - - return on; -} diff --git a/src/fprogressbar.h b/src/fprogressbar.h index 76e6fc65..1fda7012 100644 --- a/src/fprogressbar.h +++ b/src/fprogressbar.h @@ -40,40 +40,47 @@ class FProgressbar : public FWidget { - private: - int percentage; - int bar_length; - - private: - void drawPercentage(); - void drawBar(); - - protected: - virtual void draw(); - public: + // Using-declarations + using FWidget::setGeometry; + // Constructor explicit FProgressbar(FWidget* = 0); + // Destructor virtual ~FProgressbar(); - const char* getClassName() const; - void hide(); + // Accessors + const char* getClassName() const; + int getPercentage(); - int getPercentage(); - void setPercentage (int); - void reset(); - // make every setGeometry from FWidget available - using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - bool setEnable (bool); - bool setEnable(); - bool unsetEnable(); - bool setDisable(); - bool setShadow (bool); - bool setShadow(); - bool unsetShadow(); - bool hasShadow(); + // Mutators + void setPercentage (int); + void setGeometry (int, int, int, int, bool = true); + bool setEnable (bool); + bool setEnable(); + bool unsetEnable(); + bool setDisable(); + bool setShadow (bool); + bool setShadow(); + bool unsetShadow(); + + // Inquiries + bool hasShadow(); + + // Methods + void hide(); + void reset(); + + private: + // Methods + virtual void draw(); + void drawPercentage(); + void drawBar(); + + // Data Members + int percentage; + int bar_length; }; #pragma pack(pop) diff --git a/src/fradiobutton.h b/src/fradiobutton.h index 27fee95a..0a070cd5 100644 --- a/src/fradiobutton.h +++ b/src/fradiobutton.h @@ -45,24 +45,28 @@ class FRadioButton : public FToggleButton { - private: - // Disable copy constructor - FRadioButton (const FRadioButton&); - // Disable assignment operator (=) - FRadioButton& operator = (const FRadioButton&); - - void init(); - void draw(); - void drawRadioButton(); - public: // Constructors explicit FRadioButton (FWidget* = 0); FRadioButton (const FString&, FWidget* = 0); + // Destructor virtual ~FRadioButton(); + // Accessor const char* getClassName() const; + + private: + // Disable copy constructor + FRadioButton (const FRadioButton&); + + // Disable assignment operator (=) + FRadioButton& operator = (const FRadioButton&); + + // Methods + void init(); + void draw(); + void drawRadioButton(); }; #pragma pack(pop) diff --git a/src/fradiomenuitem.h b/src/fradiomenuitem.h index 6f898e1b..06f5c8db 100644 --- a/src/fradiomenuitem.h +++ b/src/fradiomenuitem.h @@ -45,26 +45,30 @@ class FRadioMenuItem : public FMenuItem { - private: - // Disable copy constructor - FRadioMenuItem (const FRadioMenuItem&); - // Disable assignment operator (=) - FRadioMenuItem& operator = (const FRadioMenuItem&); - - void init (FWidget*); - void processToggle(); - void processClicked(); - public: - // Constructor + // Constructors explicit FRadioMenuItem (FWidget* = 0); FRadioMenuItem (FString&, FWidget* = 0); FRadioMenuItem (const std::string&, FWidget* = 0); FRadioMenuItem (const char*, FWidget* = 0); + // Destructor virtual ~FRadioMenuItem(); + // Accessor const char* getClassName() const; + + private: + // Disable copy constructor + FRadioMenuItem (const FRadioMenuItem&); + + // Disable assignment operator (=) + FRadioMenuItem& operator = (const FRadioMenuItem&); + + // Methods + void init (FWidget*); + void processToggle(); + void processClicked(); }; #pragma pack(pop) diff --git a/src/frect.h b/src/frect.h index 2148d391..e4c66b44 100644 --- a/src/frect.h +++ b/src/frect.h @@ -24,23 +24,25 @@ class FRect { - private: - short X1; - short Y1; - short X2; - short Y2; - public: // Constructors FRect (); FRect (int, int, int, int); FRect (const FPoint&, const FPoint&); + // Destructor virtual ~FRect(); - virtual const char* getClassName(); + // Overloaded operators + FRect& operator = (const FRect&); - bool isNull() const; + friend FRect operator + (const FRect&, const FPoint&); + friend FRect operator - (const FRect&, const FPoint&); + friend bool operator == (const FRect&, const FRect&); + friend bool operator != (const FRect&, const FRect&); + + // Accessors + virtual const char* getClassName(); int getX1() const; int getY1() const; int getX2() const; @@ -55,10 +57,7 @@ class FRect int getWidth() const; int getHeight() const; - short& x1_ref(); - short& y1_ref(); - short& x2_ref(); - short& y2_ref(); + // Mutators void setX1 (int); void setY1 (int); void setX2 (int); @@ -75,6 +74,16 @@ class FRect void setCoordinates (const FPoint&, const FPoint&); void setCoordinates (int, int, int, int); + // Inquiry + bool isNull() const; + + // Coordinate references + short& x1_ref(); + short& y1_ref(); + short& x2_ref(); + short& y2_ref(); + + // Methods void move (int, int); void move (const FPoint&); bool contains (int, int) const; @@ -83,12 +92,12 @@ class FRect bool overlap (const FRect&) const; FRect intersect (const FRect&) const; - FRect& operator = (const FRect&); - - friend FRect operator + (const FRect&, const FPoint&); - friend FRect operator - (const FRect&, const FPoint&); - friend bool operator == (const FRect&, const FRect&); - friend bool operator != (const FRect&, const FRect&); + private: + // Data Members + short X1; + short Y1; + short X2; + short Y2; }; #pragma pack(pop) diff --git a/src/fscrollbar.cpp b/src/fscrollbar.cpp index f7726d3a..193b28af 100644 --- a/src/fscrollbar.cpp +++ b/src/fscrollbar.cpp @@ -67,147 +67,336 @@ FScrollbar::~FScrollbar() delOwnTimer(); } -// private methods of FScrollbar + +// public methods of FScrollbar //---------------------------------------------------------------------- -void FScrollbar::init() +void FScrollbar::setMinimum (int minimum) { - unsetFocusable(); - ignorePadding(); - setGeometry(1, 1, getWidth(), getHeight()); + min = minimum; + calculateSliderValues(); } //---------------------------------------------------------------------- -void FScrollbar::draw() +void FScrollbar::setMaximum (int maximum) { - updateVTerm(false); - drawButtons(); - current_slider_pos = -1; - drawBar(); - updateVTerm(true); + max = maximum; + calculateSliderValues(); } //---------------------------------------------------------------------- -FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y) +void FScrollbar::setRange(int minimum, int maximum) { - FScrollbar::sType stype; + min = minimum; + max = maximum; + calculateSliderValues(); +} + +//---------------------------------------------------------------------- +void FScrollbar::setValue (int value) +{ + val = value; + calculateSliderValues(); +} + +//---------------------------------------------------------------------- +void FScrollbar::setSteps (float st) +{ + if ( st <= 0 ) + steps = 1; + else + steps = st; + + if ( pageSize == 0 ) + pageSize = int(float(max)/steps); +} + +//---------------------------------------------------------------------- +void FScrollbar::setPageSize (int document_size, int page_size) +{ + if ( page_size == 0 ) + { + pageSize = document_size; + steps = 1.0; + } + else + { + pageSize = page_size; + steps = float(float(document_size) / float(page_size)); + } +} + +//---------------------------------------------------------------------- +void FScrollbar::setOrientation (int o) +{ + int nf = 0; + length = (getHeight() > getWidth()) ? getHeight() : getWidth(); + + if ( o == fc::vertical && bar_orientation == fc::horizontal ) + { + setWidth(1); + setHeight(length); + } + else if ( o == fc::horizontal && bar_orientation == fc::vertical ) + { + setWidth(length); + setHeight(1); + + if ( isNewFont() ) + nf = 2; + } + slider_length = bar_length = length-nf-2; + bar_orientation = o; +} + +//---------------------------------------------------------------------- +void FScrollbar::setGeometry (int x, int y, int w, int h, bool adjust) +{ + FWidget::setGeometry (x, y, w, h, adjust); + + int nf = 0; + length = (h > w) ? h : w; if ( bar_orientation == fc::vertical ) { - if ( y == 1 ) - { - stype = FScrollbar::scrollStepBackward; // decrement button - } - else if ( y >1 && y <= slider_pos+1 ) - { - stype = FScrollbar::scrollPageBackward; // before slider - } - else if ( y > slider_pos+slider_length+1 && y < getHeight() ) - { - stype = FScrollbar::scrollPageForward; // after slider - } - else if ( y == getHeight() ) - { - stype = FScrollbar::scrollStepForward; // increment button - } - else - stype = FScrollbar::noScroll; + setWidth(isNewFont() ? 2 : 1); + setHeight(length); } - else // horizontal + else // horizontal { + setWidth(length); + setHeight(1); + if ( isNewFont() ) - { - if ( x == 1 || x == 2 ) - { - stype = FScrollbar::scrollStepBackward; // decrement button - } - else if ( x >2 && x <= slider_pos+2 ) - { - stype = FScrollbar::scrollPageBackward; // before slider - } - else if ( x > slider_pos+slider_length+2 && x < getWidth()-1 ) - { - stype = FScrollbar::scrollPageForward; // after slider - } - else if ( x == getWidth()-1 || x == getWidth() ) - { - stype = FScrollbar::scrollStepForward; // increment button - } - else - stype = FScrollbar::noScroll; - } - else - { - if ( x == 1 ) - { - stype = FScrollbar::scrollStepBackward; // decrement button - } - else if ( x >1 && x <= slider_pos+1 ) - { - stype = FScrollbar::scrollPageBackward; // before slider - } - else if ( x > slider_pos+slider_length+1 && x < getWidth() ) - { - stype = FScrollbar::scrollPageForward; // after slider - } - else if ( x == getWidth() ) - { - stype = FScrollbar::scrollStepForward; // increment button - } - else - stype = FScrollbar::noScroll; - } + nf = 2; } - return stype; + slider_length = bar_length = length-nf-2; } //---------------------------------------------------------------------- -void FScrollbar::processMiddleButton (int x, int y) +void FScrollbar::resize() { - int new_val; + FWidget::resize(); + setOrientation (bar_orientation); + setValue (val); + calculateSliderValues(); +} + +//---------------------------------------------------------------------- +void FScrollbar::redraw() +{ + draw(); +} + +//---------------------------------------------------------------------- +void FScrollbar::calculateSliderValues() +{ + if ( isNewFont() && bar_orientation == fc::horizontal ) + bar_length = length - 4; + else + bar_length = length - 2; + + slider_length = int(float(bar_length) / steps); + + if ( slider_length < 1 ) + slider_length = 1; + else if ( slider_length > bar_length ) + slider_length = bar_length; + + if ( val == min ) + { + slider_pos = 0; + return; + } + + if ( val == max ) + { + slider_pos = bar_length - slider_length; + return; + } + + slider_pos = int( round ( float((bar_length - slider_length) * val) + / float(max - min) ) ); + + if ( slider_pos < 0 ) + slider_pos = 0; + else if ( slider_pos > bar_length - slider_length ) + slider_pos = bar_length - slider_length; +} + +//---------------------------------------------------------------------- +void FScrollbar::drawButtons() +{ + setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg); + + if ( isNewFont() ) + { + setPrintPos (1,1); if ( bar_orientation == fc::vertical ) { - if ( y >1 && y < getHeight() ) - { - new_val = int( round ( float(max - min) * (y - 2.0 - (slider_length/2)) - / float(bar_length - slider_length) ) ); - } + print (fc::NF_rev_up_arrow1); + print (fc::NF_rev_up_arrow2); + setPrintPos (1, length); + print (fc::NF_rev_down_arrow1); + print (fc::NF_rev_down_arrow2); + } + else // horizontal + { + print (fc::NF_rev_left_arrow1); + print (fc::NF_rev_left_arrow2); + setPrintPos (length-1, 1); + print (fc::NF_rev_right_arrow1); + print (fc::NF_rev_right_arrow2); + } + } + else + { + setPrintPos (1,1); + + if ( isMonochron() ) + setReverse(true); + + if ( bar_orientation == fc::vertical ) + { + if ( isCygwinTerminal() ) + print ('^'); else - return; + print (fc::BlackUpPointingTriangle); // ▲ + + setPrintPos (1, length); + + if ( isCygwinTerminal() ) + print ('v'); + else + print (fc::BlackDownPointingTriangle); // ▼ + } + else // horizontal + { + print (fc::BlackLeftPointingPointer); // ◄ + setPrintPos (length, 1); + print (fc::BlackRightPointingPointer); // ► + } + + if ( isMonochron() ) + setReverse(false); + } +} + +//---------------------------------------------------------------------- +void FScrollbar::drawBar() +{ + if ( slider_pos != current_slider_pos ) + { + int z; + updateVTerm(false); + + if ( bar_orientation == fc::vertical ) + { + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + + for (z=1; z <= slider_pos; z++) + { + setPrintPos (1, 1 + z); + + if ( isNewFont() ) + print (fc::NF_border_line_left); // ⎸ + + if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (' '); + } + + setColor (wc.scrollbar_bg, wc.scrollbar_fg); + + if ( isMonochron() ) + setReverse(false); + + for (z=1; z <= slider_length; z++) + { + setPrintPos (1, 1 + slider_pos + z); + + if ( isNewFont() ) + print (' '); + + print (' '); + } + + if ( isMonochron() ) + setReverse(true); + + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + + for (z=slider_pos+slider_length+1; z <= bar_length; z++) + { + setPrintPos (1, 1 + z); + + if ( isNewFont() ) + print (fc::NF_border_line_left); // ⎸ + + if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); + else + print (' '); + } } else // horizontal { - int nf = isNewFont() ? 1 : 0; + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + z = 0; - if ( x > 1+nf && x < getWidth()-nf ) - { - new_val = int( round ( float(max - min) * (x - 2.0 - nf - (slider_length/2)) - / float(bar_length - slider_length) ) ); - } + if ( isNewFont() ) + setPrintPos (3 + z, 1); else - return; + setPrintPos (2 + z, 1); + + for (; z < slider_pos; z++) + { + if ( isNewFont() ) + print (fc::NF_border_line_upper); // ¯ + else if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (' '); + } + + setColor (wc.scrollbar_bg, wc.scrollbar_fg); + + if ( isMonochron() ) + setReverse(false); + + z = 0; + + for (; z < slider_length; z++) + print (' '); + + if ( isMonochron() ) + setReverse(true); + + setColor (wc.scrollbar_fg, wc.scrollbar_bg); + z = slider_pos + slider_length + 1; + + for (; z <= bar_length; z++) + { + if ( isNewFont() ) + print (fc::NF_border_line_upper); // ¯ + else if ( isMonochron() || max_color < 16 ) + print (fc::MediumShade); // ▒ + else + print (' '); + } } - if ( new_val != val ) - { - setValue(new_val); - drawBar(); - updateTerminal(); - scroll_type = FScrollbar::scrollJump; - processScroll(); - } + current_slider_pos = slider_pos; + + if ( isMonochron() ) + setReverse(false); + + updateVTerm(true); + } } - -//---------------------------------------------------------------------- -void FScrollbar::processScroll() -{ - emitCallback("change-value"); -} - - -// public methods of FScrollbar //---------------------------------------------------------------------- void FScrollbar::onMouseDown (FMouseEvent* ev) { @@ -402,330 +591,142 @@ void FScrollbar::onTimer (FTimerEvent*) processScroll(); } + +// private methods of FScrollbar //---------------------------------------------------------------------- -void FScrollbar::resize() +void FScrollbar::init() { - FWidget::resize(); - setOrientation (bar_orientation); - setValue (val); - calculateSliderValues(); + unsetFocusable(); + ignorePadding(); + setGeometry(1, 1, getWidth(), getHeight()); } //---------------------------------------------------------------------- -void FScrollbar::redraw() +void FScrollbar::draw() { - draw(); + updateVTerm(false); + drawButtons(); + current_slider_pos = -1; + drawBar(); + updateVTerm(true); } //---------------------------------------------------------------------- -void FScrollbar::setMinimum (int minimum) +FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y) { - min = minimum; - calculateSliderValues(); -} - -//---------------------------------------------------------------------- -void FScrollbar::setMaximum (int maximum) -{ - max = maximum; - calculateSliderValues(); -} - -//---------------------------------------------------------------------- -void FScrollbar::setRange(int minimum, int maximum) -{ - min = minimum; - max = maximum; - calculateSliderValues(); -} - -//---------------------------------------------------------------------- -void FScrollbar::setValue (int value) -{ - val = value; - calculateSliderValues(); -} - -//---------------------------------------------------------------------- -void FScrollbar::setSteps (float st) -{ - if ( st <= 0 ) - steps = 1; - else - steps = st; - - if ( pageSize == 0 ) - pageSize = int(float(max)/steps); -} - -//---------------------------------------------------------------------- -void FScrollbar::setPageSize (int document_size, int page_size) -{ - if ( page_size == 0 ) - { - pageSize = document_size; - steps = 1.0; - } - else - { - pageSize = page_size; - steps = float(float(document_size) / float(page_size)); - } -} - -//---------------------------------------------------------------------- -void FScrollbar::calculateSliderValues() -{ - if ( isNewFont() && bar_orientation == fc::horizontal ) - bar_length = length - 4; - else - bar_length = length - 2; - - slider_length = int(float(bar_length) / steps); - - if ( slider_length < 1 ) - slider_length = 1; - else if ( slider_length > bar_length ) - slider_length = bar_length; - - if ( val == min ) - { - slider_pos = 0; - return; - } - - if ( val == max ) - { - slider_pos = bar_length - slider_length; - return; - } - - slider_pos = int( round ( float((bar_length - slider_length) * val) - / float(max - min) ) ); - - if ( slider_pos < 0 ) - slider_pos = 0; - else if ( slider_pos > bar_length - slider_length ) - slider_pos = bar_length - slider_length; -} - -//---------------------------------------------------------------------- -void FScrollbar::setOrientation (int o) -{ - int nf = 0; - length = (getHeight() > getWidth()) ? getHeight() : getWidth(); - - if ( o == fc::vertical && bar_orientation == fc::horizontal ) - { - setWidth(1); - setHeight(length); - } - else if ( o == fc::horizontal && bar_orientation == fc::vertical ) - { - setWidth(length); - setHeight(1); - - if ( isNewFont() ) - nf = 2; - } - slider_length = bar_length = length-nf-2; - bar_orientation = o; -} - -//---------------------------------------------------------------------- -void FScrollbar::setGeometry (int x, int y, int w, int h, bool adjust) -{ - FWidget::setGeometry (x, y, w, h, adjust); - - int nf = 0; - length = (h > w) ? h : w; + FScrollbar::sType stype; if ( bar_orientation == fc::vertical ) { - setWidth(isNewFont() ? 2 : 1); - setHeight(length); + if ( y == 1 ) + { + stype = FScrollbar::scrollStepBackward; // decrement button + } + else if ( y >1 && y <= slider_pos+1 ) + { + stype = FScrollbar::scrollPageBackward; // before slider + } + else if ( y > slider_pos+slider_length+1 && y < getHeight() ) + { + stype = FScrollbar::scrollPageForward; // after slider + } + else if ( y == getHeight() ) + { + stype = FScrollbar::scrollStepForward; // increment button + } + else + stype = FScrollbar::noScroll; } - else // horizontal + else // horizontal { - setWidth(length); - setHeight(1); - if ( isNewFont() ) - nf = 2; + { + if ( x == 1 || x == 2 ) + { + stype = FScrollbar::scrollStepBackward; // decrement button + } + else if ( x >2 && x <= slider_pos+2 ) + { + stype = FScrollbar::scrollPageBackward; // before slider + } + else if ( x > slider_pos+slider_length+2 && x < getWidth()-1 ) + { + stype = FScrollbar::scrollPageForward; // after slider + } + else if ( x == getWidth()-1 || x == getWidth() ) + { + stype = FScrollbar::scrollStepForward; // increment button + } + else + stype = FScrollbar::noScroll; + } + else + { + if ( x == 1 ) + { + stype = FScrollbar::scrollStepBackward; // decrement button + } + else if ( x >1 && x <= slider_pos+1 ) + { + stype = FScrollbar::scrollPageBackward; // before slider + } + else if ( x > slider_pos+slider_length+1 && x < getWidth() ) + { + stype = FScrollbar::scrollPageForward; // after slider + } + else if ( x == getWidth() ) + { + stype = FScrollbar::scrollStepForward; // increment button + } + else + stype = FScrollbar::noScroll; + } } - slider_length = bar_length = length-nf-2; + return stype; } //---------------------------------------------------------------------- -void FScrollbar::drawBar() +void FScrollbar::processMiddleButton (int x, int y) { - if ( slider_pos != current_slider_pos ) - { - int z; - updateVTerm(false); + int new_val; if ( bar_orientation == fc::vertical ) { - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - - for (z=1; z <= slider_pos; z++) + if ( y >1 && y < getHeight() ) { - setPrintPos (1, 1 + z); - - if ( isNewFont() ) - print (fc::NF_border_line_left); // ⎸ - - if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); // ▒ - else - print (' '); - } - - setColor (wc.scrollbar_bg, wc.scrollbar_fg); - - if ( isMonochron() ) - setReverse(false); - - for (z=1; z <= slider_length; z++) - { - setPrintPos (1, 1 + slider_pos + z); - - if ( isNewFont() ) - print (' '); - - print (' '); - } - - if ( isMonochron() ) - setReverse(true); - - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - - for (z=slider_pos+slider_length+1; z <= bar_length; z++) - { - setPrintPos (1, 1 + z); - - if ( isNewFont() ) - print (fc::NF_border_line_left); // ⎸ - - if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); - else - print (' '); + new_val = int( round ( float(max - min) * (y - 2.0 - (slider_length/2)) + / float(bar_length - slider_length) ) ); } + else + return; } else // horizontal { - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - z = 0; + int nf = isNewFont() ? 1 : 0; - if ( isNewFont() ) - setPrintPos (3 + z, 1); + if ( x > 1+nf && x < getWidth()-nf ) + { + new_val = int( round ( float(max - min) * (x - 2.0 - nf - (slider_length/2)) + / float(bar_length - slider_length) ) ); + } else - setPrintPos (2 + z, 1); - - for (; z < slider_pos; z++) - { - if ( isNewFont() ) - print (fc::NF_border_line_upper); // ¯ - else if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); // ▒ - else - print (' '); - } - - setColor (wc.scrollbar_bg, wc.scrollbar_fg); - - if ( isMonochron() ) - setReverse(false); - - z = 0; - - for (; z < slider_length; z++) - print (' '); - - if ( isMonochron() ) - setReverse(true); - - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - z = slider_pos + slider_length + 1; - - for (; z <= bar_length; z++) - { - if ( isNewFont() ) - print (fc::NF_border_line_upper); // ¯ - else if ( isMonochron() || max_color < 16 ) - print (fc::MediumShade); // ▒ - else - print (' '); - } + return; } - current_slider_pos = slider_pos; - - if ( isMonochron() ) - setReverse(false); - - updateVTerm(true); - } + if ( new_val != val ) + { + setValue(new_val); + drawBar(); + updateTerminal(); + scroll_type = FScrollbar::scrollJump; + processScroll(); + } } + //---------------------------------------------------------------------- -void FScrollbar::drawButtons() +void FScrollbar::processScroll() { - setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg); - - if ( isNewFont() ) - { - setPrintPos (1,1); - - if ( bar_orientation == fc::vertical ) - { - print (fc::NF_rev_up_arrow1); - print (fc::NF_rev_up_arrow2); - setPrintPos (1, length); - print (fc::NF_rev_down_arrow1); - print (fc::NF_rev_down_arrow2); - } - else // horizontal - { - print (fc::NF_rev_left_arrow1); - print (fc::NF_rev_left_arrow2); - setPrintPos (length-1, 1); - print (fc::NF_rev_right_arrow1); - print (fc::NF_rev_right_arrow2); - } - } - else - { - setPrintPos (1,1); - - if ( isMonochron() ) - setReverse(true); - - if ( bar_orientation == fc::vertical ) - { - if ( isCygwinTerminal() ) - print ('^'); - else - print (fc::BlackUpPointingTriangle); // ▲ - - setPrintPos (1, length); - - if ( isCygwinTerminal() ) - print ('v'); - else - print (fc::BlackDownPointingTriangle); // ▼ - } - else // horizontal - { - print (fc::BlackLeftPointingPointer); // ◄ - setPrintPos (length, 1); - print (fc::BlackRightPointingPointer); // ► - } - - if ( isMonochron() ) - setReverse(false); - } + emitCallback("change-value"); } diff --git a/src/fscrollbar.h b/src/fscrollbar.h index 680d561b..79e54ee5 100644 --- a/src/fscrollbar.h +++ b/src/fscrollbar.h @@ -41,6 +41,10 @@ class FScrollbar : public FWidget { public: + // Using-declarations + using FWidget::setGeometry; + + // Enumeration enum sType { noScroll = 0, @@ -53,7 +57,57 @@ class FScrollbar : public FWidget scrollWheelDown = 7 }; + // Constructors + explicit FScrollbar(FWidget* = 0); + FScrollbar (int = fc::vertical, FWidget* = 0); + + // Destructor + virtual ~FScrollbar(); + + // Accessors + const char* getClassName() const; + int getValue() const; + sType getScrollType() const; + + // Mutators + void setMinimum (int); + void setMaximum (int); + void setRange (int, int); + void setValue (int); + void setSteps (float); + void setPageSize (int, int); + void setOrientation (int); + void setGeometry (int, int, int, int, bool = true); + + // Methods + void resize(); + void redraw(); + void calculateSliderValues(); + void drawButtons(); + void drawBar(); + + // Event handlers + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); + void onWheel (FWheelEvent*); + void onTimer (FTimerEvent*); + private: + // Disable copy constructor + FScrollbar (const FScrollbar&); + + // Disable assignment operator (=) + FScrollbar& operator = (const FScrollbar&); + + // Methods + void init(); + void draw(); + sType getClickedScrollType (int, int); + void processMiddleButton (int, int); + void processScroll(); + + // Data Members sType scroll_type; bool threshold_reached; int threshold_time; @@ -72,52 +126,6 @@ class FScrollbar : public FWidget int length; int bar_orientation; int max_color; - - private: - // Disable copy constructor - FScrollbar (const FScrollbar&); - // Disable assignment operator (=) - FScrollbar& operator = (const FScrollbar&); - - void init(); - void draw(); - sType getClickedScrollType (int, int); - void processMiddleButton (int, int); - void processScroll(); - - public: - // Constructors - explicit FScrollbar(FWidget* = 0); - FScrollbar (int = fc::vertical, FWidget* = 0); - // Destructor - virtual ~FScrollbar(); - - const char* getClassName() const; - - // Event handlers - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - void onWheel (FWheelEvent*); - void onTimer (FTimerEvent*); - - void resize(); - void redraw(); - void setMinimum (int); - void setMaximum (int); - void setRange (int, int); - void setValue (int); - int getValue() const; - void setSteps (float); - void setPageSize (int, int); - void calculateSliderValues(); - void setOrientation (int); - // make every setGeometry from FWidget available - using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - void drawButtons(); - void drawBar(); - sType getScrollType() const; }; #pragma pack(pop) diff --git a/src/fstatusbar.cpp b/src/fstatusbar.cpp index 759c9b2e..22ef61c4 100644 --- a/src/fstatusbar.cpp +++ b/src/fstatusbar.cpp @@ -60,35 +60,14 @@ FStatusKey::FStatusKey (int k, const char* txt, FWidget* parent) //---------------------------------------------------------------------- FStatusKey::~FStatusKey() // destructor { - if ( statusbar() ) - statusbar()->remove(this); + if ( getConnectedStatusbar() ) + getConnectedStatusbar()->remove(this); delAccelerator(); } -// private methods of FStatusKey -//---------------------------------------------------------------------- -void FStatusKey::init (FWidget* parent) -{ - setGeometry (1,1,1,1); - - if ( parent && std::strcmp ( parent->getClassName() - , const_cast("FStatusBar") ) == 0 ) - { - setStatusbar( static_cast(parent) ); - - if ( statusbar() ) - statusbar()->insert(this); - } -} - -//---------------------------------------------------------------------- -void FStatusKey::processActivate() -{ - emitCallback("activate"); -} - +// public methods of FStatusKey //---------------------------------------------------------------------- void FStatusKey::onAccel (FAccelEvent* ev) { @@ -97,30 +76,17 @@ void FStatusKey::onAccel (FAccelEvent* ev) setActive(); - if ( statusbar() ) - statusbar()->redraw(); + if ( getConnectedStatusbar() ) + getConnectedStatusbar()->redraw(); ev->accept(); // unset after get back from callback unsetActive(); - if ( statusbar() ) - statusbar()->redraw(); + if ( getConnectedStatusbar() ) + getConnectedStatusbar()->redraw(); } -//---------------------------------------------------------------------- -FStatusBar* FStatusKey::statusbar() const -{ - return bar; -} - -//---------------------------------------------------------------------- -void FStatusKey::setStatusbar (FStatusBar* sb) -{ - bar = sb; -} - -// public methods of FStatusKey //---------------------------------------------------------------------- void FStatusKey::setActive() { @@ -138,6 +104,29 @@ bool FStatusKey::setMouseFocus(bool on) } +// private methods of FStatusKey +//---------------------------------------------------------------------- +void FStatusKey::init (FWidget* parent) +{ + setGeometry (1,1,1,1); + + if ( parent && std::strcmp ( parent->getClassName() + , const_cast("FStatusBar") ) == 0 ) + { + setConnectedStatusbar (static_cast(parent)); + + if ( getConnectedStatusbar() ) + getConnectedStatusbar()->insert(this); + } +} + +//---------------------------------------------------------------------- +void FStatusKey::processActivate() +{ + emitCallback("activate"); +} + + //---------------------------------------------------------------------- // class FStatusBar //---------------------------------------------------------------------- @@ -146,7 +135,7 @@ bool FStatusKey::setMouseFocus(bool on) //---------------------------------------------------------------------- FStatusBar::FStatusBar(FWidget* parent) : FWindow(parent) - , keylist() + , key_list() , text("") , mouse_down() , x(-1) @@ -159,16 +148,16 @@ FStatusBar::FStatusBar(FWidget* parent) FStatusBar::~FStatusBar() { // delete all keys - if ( ! keylist.empty() ) + if ( ! key_list.empty() ) { std::vector::iterator iter; - iter = keylist.begin(); + iter = key_list.begin(); - while ( iter != keylist.end() ) + while ( iter != key_list.end() ) { - (*iter)->setStatusbar(0); + (*iter)->setConnectedStatusbar(0); delAccelerator (*iter); - iter = keylist.erase(iter); + iter = key_list.erase(iter); } } @@ -176,6 +165,401 @@ FStatusBar::~FStatusBar() } +// public methods of FStatusBar +//---------------------------------------------------------------------- +void FStatusBar::setMessage (FString& mgs) +{ + text = mgs; +} + +//---------------------------------------------------------------------- +void FStatusBar::setMessage (const std::string& mgs) +{ + FString s = FString(mgs); + setMessage (s); +} + +//---------------------------------------------------------------------- +void FStatusBar::setMessage (const char* mgs) +{ + FString s = FString(mgs); + setMessage (s); +} + +//---------------------------------------------------------------------- +bool FStatusBar::hasActivatedKey() +{ + if ( ! key_list.empty() ) + { + std::vector::const_iterator iter, end; + iter = key_list.begin(); + end = key_list.end(); + + while ( iter != end ) + { + if ( (*iter)->isActivated() ) + return true; + + ++iter; + } + } + + return false; +} + +//---------------------------------------------------------------------- +void FStatusBar::hide() +{ + int screenWidth; + short fg, bg; + char* blank; + + FWindow::hide(); + fg = wc.term_fg; + bg = wc.term_bg; + setColor (fg, bg); + screenWidth = getColumnNumber(); + + if ( screenWidth < 0 ) + return; + + blank = new char[screenWidth+1]; + std::memset(blank, ' ', uLong(screenWidth)); + blank[screenWidth] = '\0'; + setPrintPos (1, 1); + print (blank); + delete[] blank; +} +//---------------------------------------------------------------------- +void FStatusBar::drawMessage() +{ + int termWidth, space_offset; + bool isLastActiveFocus, hasKeys; + + if ( ! (isVisible() ) ) + return; + + if ( x < 0 || x_msg < 0 ) + return; + + x = x_msg; + termWidth = getColumnNumber(); + space_offset = 1; + hasKeys = bool(! key_list.empty()); + + if ( hasKeys ) + { + std::vector::const_iterator iter = key_list.end(); + isLastActiveFocus = bool( (*(iter-1))->isActivated() + || (*(iter-1))->hasMouseFocus() ); + } + else + isLastActiveFocus = false; + + if ( isLastActiveFocus ) + space_offset = 0; + + updateVTerm(false); + setColor (wc.statusbar_fg, wc.statusbar_bg); + setPrintPos (x, 1); + + if ( isMonochron() ) + setReverse(true); + + if ( x+space_offset+3 < termWidth ) + { + if ( text ) + { + if ( ! isLastActiveFocus ) + { + x++; + print (' '); + } + + if ( hasKeys ) + { + x += 2; + print (fc::BoxDrawingsVertical); // │ + print (' '); + } + + int msg_length = int(getMessage().getLength()); + x += msg_length; + + if ( x-1 <= termWidth ) + print (getMessage()); + else + { + print ( getMessage().left(uInt(msg_length+termWidth-x-1)) ); + print (".."); + } + } + } + + for (int i=x; i <= termWidth; i++) + print (' '); + + if ( isMonochron() ) + setReverse(false); + + updateVTerm(true); +} + +//---------------------------------------------------------------------- +void FStatusBar::insert (FStatusKey* skey) +{ + key_list.push_back (skey); + + addAccelerator (skey->getKey(), skey); + + skey->addCallback + ( + "activate", + _METHOD_CALLBACK (this, &FStatusBar::cb_statuskey_activated) + ); +} + +//---------------------------------------------------------------------- +void FStatusBar::remove (FStatusKey* skey) +{ + std::vector::iterator iter; + + delAccelerator (skey); + + if ( key_list.empty() ) + return; + + iter = key_list.begin(); + + while ( iter != key_list.end() ) + { + if ( (*iter) == skey ) + { + iter = key_list.erase(iter); + skey->setConnectedStatusbar(0); + break; + } + else + ++iter; + } +} + +//---------------------------------------------------------------------- +void FStatusBar::remove (int pos) +{ + if ( int(getCount()) < pos ) + return; + + key_list.erase (key_list.begin()+pos-1); +} + +//---------------------------------------------------------------------- +void FStatusBar::clear() +{ + key_list.clear(); +} + +//---------------------------------------------------------------------- +void FStatusBar::adjustSize() +{ + setGeometry (1, getLineNumber(), getColumnNumber(), 1, false); +} + +//---------------------------------------------------------------------- + +void FStatusBar::onMouseDown (FMouseEvent* ev) +{ + if ( hasActivatedKey() ) + return; + + if ( ev->getButton() != fc::LeftButton ) + { + mouse_down = false; + + if ( ! key_list.empty() ) + { + std::vector::const_iterator iter, end; + iter = key_list.begin(); + end = key_list.end(); + + while ( iter != end ) + { + (*iter)->unsetMouseFocus(); + ++iter; + } + } + + redraw(); + return; + } + + if ( mouse_down ) + return; + + mouse_down = true; + + if ( ! key_list.empty() ) + { + std::vector::const_iterator iter, end; + int X = 1; + iter = key_list.begin(); + end = key_list.end(); + + while ( iter != end ) + { + int x1, x2, mouse_x, mouse_y, kname_len, txt_length; + + x1 = X; + kname_len = int(getKeyName((*iter)->getKey()).getLength()); + txt_length = int((*iter)->getText().getLength()); + x2 = x1 + kname_len + txt_length + 1; + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( mouse_x >= x1 + && mouse_x <= x2 + && mouse_y == 1 + && ! (*iter)->hasMouseFocus() ) + { + (*iter)->setMouseFocus(); + redraw(); + } + + X = x2 + 2; + ++iter; + } + } +} + +//---------------------------------------------------------------------- +void FStatusBar::onMouseUp (FMouseEvent* ev) +{ + if ( hasActivatedKey() ) + return; + + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( mouse_down ) + { + mouse_down = false; + + if ( ! key_list.empty() ) + { + std::vector::const_iterator iter, end; + int X = 1; + iter = key_list.begin(); + end = key_list.end(); + + while ( iter != end ) + { + int x1, x2, kname_len, txt_length; + x1 = X; + kname_len = int(getKeyName((*iter)->getKey()).getLength()); + txt_length = int((*iter)->getText().getLength()); + x2 = x1 + kname_len + txt_length + 1; + + if ( (*iter)->hasMouseFocus() ) + { + int mouse_x, mouse_y; + (*iter)->unsetMouseFocus(); + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( mouse_x >= x1 && mouse_x <= x2 && mouse_y == 1 ) + (*iter)->setActive(); + + // unset after get back from callback + (*iter)->unsetActive(); + redraw(); + } + + X = x2 + 2; + ++iter; + } + } + } +} + +//---------------------------------------------------------------------- +void FStatusBar::onMouseMove (FMouseEvent* ev) +{ + if ( hasActivatedKey() ) + return; + + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( mouse_down && ! key_list.empty() ) + { + std::vector::const_iterator iter, end; + bool focus_changed = false; + int X=1; + iter = key_list.begin(); + end = key_list.end(); + + while ( iter != end ) + { + int x1, x2, mouse_x, mouse_y, kname_len, txt_length; + x1 = X; + kname_len = int(getKeyName((*iter)->getKey()).getLength()); + txt_length = int((*iter)->getText().getLength()); + x2 = x1 + kname_len + txt_length + 1; + mouse_x = ev->getX(); + mouse_y = ev->getY(); + + if ( mouse_x >= x1 + && mouse_x <= x2 + && mouse_y == 1 ) + { + if ( ! (*iter)->hasMouseFocus() ) + { + (*iter)->setMouseFocus(); + focus_changed = true; + } + } + else + { + if ( (*iter)->hasMouseFocus() ) + { + (*iter)->unsetMouseFocus(); + focus_changed = true; + } + } + + X = x2 + 2; + ++iter; + } + + if ( focus_changed ) + redraw(); + } +} + +//---------------------------------------------------------------------- +void FStatusBar::cb_statuskey_activated (FWidget* widget, void*) +{ + if ( ! key_list.empty() ) + { + std::vector::const_iterator iter, end; + FStatusKey* statuskey = static_cast(widget); + + iter = key_list.begin(); + end = key_list.end(); + + while ( iter != end ) + { + if ( (*iter) != statuskey && (*iter)->isActivated() ) + (*iter)->unsetActive(); + ++iter; + } + } + + if ( isVisible() && isShown() ) + redraw(); +} + + // private methods of FStatusBar //---------------------------------------------------------------------- void FStatusBar::init() @@ -214,7 +598,7 @@ void FStatusBar::drawKeys() screenWidth = getColumnNumber(); x = 1; - if ( keylist.empty() ) + if ( key_list.empty() ) { x_msg = 1; return; @@ -226,8 +610,8 @@ void FStatusBar::drawKeys() if ( isMonochron() ) setReverse(true); - iter = keylist.begin(); - end = keylist.end(); + iter = key_list.begin(); + end = key_list.end(); while ( iter != end ) { @@ -294,7 +678,7 @@ void FStatusBar::drawKeys() print (".."); } - if ( iter+1 != keylist.end() + if ( iter+1 != key_list.end() && ( (*(iter+1))->isActivated() || (*(iter+1))->hasMouseFocus() ) && x + int(getKeyName((*(iter+1))->getKey()).getLength()) + 3 < screenWidth ) @@ -310,7 +694,7 @@ void FStatusBar::drawKeys() if ( isMonochron() ) setReverse(true); } - else if ( iter+1 != keylist.end() && x < screenWidth ) + else if ( iter+1 != key_list.end() && x < screenWidth ) { // not the last element setColor (wc.statusbar_separator_fg, wc.statusbar_bg); @@ -334,398 +718,3 @@ void FStatusBar::drawKeys() updateVTerm(true); x_msg = x; } - - -// public methods of FStatusBar -//---------------------------------------------------------------------- -void FStatusBar::hide() -{ - int screenWidth; - short fg, bg; - char* blank; - - FWindow::hide(); - fg = wc.term_fg; - bg = wc.term_bg; - setColor (fg, bg); - screenWidth = getColumnNumber(); - - if ( screenWidth < 0 ) - return; - - blank = new char[screenWidth+1]; - std::memset(blank, ' ', uLong(screenWidth)); - blank[screenWidth] = '\0'; - setPrintPos (1, 1); - print (blank); - delete[] blank; -} -//---------------------------------------------------------------------- - -void FStatusBar::onMouseDown (FMouseEvent* ev) -{ - if ( hasActivatedKey() ) - return; - - if ( ev->getButton() != fc::LeftButton ) - { - mouse_down = false; - - if ( ! keylist.empty() ) - { - std::vector::const_iterator iter, end; - iter = keylist.begin(); - end = keylist.end(); - - while ( iter != end ) - { - (*iter)->unsetMouseFocus(); - ++iter; - } - } - - redraw(); - return; - } - - if ( mouse_down ) - return; - - mouse_down = true; - - if ( ! keylist.empty() ) - { - std::vector::const_iterator iter, end; - int X = 1; - iter = keylist.begin(); - end = keylist.end(); - - while ( iter != end ) - { - int x1, x2, mouse_x, mouse_y, kname_len, txt_length; - - x1 = X; - kname_len = int(getKeyName((*iter)->getKey()).getLength()); - txt_length = int((*iter)->getText().getLength()); - x2 = x1 + kname_len + txt_length + 1; - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( mouse_x >= x1 - && mouse_x <= x2 - && mouse_y == 1 - && ! (*iter)->hasMouseFocus() ) - { - (*iter)->setMouseFocus(); - redraw(); - } - - X = x2 + 2; - ++iter; - } - } -} - -//---------------------------------------------------------------------- -void FStatusBar::onMouseUp (FMouseEvent* ev) -{ - if ( hasActivatedKey() ) - return; - - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( mouse_down ) - { - mouse_down = false; - - if ( ! keylist.empty() ) - { - std::vector::const_iterator iter, end; - int X = 1; - iter = keylist.begin(); - end = keylist.end(); - - while ( iter != end ) - { - int x1, x2, kname_len, txt_length; - x1 = X; - kname_len = int(getKeyName((*iter)->getKey()).getLength()); - txt_length = int((*iter)->getText().getLength()); - x2 = x1 + kname_len + txt_length + 1; - - if ( (*iter)->hasMouseFocus() ) - { - int mouse_x, mouse_y; - (*iter)->unsetMouseFocus(); - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( mouse_x >= x1 && mouse_x <= x2 && mouse_y == 1 ) - (*iter)->setActive(); - - // unset after get back from callback - (*iter)->unsetActive(); - redraw(); - } - - X = x2 + 2; - ++iter; - } - } - } -} - -//---------------------------------------------------------------------- -void FStatusBar::onMouseMove (FMouseEvent* ev) -{ - if ( hasActivatedKey() ) - return; - - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( mouse_down && ! keylist.empty() ) - { - std::vector::const_iterator iter, end; - bool focus_changed = false; - int X=1; - iter = keylist.begin(); - end = keylist.end(); - - while ( iter != end ) - { - int x1, x2, mouse_x, mouse_y, kname_len, txt_length; - x1 = X; - kname_len = int(getKeyName((*iter)->getKey()).getLength()); - txt_length = int((*iter)->getText().getLength()); - x2 = x1 + kname_len + txt_length + 1; - mouse_x = ev->getX(); - mouse_y = ev->getY(); - - if ( mouse_x >= x1 - && mouse_x <= x2 - && mouse_y == 1 ) - { - if ( ! (*iter)->hasMouseFocus() ) - { - (*iter)->setMouseFocus(); - focus_changed = true; - } - } - else - { - if ( (*iter)->hasMouseFocus() ) - { - (*iter)->unsetMouseFocus(); - focus_changed = true; - } - } - - X = x2 + 2; - ++iter; - } - - if ( focus_changed ) - redraw(); - } -} - -//---------------------------------------------------------------------- -bool FStatusBar::hasActivatedKey() -{ - if ( ! keylist.empty() ) - { - std::vector::const_iterator iter, end; - iter = keylist.begin(); - end = keylist.end(); - - while ( iter != end ) - { - if ( (*iter)->isActivated() ) - return true; - - ++iter; - } - } - - return false; -} - -//---------------------------------------------------------------------- -void FStatusBar::drawMessage() -{ - int termWidth, space_offset; - bool isLastActiveFocus, hasKeys; - - if ( ! (isVisible() ) ) - return; - - if ( x < 0 || x_msg < 0 ) - return; - - x = x_msg; - termWidth = getColumnNumber(); - space_offset = 1; - hasKeys = bool(! keylist.empty()); - - if ( hasKeys ) - { - std::vector::const_iterator iter = keylist.end(); - isLastActiveFocus = bool( (*(iter-1))->isActivated() - || (*(iter-1))->hasMouseFocus() ); - } - else - isLastActiveFocus = false; - - if ( isLastActiveFocus ) - space_offset = 0; - - updateVTerm(false); - setColor (wc.statusbar_fg, wc.statusbar_bg); - setPrintPos (x, 1); - - if ( isMonochron() ) - setReverse(true); - - if ( x+space_offset+3 < termWidth ) - { - if ( text ) - { - if ( ! isLastActiveFocus ) - { - x++; - print (' '); - } - - if ( hasKeys ) - { - x += 2; - print (fc::BoxDrawingsVertical); // │ - print (' '); - } - - int msg_length = int(getMessage().getLength()); - x += msg_length; - - if ( x-1 <= termWidth ) - print (getMessage()); - else - { - print ( getMessage().left(uInt(msg_length+termWidth-x-1)) ); - print (".."); - } - } - } - - for (int i=x; i <= termWidth; i++) - print (' '); - - if ( isMonochron() ) - setReverse(false); - - updateVTerm(true); -} - -//---------------------------------------------------------------------- -void FStatusBar::setMessage (FString& mgs) -{ - text = mgs; -} - -//---------------------------------------------------------------------- -void FStatusBar::setMessage (const std::string& mgs) -{ - FString s = FString(mgs); - setMessage (s); -} - -//---------------------------------------------------------------------- -void FStatusBar::setMessage (const char* mgs) -{ - FString s = FString(mgs); - setMessage (s); -} - -//---------------------------------------------------------------------- -void FStatusBar::insert (FStatusKey* skey) -{ - keylist.push_back (skey); - - addAccelerator (skey->getKey(), skey); - - skey->addCallback - ( - "activate", - _METHOD_CALLBACK (this, &FStatusBar::cb_statuskey_activated) - ); -} - -//---------------------------------------------------------------------- -void FStatusBar::remove (FStatusKey* skey) -{ - std::vector::iterator iter; - - delAccelerator (skey); - - if ( keylist.empty() ) - return; - - iter = keylist.begin(); - - while ( iter != keylist.end() ) - { - if ( (*iter) == skey ) - { - iter = keylist.erase(iter); - skey->setStatusbar(0); - break; - } - else - ++iter; - } -} - -//---------------------------------------------------------------------- -void FStatusBar::remove (int pos) -{ - if ( int(count()) < pos ) - return; - - keylist.erase (keylist.begin()+pos-1); -} - -//---------------------------------------------------------------------- -void FStatusBar::clear() -{ - keylist.clear(); -} - -//---------------------------------------------------------------------- -void FStatusBar::adjustSize() -{ - setGeometry (1, getLineNumber(), getColumnNumber(), 1, false); -} - -//---------------------------------------------------------------------- -void FStatusBar::cb_statuskey_activated (FWidget* widget, void*) -{ - if ( ! keylist.empty() ) - { - std::vector::const_iterator iter, end; - FStatusKey* statuskey = static_cast(widget); - - iter = keylist.begin(); - end = keylist.end(); - - while ( iter != end ) - { - if ( (*iter) != statuskey && (*iter)->isActivated() ) - (*iter)->unsetActive(); - ++iter; - } - } - - if ( isVisible() && isShown() ) - redraw(); -} diff --git a/src/fstatusbar.h b/src/fstatusbar.h index 7a78411b..e437f2d1 100644 --- a/src/fstatusbar.h +++ b/src/fstatusbar.h @@ -51,66 +51,84 @@ class FStatusBar; class FStatusKey : public FWidget { - private: - int key; - FString text; - bool active; - bool mouse_focus; - FStatusBar* bar; - - private: - // Disable copy constructor - FStatusKey (const FStatusKey&); - // Disable assignment operator (=) - FStatusKey& operator = (const FStatusKey&); - - void init (FWidget*); - void processActivate(); - FStatusBar* statusbar() const; - void setStatusbar (FStatusBar*); - public: // Constructors explicit FStatusKey (FWidget* = 0); FStatusKey (int, FString&, FWidget* = 0); FStatusKey (int, const std::string&, FWidget* = 0); FStatusKey (int, const char*, FWidget* = 0); + // Destructor virtual ~FStatusKey(); - // Event handler - void onAccel (FAccelEvent*); + // Accessors + virtual const char* getClassName() const; + virtual int getKey() const; + virtual FString getText() const; - void setActive(); - void unsetActive(); - bool isActivated() const; - bool setMouseFocus(bool); - bool setMouseFocus(); - bool unsetMouseFocus(); - bool hasMouseFocus() const; - virtual int getKey() const; - virtual FString getText() const; + // Mutators + void setActive(); + void unsetActive(); + bool setMouseFocus(bool); + bool setMouseFocus(); + bool unsetMouseFocus(); + + // Inquiry + bool isActivated() const; + bool hasMouseFocus() const; + + // Event handler + void onAccel (FAccelEvent*); protected: - void setKey (int); - void setText (FString&); - void setText (const std::string&); - void setText (const char*); + // Mutators + void setKey (int); + void setText (FString&); + void setText (const std::string&); + void setText (const char*); private: + // Disable copy constructor + FStatusKey (const FStatusKey&); + + // Disable assignment operator (=) + FStatusKey& operator = (const FStatusKey&); + + // Methods + void init (FWidget*); + void processActivate(); + FStatusBar* getConnectedStatusbar() const; + void setConnectedStatusbar (FStatusBar*); + + // Friend class friend class FStatusBar; + + // Data Members + int key; + FString text; + bool active; + bool mouse_focus; + FStatusBar* bar; }; #pragma pack(pop) // FStatusKey inline functions //---------------------------------------------------------------------- -inline void FStatusKey::unsetActive() -{ active = false; } +inline const char* FStatusKey::getClassName() const +{ return "FStatusKey"; } //---------------------------------------------------------------------- -inline bool FStatusKey::isActivated() const -{ return active; } +inline int FStatusKey::getKey() const +{ return key; } + +//---------------------------------------------------------------------- +inline FString FStatusKey::getText() const +{ return text; } + +//---------------------------------------------------------------------- +inline void FStatusKey::unsetActive() +{ active = false; } //---------------------------------------------------------------------- inline bool FStatusKey::setMouseFocus() @@ -120,18 +138,14 @@ inline bool FStatusKey::setMouseFocus() inline bool FStatusKey::unsetMouseFocus() { return setMouseFocus(false); } +//---------------------------------------------------------------------- +inline bool FStatusKey::isActivated() const +{ return active; } + //---------------------------------------------------------------------- inline bool FStatusKey::hasMouseFocus() const { return mouse_focus; } -//---------------------------------------------------------------------- -inline int FStatusKey::getKey() const -{ return key; } - -//---------------------------------------------------------------------- -inline FString FStatusKey::getText() const -{ return text; } - //---------------------------------------------------------------------- inline void FStatusKey::setKey (int k) { key = k; } @@ -148,6 +162,14 @@ inline void FStatusKey::setText (const std::string& txt) inline void FStatusKey::setText (const char* txt) { text = txt; } +//---------------------------------------------------------------------- +inline FStatusBar* FStatusKey::getConnectedStatusbar() const +{ return bar; } + +//---------------------------------------------------------------------- +inline void FStatusKey::setConnectedStatusbar (FStatusBar* sb) +{ bar = sb; } + //---------------------------------------------------------------------- // class FStatusBar @@ -158,60 +180,69 @@ inline void FStatusKey::setText (const char* txt) class FStatusBar : public FWindow { - private: - std::vector keylist; - FString text; - bool mouse_down; - int x; - int x_msg; - - private: - // Disable copy constructor - FStatusBar (const FStatusBar&); - // Disable assignment operator (=) - FStatusBar& operator = (const FStatusBar&); - - void init(); - void draw(); - void drawKeys(); - public: // Constructor explicit FStatusBar (FWidget* = 0); + // Destructor virtual ~FStatusBar(); + // Accessors virtual const char* getClassName() const; - void hide(); + FStatusKey* getStatusKey (int) const; + FString getMessage() const; + uInt getCount() const; + + // Mutators + void activateKey (int); + void deactivateKey (int); + void setMessage (FString&); + void setMessage (const std::string&); + void setMessage (const char*); + + // Inquiries + bool isActivated (int) const; + bool hasActivatedKey(); + + // Methods + void hide(); + void drawMessage(); + void clearMessage(); + void insert (FStatusKey*); + void remove (FStatusKey*); + void remove (int); + void clear(); + void adjustSize(); // Event handlers - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onMouseMove (FMouseEvent*); - - uInt count() const; - FStatusKey* key (int) const; - void activateKey (int); - void deactivateKey (int); - bool isActivated (int) const; - bool hasActivatedKey(); - - void drawMessage(); - void setMessage (FString&); - void setMessage (const std::string&); - void setMessage (const char*); - FString getMessage() const; - void clearMessage(); - - void insert (FStatusKey*); - void remove (FStatusKey*); - void remove (int); - void clear(); - - void adjustSize(); + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onMouseMove (FMouseEvent*); // Callback method - void cb_statuskey_activated (FWidget*, void*); + void cb_statuskey_activated (FWidget*, void*); + + private: + // Typedef + typedef std::vector keyList; + + // Disable copy constructor + FStatusBar (const FStatusBar&); + + // Disable assignment operator (=) + FStatusBar& operator = (const FStatusBar&); + + // Methods + void init(); + void draw(); + void drawKeys(); + + // Data Members + keyList key_list; + FString text; + bool mouse_down; + int x; + int x_msg; }; #pragma pack(pop) @@ -222,24 +253,24 @@ inline const char* FStatusBar::getClassName() const { return "FStatusBar"; } //---------------------------------------------------------------------- -inline uInt FStatusBar::count() const -{ return uInt(keylist.size()); } +inline FStatusKey* FStatusBar::getStatusKey (int index) const +{ return key_list[uInt(index-1)]; } //---------------------------------------------------------------------- -inline FStatusKey* FStatusBar::key(int index) const -{ return keylist[uInt(index-1)]; } +inline uInt FStatusBar::getCount() const +{ return uInt(key_list.size()); } //---------------------------------------------------------------------- inline void FStatusBar::activateKey (int index) -{ keylist[uInt(index-1)]->setActive(); } +{ key_list[uInt(index-1)]->setActive(); } //---------------------------------------------------------------------- inline void FStatusBar::deactivateKey (int index) -{ keylist[uInt(index-1)]->unsetActive(); } +{ key_list[uInt(index-1)]->unsetActive(); } //---------------------------------------------------------------------- inline bool FStatusBar::isActivated(int index) const -{ return keylist[uInt(index-1)]->isActivated(); } +{ return key_list[uInt(index-1)]->isActivated(); } //---------------------------------------------------------------------- inline FString FStatusBar::getMessage() const diff --git a/src/fstring.cpp b/src/fstring.cpp index 45772dce..4208c6dc 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -3,6 +3,10 @@ #include "fstring.h" +// static class constant +const char* FString::bad_alloc_str = "not enough memory " \ + "to alloc a new string"; + //---------------------------------------------------------------------- // class FString //---------------------------------------------------------------------- @@ -107,14 +111,14 @@ FString::FString (uInt len, char c) } //---------------------------------------------------------------------- -FString::FString (const FString& s) - : string(0) - , length(0) - , bufsize(0) +FString::FString (const FString& s) // copy constructor + : string(new wchar_t[FWDBUFFER + s.length + 1]()) + , length(s.length) + , bufsize(FWDBUFFER + s.length + 1) , c_string(0) { if ( s.string ) - _replace (s.string); + std::wcscpy (string, s.string); } //---------------------------------------------------------------------- @@ -213,350 +217,7 @@ FString::~FString() // destructor } -// private methods of FString -//---------------------------------------------------------------------- -inline void FString::initLength (uInt len) -{ - if ( len == 0 ) - return; - - length = len; - bufsize = FWDBUFFER + len + 1; - string = new wchar_t[bufsize](); - std::wmemset (string, L'\0', bufsize); -} - -//---------------------------------------------------------------------- -inline void FString::_replace (const wchar_t* s) -{ - if ( string ) - delete[](string); - - length = uInt(std::wcslen(s)); - bufsize = FWDBUFFER + length + 1; - - try - { - string = new wchar_t[bufsize](); - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << ex.what() << std::endl; - return; - } -/* catch (std::exception& e) - { - std::cerr << "not enough memory for a new FString object " - << e.what() << std::endl; - return; - }*/ - std::wcscpy (string, s); -} - -//---------------------------------------------------------------------- -inline void FString::_insert (uInt pos, uInt len, const wchar_t* s) -{ - if ( ! string ) - { - // string is null - length = len; - bufsize = FWDBUFFER + length + 1; - - try - { - string = new wchar_t[bufsize](); - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return; - } - - std::wcscpy (string, s); - return; - } - else - { - uInt x; - - if ( (length + len + 1) <= bufsize ) - { - // output string <= bufsize - for (x = length; x > pos-1; x--) // shifting right side + '\0' - string[x+len] = string[x]; - - for (x=0; x < len; x++) // insert string - string[x+pos] = s[x]; - - length += len; - } - else - { - wchar_t* sptr; - // output string > bufsize - bufsize = FWDBUFFER + length + len + 1; - - try - { - sptr = new wchar_t[bufsize](); // generate new string - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return; - } - - uInt y = 0; - - for (x=0; x < pos; x++) // left side - sptr[y++] = string[x]; - - for (x=0; x < len; x++) // insert string - sptr[y++] = s[x]; - - for (x=pos; x < length+1; x++) // right side + '\0' - sptr[y++] = string[x]; - - length += len; - delete[](string); // delete old string - string = sptr; - } - } -} - -//---------------------------------------------------------------------- -inline void FString::_remove (uInt pos, uInt len) -{ - if ( (bufsize - length - 1 + len) <= FWDBUFFER ) - { - // shifting left side to pos - for (uInt i=pos; (i+len) < length+1; i++) - string[i] = string[i+len]; - - length -= len; - } - else - { - wchar_t* sptr; - bufsize = length + 1 - len + FWDBUFFER; - - try - { - sptr = new wchar_t[bufsize](); // generate new string - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return; - } - - uInt x, y = 0; - - for (x=0; x < pos; x++) // left side - sptr[y++] = string[x]; - - for (x=pos+len; x < length+1; x++) // right side + '\0' - sptr[y++] = string[x]; - - delete[](string); // delete old string - string = sptr; - length -= len; - } -} - -//---------------------------------------------------------------------- -inline char* FString::wc_to_c_str (const wchar_t* s) const -{ - int mblength, size, dest_size; - const wchar_t* src; - - if ( ! s ) // handle NULL string - return 0; - - if ( ! *s ) // handle empty string - { - try - { - // Generate a empty string ("") - c_string = new char[1](); - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return 0; - } - - return c_string; - } - - if ( c_string ) - delete[](c_string); - - size = int(std::wcslen(s)) + 1; - dest_size = size * int(CHAR_SIZE); - src = s; - std::mbstate_t state; - std::memset (&state, '\0', sizeof(mbstate_t)); - - try - { - c_string = new char[dest_size](); - - // pre-initialiaze the whole string with '\0' - std::memset (c_string, '\0', size_t(dest_size)); - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return 0; - } - - mblength = int(std::wcsrtombs (c_string, &src, uLong(dest_size), &state)); - - if ( mblength == -1 && errno != EILSEQ ) - { - delete[](c_string); - c_string = 0; - return const_cast(""); - } - - return c_string; -} - -//---------------------------------------------------------------------- -inline wchar_t* FString::c_to_wc_str (const char* s) const -{ - int wclength, size, dest_size; - const char* src; - wchar_t* dest; - - if ( ! s ) // handle NULL string - return 0; - - if ( ! *s ) // handle empty string - { - try - { - // Generate a empty wide string (L"") - return (new wchar_t[1]()); - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return 0; - } - } - - size = int(std::strlen(s)) + 1; - dest_size = size * int(CHAR_SIZE); - src = s; - std::mbstate_t state; - std::memset (&state, '\0', sizeof(mbstate_t)); - - try - { - dest = new wchar_t[size](); - // pre-initialiaze the whole string with '\0' - std::wmemset (dest, L'\0', size_t(size)); - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << " " << ex.what() << std::endl; - return 0; - } - - wclength = int(std::mbsrtowcs (dest, &src, uLong(dest_size), &state)); - - if ( wclength == -1 ) - { - if ( src != s ) - return dest; - else - { - delete[] dest; - return 0; - } - } - - if ( wclength == size ) - dest[size-1] = '\0'; - - if ( wclength ) - return dest; - else - { - delete[] dest; - return 0; - } -} - -//---------------------------------------------------------------------- -inline wchar_t* FString::extractToken ( wchar_t** rest - , const wchar_t* s - , const wchar_t* delim ) -{ - register wchar_t* token; - token = ( s ) ? const_cast(s) : *rest; - - if ( ! *token ) - return 0; - - *rest = std::wcspbrk(token, delim); - - if ( *rest ) - *(*rest)++ = '\0'; - else - *rest = token + std::wcslen(token); - return token; -} - - // FString operators -//---------------------------------------------------------------------- -std::ostream& operator << (std::ostream& outstr, const FString& s) -{ - if ( s.length ) - outstr << s.wc_to_c_str( s.string ); - - return (outstr); -} - -//---------------------------------------------------------------------- -std::istream& operator >> (std::istream& instr, FString& s) -{ - const wchar_t* wc_str; - char buf[INPBUFFER+1]; - - instr.getline (buf, INPBUFFER); - wc_str = s.c_to_wc_str(buf); - - if ( wc_str ) - { - s._replace (wc_str); - delete[] wc_str; - } - - return (instr); -} - -//---------------------------------------------------------------------- -std::wostream& operator << (std::wostream& outstr, const FString& s) -{ - if ( s.length ) - outstr << s.string; - - return (outstr); -} - -//---------------------------------------------------------------------- -std::wistream& operator >> (std::wistream& instr, FString& s) -{ - wchar_t buf[INPBUFFER+1]; - instr.getline (buf, INPBUFFER); - s._replace (buf); - return (instr); -} - //---------------------------------------------------------------------- FString& FString::operator = (const FString& s) { @@ -785,88 +446,6 @@ const FString FString::operator + (const char c) return(tmp); } -//---------------------------------------------------------------------- -const FString operator + (const FString& s1, const FString& s2) -{ - FString tmp(s1); - tmp._insert ( uInt(std::wcslen(s1.wc_str())) - , uInt(std::wcslen(s2.wc_str())) - , s2.wc_str() ); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const FString& s, const wchar_t c) -{ - FString tmp(s); - tmp._insert ( uInt(std::wcslen(s.wc_str())), 1, &c); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const std::wstring& s1, const FString& s2) -{ - FString tmp(s1); - tmp._insert ( uInt(std::wcslen(s1.c_str())) - , uInt(std::wcslen(s2.wc_str())) - , s2.wc_str() ); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const wchar_t* s1, const FString& s2) -{ - FString tmp(s1); - tmp._insert ( uInt(std::wcslen(s1)) - , uInt(std::wcslen(s2.wc_str())) - , s2.wc_str() ); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const std::string& s1, const FString& s2) -{ - FString tmp(s1); - tmp._insert ( tmp.getLength() - , uInt(std::wcslen(s2.wc_str())) - , s2.wc_str() ); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const char* s1, const FString& s2) -{ - FString tmp(s1); - tmp._insert ( tmp.getLength() - , uInt(std::wcslen(s2.wc_str())) - , s2.wc_str() ); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const wchar_t c, const FString& s) -{ - FString tmp(c); - tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str()); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const char c, const FString& s) -{ - FString tmp(c); - tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str()); - return (tmp); -} - -//---------------------------------------------------------------------- -const FString operator + (const wchar_t c, const std::wstring& s) -{ - FString tmp(c); - tmp._insert (1, uInt(s.length()), s.c_str()); - return (tmp); -} - //---------------------------------------------------------------------- wchar_t& FString::operator [] (int pos) { @@ -1125,7 +704,7 @@ long FString::toLong() const p++; } - if ( *p != L'\0' && ! std::isdigit(*p) ) + if ( ! std::isdigit(*p) ) throw std::invalid_argument ("no valid number"); return num; @@ -1171,7 +750,7 @@ uLong FString::toULong() const p++; } - if ( *p != L'\0' && ! std::isdigit(*p) ) + if ( ! std::isdigit(*p) ) throw std::invalid_argument ("no valid number"); return num; @@ -2610,3 +2189,430 @@ bool FString::includes (const char c) s[1] = L'\0'; return (std::wcsstr(string, s) != 0); } + + +// private methods of FString +//---------------------------------------------------------------------- +inline void FString::initLength (uInt len) +{ + if ( len == 0 ) + return; + + length = len; + bufsize = FWDBUFFER + len + 1; + string = new wchar_t[bufsize](); + std::wmemset (string, L'\0', bufsize); +} + +//---------------------------------------------------------------------- +inline void FString::_replace (const wchar_t* s) +{ + if ( string ) + delete[](string); + + length = uInt(std::wcslen(s)); + bufsize = FWDBUFFER + length + 1; + + try + { + string = new wchar_t[bufsize](); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << ex.what() << std::endl; + return; + } +/* catch (std::exception& e) + { + std::cerr << "not enough memory for a new FString object " + << e.what() << std::endl; + return; + }*/ + std::wcscpy (string, s); +} + +//---------------------------------------------------------------------- +inline void FString::_insert (uInt pos, uInt len, const wchar_t* s) +{ + if ( ! string ) + { + // string is null + length = len; + bufsize = FWDBUFFER + length + 1; + + try + { + string = new wchar_t[bufsize](); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return; + } + + std::wcscpy (string, s); + return; + } + else + { + uInt x; + + if ( (length + len + 1) <= bufsize ) + { + // output string <= bufsize + for (x = length; x > pos-1; x--) // shifting right side + '\0' + string[x+len] = string[x]; + + for (x=0; x < len; x++) // insert string + string[x+pos] = s[x]; + + length += len; + } + else + { + wchar_t* sptr; + // output string > bufsize + bufsize = FWDBUFFER + length + len + 1; + + try + { + sptr = new wchar_t[bufsize](); // generate new string + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return; + } + + uInt y = 0; + + for (x=0; x < pos; x++) // left side + sptr[y++] = string[x]; + + for (x=0; x < len; x++) // insert string + sptr[y++] = s[x]; + + for (x=pos; x < length+1; x++) // right side + '\0' + sptr[y++] = string[x]; + + length += len; + delete[](string); // delete old string + string = sptr; + } + } +} + +//---------------------------------------------------------------------- +inline void FString::_remove (uInt pos, uInt len) +{ + if ( (bufsize - length - 1 + len) <= FWDBUFFER ) + { + // shifting left side to pos + for (uInt i=pos; (i+len) < length+1; i++) + string[i] = string[i+len]; + + length -= len; + } + else + { + wchar_t* sptr; + bufsize = length + 1 - len + FWDBUFFER; + + try + { + sptr = new wchar_t[bufsize](); // generate new string + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return; + } + + uInt x, y = 0; + + for (x=0; x < pos; x++) // left side + sptr[y++] = string[x]; + + for (x=pos+len; x < length+1; x++) // right side + '\0' + sptr[y++] = string[x]; + + delete[](string); // delete old string + string = sptr; + length -= len; + } +} + +//---------------------------------------------------------------------- +inline char* FString::wc_to_c_str (const wchar_t* s) const +{ + int mblength, size, dest_size; + const wchar_t* src; + + if ( ! s ) // handle NULL string + return 0; + + if ( ! *s ) // handle empty string + { + try + { + // Generate a empty string ("") + c_string = new char[1](); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return 0; + } + + return c_string; + } + + if ( c_string ) + delete[](c_string); + + size = int(std::wcslen(s)) + 1; + dest_size = size * int(CHAR_SIZE); + src = s; + std::mbstate_t state; + std::memset (&state, '\0', sizeof(mbstate_t)); + + try + { + c_string = new char[dest_size](); + + // pre-initialiaze the whole string with '\0' + std::memset (c_string, '\0', size_t(dest_size)); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return 0; + } + + mblength = int(std::wcsrtombs (c_string, &src, uLong(dest_size), &state)); + + if ( mblength == -1 && errno != EILSEQ ) + { + delete[](c_string); + c_string = 0; + return const_cast(""); + } + + return c_string; +} + +//---------------------------------------------------------------------- +inline wchar_t* FString::c_to_wc_str (const char* s) const +{ + int wclength, size, dest_size; + const char* src; + wchar_t* dest; + + if ( ! s ) // handle NULL string + return 0; + + if ( ! *s ) // handle empty string + { + try + { + // Generate a empty wide string (L"") + return (new wchar_t[1]()); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return 0; + } + } + + size = int(std::strlen(s)) + 1; + dest_size = size * int(CHAR_SIZE); + src = s; + std::mbstate_t state; + std::memset (&state, '\0', sizeof(mbstate_t)); + + try + { + dest = new wchar_t[size](); + // pre-initialiaze the whole string with '\0' + std::wmemset (dest, L'\0', size_t(size)); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << " " << ex.what() << std::endl; + return 0; + } + + wclength = int(std::mbsrtowcs (dest, &src, uLong(dest_size), &state)); + + if ( wclength == -1 ) + { + if ( src != s ) + return dest; + else + { + delete[] dest; + return 0; + } + } + + if ( wclength == size ) + dest[size-1] = '\0'; + + if ( wclength ) + return dest; + else + { + delete[] dest; + return 0; + } +} + +//---------------------------------------------------------------------- +inline wchar_t* FString::extractToken ( wchar_t** rest + , const wchar_t* s + , const wchar_t* delim ) +{ + register wchar_t* token; + token = ( s ) ? const_cast(s) : *rest; + + if ( ! *token ) + return 0; + + *rest = std::wcspbrk(token, delim); + + if ( *rest ) + *(*rest)++ = '\0'; + else + *rest = token + std::wcslen(token); + return token; +} + + +// FString non-member operators +//---------------------------------------------------------------------- +std::ostream& operator << (std::ostream& outstr, const FString& s) +{ + if ( s.length ) + outstr << s.wc_to_c_str( s.string ); + + return (outstr); +} + +//---------------------------------------------------------------------- +std::istream& operator >> (std::istream& instr, FString& s) +{ + const wchar_t* wc_str; + char buf[FString::INPBUFFER + 1]; + + instr.getline (buf, FString::INPBUFFER); + wc_str = s.c_to_wc_str(buf); + + if ( wc_str ) + { + s._replace (wc_str); + delete[] wc_str; + } + + return (instr); +} + +//---------------------------------------------------------------------- +std::wostream& operator << (std::wostream& outstr, const FString& s) +{ + if ( s.length ) + outstr << s.string; + + return (outstr); +} + +//---------------------------------------------------------------------- +std::wistream& operator >> (std::wistream& instr, FString& s) +{ + wchar_t buf[FString::INPBUFFER + 1]; + instr.getline (buf, FString::INPBUFFER); + s._replace (buf); + return (instr); +} + +//---------------------------------------------------------------------- +const FString operator + (const FString& s1, const FString& s2) +{ + FString tmp(s1); + tmp._insert ( uInt(std::wcslen(s1.wc_str())) + , uInt(std::wcslen(s2.wc_str())) + , s2.wc_str() ); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const FString& s, const wchar_t c) +{ + FString tmp(s); + tmp._insert ( uInt(std::wcslen(s.wc_str())), 1, &c); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const std::wstring& s1, const FString& s2) +{ + FString tmp(s1); + tmp._insert ( uInt(std::wcslen(s1.c_str())) + , uInt(std::wcslen(s2.wc_str())) + , s2.wc_str() ); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const wchar_t* s1, const FString& s2) +{ + FString tmp(s1); + tmp._insert ( uInt(std::wcslen(s1)) + , uInt(std::wcslen(s2.wc_str())) + , s2.wc_str() ); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const std::string& s1, const FString& s2) +{ + FString tmp(s1); + tmp._insert ( tmp.getLength() + , uInt(std::wcslen(s2.wc_str())) + , s2.wc_str() ); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const char* s1, const FString& s2) +{ + FString tmp(s1); + tmp._insert ( tmp.getLength() + , uInt(std::wcslen(s2.wc_str())) + , s2.wc_str() ); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const wchar_t c, const FString& s) +{ + FString tmp(c); + tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str()); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const char c, const FString& s) +{ + FString tmp(c); + tmp._insert (1, uInt(std::wcslen(s.wc_str())), s.wc_str()); + return (tmp); +} + +//---------------------------------------------------------------------- +const FString operator + (const wchar_t c, const std::wstring& s) +{ + FString tmp(c); + tmp._insert (1, uInt(s.length()), s.c_str()); + return (tmp); +} diff --git a/src/fstring.h b/src/fstring.h index 5c45c6e1..c1c71900 100644 --- a/src/fstring.h +++ b/src/fstring.h @@ -17,12 +17,12 @@ #include #include -#include // for read errno +#include // for read errno #include #include #include -#include // need for va_list, va_start and va_end -#include // need for vsprintf +#include // need for va_list, va_start and va_end +#include // need for vsprintf #include #include #include @@ -34,11 +34,6 @@ #include -#define FWDBUFFER 15 -#define INPBUFFER 200 -#define CHAR_SIZE (sizeof(wchar_t)) // bytes per character -#define bad_alloc_str ("not enough memory to alloc a new string") - typedef unsigned char uChar; typedef unsigned int uInt; typedef unsigned long uLong; @@ -64,24 +59,9 @@ typedef long double lDouble; class FString { public: + // Typedef typedef const wchar_t* iterator; - private: - wchar_t* string; - uInt length; - uInt bufsize; - mutable char* c_string; - - private: - void initLength (uInt); - void _replace (const wchar_t*); - void _insert (uInt, uInt, const wchar_t*); - void _remove (uInt, uInt); - char* wc_to_c_str (const wchar_t*) const; - wchar_t* c_to_wc_str (const char*) const; - wchar_t* extractToken (wchar_t**, const wchar_t*, const wchar_t*); - - public: // Constructors FString (); explicit FString (int); @@ -90,25 +70,119 @@ class FString FString (uInt, wchar_t); FString (int, char); FString (uInt, char); - FString (const FString&); // implicit conversion constructor + FString (const FString&); // implicit conversion copy constructor FString (const std::wstring&); // implicit conversion constructor FString (const wchar_t*); // implicit conversion constructor FString (const std::string&); // implicit conversion constructor FString (const char*); // implicit conversion constructor FString (const wchar_t); // implicit conversion constructor FString (const char); // implicit conversion constructor + // Destructor virtual ~FString (); + // Overloaded operators + FString& operator = (const FString&); + FString& operator = (const std::wstring&); + const FString& operator = (const wchar_t*); + FString& operator = (const std::string&); + const FString& operator = (const char*); + const FString& operator = (const wchar_t); + const FString& operator = (const char); + + const FString& operator += (const FString&); + const FString& operator += (const std::wstring&); + const FString& operator += (const wchar_t*); + const FString& operator += (const std::string&); + const FString& operator += (const char*); + const FString& operator += (const wchar_t); + const FString& operator += (const char); + + const FString operator + (const FString&); + const FString operator + (const std::wstring&); + const FString operator + (const wchar_t*); + const FString operator + (const std::string&); + const FString operator + (const char*); + const FString operator + (const wchar_t); + const FString operator + (const char); + + wchar_t& operator [] (int); + wchar_t& operator [] (uInt); + const FString operator () (uInt, uInt); + + bool operator < (const FString&) const; + bool operator < (const std::wstring&) const; + bool operator < (const wchar_t*) const; + bool operator < (const std::string&) const; + bool operator < (const char*) const; + bool operator < (const wchar_t) const; + bool operator < (const char) const; + bool operator <= (const FString&) const; + bool operator <= (const std::wstring&) const; + bool operator <= (const wchar_t*) const; + bool operator <= (const std::string&) const; + bool operator <= (const char*) const; + bool operator <= (const wchar_t) const; + bool operator <= (const char) const; + bool operator == (const FString&) const; + bool operator == (const std::wstring&) const; + bool operator == (const wchar_t*) const; + bool operator == (const std::string&) const; + bool operator == (const char*) const; + bool operator == (const wchar_t) const; + bool operator == (const char) const; + bool operator != (const FString&) const; + bool operator != (const std::wstring&) const; + bool operator != (const wchar_t*) const; + bool operator != (const std::string&) const; + bool operator != (const char*) const; + bool operator != (const wchar_t) const; + bool operator != (const char) const; + bool operator >= (const FString&) const; + bool operator >= (const std::wstring&) const; + bool operator >= (const wchar_t*) const; + bool operator >= (const std::string&) const; + bool operator >= (const char*) const; + bool operator >= (const wchar_t) const; + bool operator >= (const char) const; + bool operator > (const FString&) const; + bool operator > (const std::wstring&) const; + bool operator > (const wchar_t*) const; + bool operator > (const std::string&) const; + bool operator > (const char*) const; + bool operator > (const wchar_t) const; + bool operator > (const char) const; + + operator const char* () const { return c_str(); } + + // Non-member operators + friend std::ostream& operator << (std::ostream& outstr, const FString& s); + friend std::istream& operator >> (std::istream& instr, FString& s); + friend std::wostream& operator << (std::wostream& outstr, const FString& s); + friend std::wistream& operator >> (std::wistream& instr, FString& s); + + friend const FString operator + (const FString&, const FString&); + friend const FString operator + (const FString&, const wchar_t); + friend const FString operator + (const std::wstring&, const FString&); + friend const FString operator + (const wchar_t*, const FString&); + friend const FString operator + (const std::string&, const FString&); + friend const FString operator + (const char*, const FString&); + friend const FString operator + (const wchar_t, const FString&); + friend const FString operator + (const char, const FString&); + friend const FString operator + (const wchar_t, const std::wstring&); + + // inquiries bool isNull() const; bool isEmpty() const; + + // Methods uInt getLength() const; uInt getUTF8length() const; iterator begin() const; - iterator end() const; - wchar_t front() const; - wchar_t back() const; + iterator end() const; + wchar_t front() const; + wchar_t back() const; FString& sprintf (const wchar_t*, ...); FString& sprintf (const char*, ...) @@ -175,94 +249,6 @@ class FString FString& setFormatedNumber (long, char = nl_langinfo(THOUSEP)[0]); FString& setFormatedNumber (uLong, char = nl_langinfo(THOUSEP)[0]); - friend std::ostream& operator << (std::ostream& outstr, const FString& s); - friend std::istream& operator >> (std::istream& instr, FString& s); - friend std::wostream& operator << (std::wostream& outstr, const FString& s); - friend std::wistream& operator >> (std::wistream& instr, FString& s); - - FString& operator = (const FString&); - FString& operator = (const std::wstring&); - const FString& operator = (const wchar_t*); - FString& operator = (const std::string&); - const FString& operator = (const char*); - const FString& operator = (const wchar_t); - const FString& operator = (const char); - - const FString& operator += (const FString&); - const FString& operator += (const std::wstring&); - const FString& operator += (const wchar_t*); - const FString& operator += (const std::string&); - const FString& operator += (const char*); - const FString& operator += (const wchar_t); - const FString& operator += (const char); - - const FString operator + (const FString&); - const FString operator + (const std::wstring&); - const FString operator + (const wchar_t*); - const FString operator + (const std::string&); - const FString operator + (const char*); - const FString operator + (const wchar_t); - const FString operator + (const char); - - friend const FString operator + (const FString&, const FString&); - friend const FString operator + (const FString&, const wchar_t); - friend const FString operator + (const std::wstring&, const FString&); - friend const FString operator + (const wchar_t*, const FString&); - friend const FString operator + (const std::string&, const FString&); - friend const FString operator + (const char*, const FString&); - friend const FString operator + (const wchar_t, const FString&); - friend const FString operator + (const char, const FString&); - friend const FString operator + (const wchar_t, const std::wstring&); - - wchar_t& operator [] (int); - wchar_t& operator [] (uInt); - const FString operator () (uInt, uInt); - - bool operator < (const FString&) const; - bool operator < (const std::wstring&) const; - bool operator < (const wchar_t*) const; - bool operator < (const std::string&) const; - bool operator < (const char*) const; - bool operator < (const wchar_t) const; - bool operator < (const char) const; - bool operator <= (const FString&) const; - bool operator <= (const std::wstring&) const; - bool operator <= (const wchar_t*) const; - bool operator <= (const std::string&) const; - bool operator <= (const char*) const; - bool operator <= (const wchar_t) const; - bool operator <= (const char) const; - bool operator == (const FString&) const; - bool operator == (const std::wstring&) const; - bool operator == (const wchar_t*) const; - bool operator == (const std::string&) const; - bool operator == (const char*) const; - bool operator == (const wchar_t) const; - bool operator == (const char) const; - bool operator != (const FString&) const; - bool operator != (const std::wstring&) const; - bool operator != (const wchar_t*) const; - bool operator != (const std::string&) const; - bool operator != (const char*) const; - bool operator != (const wchar_t) const; - bool operator != (const char) const; - bool operator >= (const FString&) const; - bool operator >= (const std::wstring&) const; - bool operator >= (const wchar_t*) const; - bool operator >= (const std::string&) const; - bool operator >= (const char*) const; - bool operator >= (const wchar_t) const; - bool operator >= (const char) const; - bool operator > (const FString&) const; - bool operator > (const std::wstring&) const; - bool operator > (const wchar_t*) const; - bool operator > (const std::string&) const; - bool operator > (const char*) const; - bool operator > (const wchar_t) const; - bool operator > (const char) const; - - operator const char* () const { return c_str(); } - const FString& insert (const FString&, uInt); const FString& insert (const wchar_t*, uInt); const FString& insert (const char*, uInt); @@ -329,11 +315,33 @@ class FString const FString& overwrite (const wchar_t, uInt); const FString& remove (uInt, uInt); - bool includes (const FString&); - bool includes (const wchar_t*); - bool includes (const char*); - bool includes (const wchar_t); - bool includes (const char); + bool includes (const FString&); + bool includes (const wchar_t*); + bool includes (const char*); + bool includes (const wchar_t); + bool includes (const char); + + private: + // Constants + static const uInt FWDBUFFER = 15; + static const uInt INPBUFFER = 200; + static const uInt CHAR_SIZE = sizeof(wchar_t); // bytes per character + static const char* bad_alloc_str; + + // Methods + void initLength (uInt); + void _replace (const wchar_t*); + void _insert (uInt, uInt, const wchar_t*); + void _remove (uInt, uInt); + char* wc_to_c_str (const wchar_t*) const; + wchar_t* c_to_wc_str (const char*) const; + wchar_t* extractToken (wchar_t**, const wchar_t*, const wchar_t*); + + // Data Members + wchar_t* string; + uInt length; + uInt bufsize; + mutable char* c_string; }; diff --git a/src/fswitch.cpp b/src/fswitch.cpp index 974710f1..da54750b 100644 --- a/src/fswitch.cpp +++ b/src/fswitch.cpp @@ -33,6 +33,66 @@ FSwitch::~FSwitch() // destructor { } +// public methods of FSwitch +//---------------------------------------------------------------------- +void FSwitch::setText (FString txt) +{ + FToggleButton::setText(txt); + switch_offset_pos = int(txt.getLength()) + 1; +} + +//---------------------------------------------------------------------- +void FSwitch::onKeyPress (FKeyEvent* ev) +{ + switch ( ev->key() ) + { + case fc::Fkey_home: + case fc::Fkey_left: + setChecked(); + ev->accept(); + break; + + case fc::Fkey_end: + case fc::Fkey_right: + unsetChecked(); + ev->accept(); + break; + + default: + break; + } + + if ( ev->isAccepted() ) + draw(); + else + FToggleButton::onKeyPress(ev); +} + +//---------------------------------------------------------------------- +void FSwitch::onMouseDown (FMouseEvent* ev) +{ + FToggleButton::onMouseDown(ev); + + if ( ev->getButton() != fc::LeftButton ) + return; + + button_pressed = true; + draw(); +} + +//---------------------------------------------------------------------- +void FSwitch::onMouseUp (FMouseEvent* ev) +{ + FToggleButton::onMouseUp(ev); + + if ( ev->getButton() != fc::LeftButton ) + return; + + button_pressed = false; + draw(); +} + + // private methods of FSwitch //---------------------------------------------------------------------- void FSwitch::draw() @@ -143,62 +203,3 @@ void FSwitch::drawCheckButton() setCursorPos (7 + switch_offset_pos, 1); } } - -// public methods of FSwitch -//---------------------------------------------------------------------- -void FSwitch::setText (FString txt) -{ - FToggleButton::setText(txt); - switch_offset_pos = int(txt.getLength()) + 1; -} - -//---------------------------------------------------------------------- -void FSwitch::onKeyPress (FKeyEvent* ev) -{ - switch ( ev->key() ) - { - case fc::Fkey_home: - case fc::Fkey_left: - setChecked(); - ev->accept(); - break; - - case fc::Fkey_end: - case fc::Fkey_right: - unsetChecked(); - ev->accept(); - break; - - default: - break; - } - - if ( ev->isAccepted() ) - draw(); - else - FToggleButton::onKeyPress(ev); -} - -//---------------------------------------------------------------------- -void FSwitch::onMouseDown (FMouseEvent* ev) -{ - FToggleButton::onMouseDown(ev); - - if ( ev->getButton() != fc::LeftButton ) - return; - - button_pressed = true; - draw(); -} - -//---------------------------------------------------------------------- -void FSwitch::onMouseUp (FMouseEvent* ev) -{ - FToggleButton::onMouseUp(ev); - - if ( ev->getButton() != fc::LeftButton ) - return; - - button_pressed = false; - draw(); -} diff --git a/src/fswitch.h b/src/fswitch.h index 86eac5a0..d3b3ee7b 100644 --- a/src/fswitch.h +++ b/src/fswitch.h @@ -45,33 +45,39 @@ class FSwitch : public FToggleButton { - private: - int switch_offset_pos; - bool button_pressed; - - private: - // Disable copy constructor - FSwitch (const FSwitch&); - // Disable assignment operator (=) - FSwitch& operator = (const FSwitch&); - - void draw(); - void drawCheckButton(); - public: // Constructors explicit FSwitch (FWidget* = 0); FSwitch (const FString&, FWidget* = 0); + // Destructor virtual ~FSwitch(); + // Accessor const char* getClassName() const; + + // Mutator void setText (FString); // Event handlers void onKeyPress (FKeyEvent*); void onMouseDown (FMouseEvent*); void onMouseUp (FMouseEvent*); + + private: + // Disable copy constructor + FSwitch (const FSwitch&); + + // Disable assignment operator (=) + FSwitch& operator = (const FSwitch&); + + // Methods + void draw(); + void drawCheckButton(); + + // Data Members + int switch_offset_pos; + bool button_pressed; }; #pragma pack(pop) diff --git a/src/fterm.cpp b/src/fterm.cpp index af3be819..22a16888 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -78,8 +78,7 @@ FTerm::modifier_key FTerm::mod_key; std::map* FTerm::vt100_alt_char = 0; std::map* \ FTerm::encoding_set = 0; -FTermcap::tcap_map* FTerm::tcap = term_caps; -FTermcap::tcap_map* FTermcap::tcap = 0; +FTerm::termcap_map* FTerm::tcap = term_caps; bool FTermcap::background_color_erase = false; bool FTermcap::automatic_left_margin = false; bool FTermcap::automatic_right_margin = false; @@ -124,6 +123,1426 @@ FTerm::~FTerm() // destructor } +// public methods of FTerm +//---------------------------------------------------------------------- +int FTerm::getLineNumber() +{ + if ( term->getHeight() == 0 ) + detectTermSize(); + + return term->getHeight(); +} + +//---------------------------------------------------------------------- +int FTerm::getColumnNumber() +{ + if ( term->getWidth() == 0 ) + detectTermSize(); + + return term->getWidth(); +} + +//---------------------------------------------------------------------- +FString FTerm::getKeyName (int keynum) +{ + for (int i=0; FkeyName[i].string[0] != 0; i++) + if ( FkeyName[i].num && FkeyName[i].num == keynum ) + return FString(FkeyName[i].string); + + if ( keynum > 32 && keynum < 127 ) + return FString(char(keynum)); + + return FString(""); +} + +//---------------------------------------------------------------------- +FTerm::modifier_key& FTerm::getModifierKey() +{ + char subcode = 6; + // fill bit field with 0 + std::memset (&mod_key, 0x00, sizeof(mod_key)); + + // TIOCLINUX, subcode=6 + if ( ioctl(0, TIOCLINUX, &subcode) >= 0 ) + { + if ( subcode & (1 << KG_SHIFT) ) + mod_key.shift = true; + + if ( subcode & (1 << KG_ALTGR) ) + mod_key.alt_gr = true; + + if ( subcode & (1 << KG_CTRL) ) + mod_key.ctrl = true; + + if ( subcode & (1 << KG_ALT) ) + mod_key.alt = true; + } + + return mod_key; +} + +//---------------------------------------------------------------------- +fc::consoleCursorStyle FTerm::getConsoleCursor() +{ + return console_cursor_style; +} + +//---------------------------------------------------------------------- +bool FTerm::isKeyTimeout (timeval* time, register long timeout) +{ + register long diff_usec; + struct timeval now; + struct timeval diff; + + FObject::getCurrentTime(now); + diff.tv_sec = now.tv_sec - time->tv_sec; + diff.tv_usec = now.tv_usec - time->tv_usec; + + if ( diff.tv_usec < 0 ) + { + diff.tv_sec--; + diff.tv_usec += 1000000; + } + + diff_usec = (diff.tv_sec * 1000000) + diff.tv_usec; + return (diff_usec > timeout); +} + +//---------------------------------------------------------------------- +void FTerm::setConsoleCursor (fc::consoleCursorStyle style, bool hidden) +{ + // Set cursor style in linux console + if ( ! linux_terminal ) + return; + + console_cursor_style = style; + + if ( hidden ) + return; + + putstringf (CSI "?%dc", style); + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +bool FTerm::setRawMode (bool on) +{ + if ( on == raw_mode ) + return raw_mode; + + std::fflush(stdout); + + if ( on ) + { + // Info under: man 3 termios + struct termios t; + tcgetattr (stdin_no, &t); + + /* set + unset flags for raw mode */ + // input mode + t.c_iflag &= uInt(~(IGNBRK | BRKINT | PARMRK | ISTRIP + | INLCR | IGNCR | ICRNL | IXON)); + // output mode + t.c_oflag &= uInt(~OPOST); + + // local mode +#if DEBUG + // Exit with ctrl-c only if compiled with "DEBUG" option + t.c_lflag &= uInt(~(ECHO | ECHONL | ICANON | IEXTEN)); +#else + // Plus disable signals. + t.c_lflag &= uInt(~(ECHO | ECHONL | ICANON | IEXTEN | ISIG)); +#endif + + // control mode + t.c_cflag &= uInt(~(CSIZE | PARENB)); + t.c_cflag |= uInt(CS8); + + // defines the terminal special characters for noncanonical read + t.c_cc[VTIME] = 0; // Timeout in deciseconds + t.c_cc[VMIN] = 1; // Minimum number of characters + + // set the new termios settings + tcsetattr (stdin_no, TCSAFLUSH, &t); + raw_mode = true; + } + else + { + // restore termios settings + tcsetattr (stdin_no, TCSAFLUSH, &term_init); + raw_mode = false; + } + + return raw_mode; +} + +//---------------------------------------------------------------------- +bool FTerm::setUTF8 (bool on) // UTF-8 (Unicode) +{ + if ( on == utf8_state ) + return utf8_state; + + if ( on ) + utf8_state = true; + else + utf8_state = false; + + if ( linux_terminal ) + { + if ( on ) + putstring (ESC "%G"); + else + putstring (ESC "%@"); + } + + std::fflush(stdout); + return utf8_state; +} + +//---------------------------------------------------------------------- +bool FTerm::setNonBlockingInput (bool on) +{ + if ( on == non_blocking_stdin ) + return non_blocking_stdin; + + if ( on ) // make stdin non-blocking + { + stdin_status_flags |= O_NONBLOCK; + + if ( fcntl (stdin_no, F_SETFL, stdin_status_flags) != -1 ) + non_blocking_stdin = true; + } + else + { + stdin_status_flags &= ~O_NONBLOCK; + + if ( fcntl (stdin_no, F_SETFL, stdin_status_flags) != -1 ) + non_blocking_stdin = false; + } + + return non_blocking_stdin; +} + +//---------------------------------------------------------------------- +int FTerm::parseKeyString ( char* buffer + , int buf_size + , timeval* time_keypressed ) +{ + register uChar firstchar = uChar(buffer[0]); + register size_t buf_len = std::strlen(buffer); + const long key_timeout = 100000; // 100 ms + int key, len, n; + + if ( firstchar == ESC[0] ) + { + // x11 mouse tracking + if ( buf_len >= 6 && buffer[1] == '[' && buffer[2] == 'M' ) + return fc::Fkey_mouse; + + // SGR mouse tracking + if ( buffer[1] == '[' && buffer[2] == '<' && buf_len >= 9 + && (buffer[buf_len-1] == 'M' || buffer[buf_len-1] == 'm') ) + return fc::Fkey_extended_mouse; + + // urxvt mouse tracking + if ( buffer[1] == '[' && buffer[2] >= '1' && buffer[2] <= '9' + && buffer[3] >= '0' && buffer[3] <= '9' && buf_len >= 9 + && buffer[buf_len-1] == 'M' ) + return fc::Fkey_urxvt_mouse; + + // look for termcap keys + for (int i=0; Fkey[i].tname[0] != 0; i++) + { + char* k = Fkey[i].string; + len = (k) ? int(std::strlen(k)) : 0; + + if ( k && std::strncmp(k, buffer, uInt(len)) == 0 ) // found + { + n = len; + + for (; n < buf_size; n++) // Remove founded entry + buffer[n-len] = buffer[n]; + + for (; n-len < len; n++) // Fill rest with '\0' + buffer[n-len] = '\0'; + + input_data_pending = bool(buffer[0] != '\0'); + return Fkey[i].num; + } + } + + // look for meta keys + for (int i=0; Fmetakey[i].string[0] != 0; i++) + { + char* kmeta = Fmetakey[i].string; // The string is never null + len = int(std::strlen(kmeta)); + + if ( std::strncmp(kmeta, buffer, uInt(len)) == 0 ) // found + { + if ( len == 2 && ( buffer[1] == 'O' + || buffer[1] == '[' + || buffer[1] == ']') ) + { + if ( ! isKeyTimeout(time_keypressed, key_timeout) ) + return NEED_MORE_DATA; + } + n = len; + + for (; n < buf_size; n++) // Remove founded entry + buffer[n-len] = buffer[n]; + + for (; n-len < len; n++) // Fill rest with '\0' + buffer[n-len] = '\0'; + + input_data_pending = bool(buffer[0] != '\0'); + return Fmetakey[i].num; + } + } + + if ( ! isKeyTimeout(time_keypressed, key_timeout) ) + return NEED_MORE_DATA; + } + + // look for utf-8 character + + len = 1; + + if ( utf8_input && (firstchar & 0xc0) == 0xc0 ) + { + char utf8char[4] = {}; // init array with '\0' + + if ((firstchar & 0xe0) == 0xc0) + len = 2; + else if ((firstchar & 0xf0) == 0xe0) + len = 3; + else if ((firstchar & 0xf8) == 0xf0) + len = 4; + + for (n=0; n < len ; n++) + utf8char[n] = char(buffer[n] & 0xff); + + key = UTF8decode(utf8char); + } + else + key = uChar(buffer[0] & 0xff); + + n = len; + + for (; n < buf_size; n++) // remove the key from the buffer front + buffer[n-len] = buffer[n]; + + for (n=n-len; n < buf_size; n++) // fill the rest with '\0' bytes + buffer[n] = '\0'; + + input_data_pending = bool(buffer[0] != '\0'); + + if ( key == 0 ) // Ctrl+Space or Ctrl+@ + key = fc::Fckey_space; + + return int(key == 127 ? fc::Fkey_backspace : key); +} + +//---------------------------------------------------------------------- +bool& FTerm::unprocessedInput() +{ + return input_data_pending; +} + +//---------------------------------------------------------------------- +bool FTerm::setVGAFont() +{ + if ( VGAFont ) + return VGAFont; + + if ( gnome_terminal + || kde_konsole + || putty_terminal + || tera_terminal + || cygwin_terminal + || mintty_terminal ) + return false; + + VGAFont = true; + + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + // Set font in xterm to vga + oscPrefix(); + putstring (OSC "50;vga" BEL); + oscPostfix(); + std::fflush(stdout); + NewFont = false; + pc_charset_console = true; + Encoding = fc::PC; + + if ( xterm_terminal && utf8_console ) + Fputchar = &FTerm::putchar_UTF8; + else + Fputchar = &FTerm::putchar_ASCII; + } + else if ( linux_terminal ) + { + if ( openConsole() == 0 ) + { + if ( isConsole() ) + { + // standard vga font 8x16 + int ret = setScreenFont(__8x16std, 256, 8, 16); + + if ( ret != 0 ) + VGAFont = false; + + // unicode character mapping + struct unimapdesc unimap; + unimap.entry_ct = uChar ( sizeof(unicode_cp437_pairs) + / sizeof(unipair) ); + unimap.entries = &unicode_cp437_pairs[0]; + setUnicodeMap(&unimap); + } + else + VGAFont = false; + + detectTermSize(); + closeConsole(); + } + else + VGAFont = false; + + pc_charset_console = true; + Encoding = fc::PC; + Fputchar = &FTerm::putchar_ASCII; + } + else + VGAFont = false; + + return VGAFont; +} + +//---------------------------------------------------------------------- +bool FTerm::setNewFont() +{ + if ( NewFont ) + return true; + + if ( gnome_terminal + || kde_konsole + || putty_terminal + || tera_terminal + || cygwin_terminal + || mintty_terminal ) + return false; + + if ( xterm_terminal || screen_terminal + || urxvt_terminal || FTermcap::osc_support ) + { + NewFont = true; + // Set font in xterm to 8x16graph + oscPrefix(); + putstring (OSC "50;8x16graph" BEL); + oscPostfix(); + std::fflush(stdout); + pc_charset_console = true; + Encoding = fc::PC; + + if ( xterm_terminal && utf8_console ) + Fputchar = &FTerm::putchar_UTF8; + else + Fputchar = &FTerm::putchar_ASCII; + } + else if ( linux_terminal ) + { + NewFont = true; + + if ( openConsole() == 0 ) + { + if ( isConsole() ) + { + struct unimapdesc unimap; + int ret; + + // Set the graphical font 8x16 + ret = setScreenFont(__8x16graph, 256, 8, 16); + + if ( ret != 0 ) + NewFont = false; + + // unicode character mapping + unimap.entry_ct = uInt16 ( sizeof(unicode_cp437_pairs) + / sizeof(unipair) ); + unimap.entries = &unicode_cp437_pairs[0]; + setUnicodeMap(&unimap); + } + + detectTermSize(); + closeConsole(); + } + + pc_charset_console = true; + Encoding = fc::PC; + Fputchar = &FTerm::putchar_ASCII; // function pointer + } + else + NewFont = false; + + return NewFont; +} + +//---------------------------------------------------------------------- +bool FTerm::setOldFont() +{ + bool retval; + + if ( ! (NewFont || VGAFont) ) + return false; + + retval = \ + NewFont = \ + VGAFont = false; + + if ( xterm_terminal || screen_terminal + || urxvt_terminal || FTermcap::osc_support ) + { + if ( xterm_font && xterm_font->getLength() > 2 ) + { + // restore saved xterm font + oscPrefix(); + putstringf (OSC "50;%s" BEL, xterm_font->c_str() ); + oscPostfix(); + } + else + { + // Set font in xterm to vga + oscPrefix(); + putstring (OSC "50;vga" BEL); + oscPostfix(); + } + + std::fflush(stdout); + retval = true; + } + else if ( linux_terminal ) + { + if ( openConsole() == 0 ) + { + if ( isConsole() ) + { + if ( screen_font.data ) + { + int ret = setScreenFont ( screen_font.data + , screen_font.charcount + , screen_font.width + , screen_font.height + , true ); + delete[] screen_font.data; + + if ( ret == 0 ) + retval = true; + } + + if ( screen_unicode_map.entries ) + { + setUnicodeMap (&screen_unicode_map); + delete[] screen_unicode_map.entries; + } + + } + + detectTermSize(); + closeConsole(); + } + } + + return retval; +} + +//---------------------------------------------------------------------- +char* FTerm::moveCursor (int xold, int yold, int xnew, int ynew) +{ + // returns the cursor move string + if ( cursor_optimisation ) + return opti_move->moveCursor (xold, yold, xnew, ynew); + else + return tgoto(tcap[fc::t_cursor_address].string, xnew, ynew); +} + +//---------------------------------------------------------------------- +char* FTerm::enableCursor() +{ + char*& vs = tcap[fc::t_cursor_visible].string; + char*& ve = tcap[fc::t_cursor_normal].string; + + if ( ve ) + return ve; + else if ( vs ) + return vs; + + return 0; +} + +//---------------------------------------------------------------------- +char* FTerm::disableCursor() +{ + char*& vi = tcap[fc::t_cursor_invisible].string; + + if ( vi ) + return vi; + + return 0; +} + +//---------------------------------------------------------------------- +void FTerm::detectTermSize() +{ + struct winsize win_size; + bool close_after_detect = false; + int ret; + + if ( fd_tty < 0 ) // console is already closed + { + if ( openConsole() != 0 ) + return; + + close_after_detect = true; + } + + ret = ioctl (fd_tty, TIOCGWINSZ, &win_size); + + if ( ret != 0 || win_size.ws_col == 0 || win_size.ws_row == 0 ) + { + char* str; + term->setPos(1,1); + str = std::getenv("COLUMNS"); + term->setWidth(str ? std::atoi(str) : 80); + str = std::getenv("LINES"); + term->setHeight(str ? std::atoi(str) : 25); + } + else + { + term->setRect(1, 1, win_size.ws_col, win_size.ws_row); + } + + opti_move->setTermSize (term->getWidth(), term->getHeight()); + + if ( close_after_detect ) + closeConsole(); +} + +//---------------------------------------------------------------------- +void FTerm::setTermSize (int term_width, int term_height) +{ + // Set xterm size to {term_width} x {term_height} + if ( xterm_terminal ) + { + putstringf (CSI "8;%d;%dt", term_height, term_width); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setKDECursor (fc::kdeKonsoleCursorShape style) +{ + // Set cursor style in KDE konsole + if ( kde_konsole ) + { + oscPrefix(); + putstringf (OSC "50;CursorShape=%d" BEL, style); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +const FString FTerm::getXTermFont() +{ + FString font(""); + + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + if ( raw_mode && non_blocking_stdin ) + { + int n; + char temp[150] = {}; + oscPrefix(); + putstring (OSC "50;?" BEL); // get font + oscPostfix(); + std::fflush(stdout); + usleep(150000); // wait 150 ms + + // read the terminal answer + n = int(read(fileno(stdin), &temp, sizeof(temp)-1)); + + // BEL + '\0' = string terminator + if ( n >= 6 && temp[n-1] == BEL[0] && temp[n] == '\0' ) + { + temp[n-1] = '\0'; + font = static_cast(temp + 5); + } + } + } + + return font; +} + +//---------------------------------------------------------------------- +const FString FTerm::getXTermTitle() +{ + FString title(""); + + if ( kde_konsole ) + return title; + + if ( raw_mode && non_blocking_stdin ) + { + int n; + char temp[512] = {}; + putstring (CSI "21t"); // get title + std::fflush(stdout); + usleep(150000); // wait 150 ms + + // read the terminal answer + n = int(read(fileno(stdin), &temp, sizeof(temp)-1)); + + // Esc + \ = OSC string terminator + if ( n >= 5 && temp[n-1] == '\\' && temp[n-2] == ESC[0] ) + { + temp[n-2] = '\0'; + title = static_cast(temp + 3); + } + } + + return title; +} + +//---------------------------------------------------------------------- +void FTerm::setXTermCursorStyle (fc::xtermCursorStyle style) +{ + // Set the xterm cursor style + if ( (xterm_terminal || mintty_terminal) && ! (gnome_terminal || kde_konsole) ) + { + putstringf (CSI "%d q", style); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermTitle (const FString& title) +{ + // Set the xterm title + if ( xterm_terminal || screen_terminal + || mintty_terminal || putty_terminal + || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "0;%s" BEL, title.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermForeground (const FString& fg) +{ + // Set the VT100 text foreground color + if ( xterm_terminal || screen_terminal + || mintty_terminal || mlterm_terminal + || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "10;%s" BEL, fg.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermBackground (const FString& bg) +{ + // Set the VT100 text background color + if ( xterm_terminal || screen_terminal + || mintty_terminal || mlterm_terminal + || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "11;%s" BEL, bg.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermCursorColor (const FString& cc) +{ + // Set the text cursor color + if ( xterm_terminal || screen_terminal + || mintty_terminal || urxvt_terminal + || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "12;%s" BEL, cc.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermMouseForeground (const FString& mfg) +{ + // Set the mouse foreground color + if ( xterm_terminal || screen_terminal + || urxvt_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "13;%s" BEL, mfg.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermMouseBackground (const FString& mbg) +{ + // Set the mouse background color + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "14;%s" BEL, mbg.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setXTermHighlightBackground (const FString& hbg) +{ + // Set the highlight background color + if ( xterm_terminal || screen_terminal + || urxvt_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "17;%s" BEL, hbg.c_str()); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermColors() +{ + // Reset the entire color table + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "104" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermForeground() +{ + // Reset the VT100 text foreground color + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstring (OSC "110" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermBackground() +{ + // Reset the VT100 text background color + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstring (OSC "111" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermCursorColor() +{ + // Reset the text cursor color + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstring (OSC "112" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermMouseForeground() +{ + // Reset the mouse foreground color + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstring (OSC "113" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermMouseBackground() +{ + // Reset the mouse background color + if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstring (OSC "114" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::resetXTermHighlightBackground() +{ + // Reset the highlight background color + if ( xterm_terminal || screen_terminal + || urxvt_terminal || FTermcap::osc_support ) + { + oscPrefix(); + putstringf (OSC "117" BEL); + oscPostfix(); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::saveColorMap() +{ + // ioctl (0, GIO_CMAP, &color_map); +} + +//---------------------------------------------------------------------- +void FTerm::resetColorMap() +{ + char*& op = tcap[fc::t_orig_pair].string; + char*& oc = tcap[fc::t_orig_colors].string; + + if ( op ) + putstring (op); + else if ( oc ) + putstring (oc); +/*else + { + dacreg CurrentColors[16] = + { + {0x00, 0x00, 0x00}, {0xAA, 0x00, 0x00}, + {0x00, 0xAA, 0x00}, {0xAA, 0x55, 0x00}, + {0x00, 0x00, 0xAA}, {0xAA, 0x00, 0xAA}, + {0x00, 0xAA, 0xAA}, {0xAA, 0xAA, 0xAA}, + {0x55, 0x55, 0x55}, {0xFF, 0x55, 0x55}, + {0x55, 0xFF, 0x55}, {0xFF, 0xFF, 0x55}, + {0x55, 0x55, 0xFF}, {0xFF, 0x55, 0xFF}, + {0x55, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF} + }; + for (int x=0; x<16; x++) + { + color_map.d[x].red = CurrentColors[x].red; + color_map.d[x].green = CurrentColors[x].green; + color_map.d[x].blue = CurrentColors[x].blue; + } + ioctl (0, PIO_CMAP, &color_map); + }*/ + + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +void FTerm::setPalette (short index, int r, int g, int b) +{ + char*& Ic = tcap[fc::t_initialize_color].string; + char*& Ip = tcap[fc::t_initialize_pair].string; + + index = FOptiAttr::vga2ansi(index); + + if ( Ic || Ip ) + { + int rr, gg, bb; + const char* color_str = ""; + + rr = (r * 1001) / 256; + gg = (g * 1001) / 256; + bb = (b * 1001) / 256; + + if ( Ic ) + color_str = tparm(Ic, index, rr, gg, bb, 0, 0, 0, 0, 0); + else if ( Ip ) + color_str = tparm(Ip, index, 0, 0, 0, rr, gg, bb, 0, 0); + + putstring (color_str); + } + else if ( linux_terminal ) + { +/* // direct vga-register set + if ( r>=0 && r<256 + && g>=0 && g<256 + && b>=0 && b<256 ) + { + map.d[index].red = r; + map.d[index].green = g; + map.d[index].blue = b; + } + ioctl (0, PIO_CMAP, &map); */ + } + + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +void FTerm::setBeep (int Hz, int ms) +{ + if ( ! linux_terminal ) + return; + + // range for frequency: 21-32766 + if ( Hz < 21 || Hz > 32766 ) + return; + + // range for duration: 0-1999 + if ( ms < 0 || ms > 1999 ) + return; + + putstringf ( CSI "10;%d]" + CSI "11;%d]" + , Hz, ms ); + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +void FTerm::resetBeep() +{ + if ( ! linux_terminal ) + return; + + // default frequency: 750 Hz + // default duration: 125 ms + putstring ( CSI "10;750]" + CSI "11;125]" ); + std::fflush(stdout); +} + +//---------------------------------------------------------------------- +void FTerm::beep() +{ + if ( tcap[fc::t_bell].string ) + { + putstring (tcap[fc::t_bell].string); + std::fflush(stdout); + } +} + +//---------------------------------------------------------------------- +void FTerm::setEncoding (std::string enc) +{ + std::map::const_iterator it; + + // available encodings: "UTF8", "VT100", "PC" and "ASCII" + it = encoding_set->find(enc); + + if ( it == encoding_set->end() ) // not found + return; + + Encoding = it->second; + + assert ( Encoding == fc::UTF8 + || Encoding == fc::VT100 + || Encoding == fc::PC + || Encoding == fc::ASCII ); + + // set the new Fputchar function pointer + switch ( int(Encoding) ) + { + case fc::UTF8: + Fputchar = &FTerm::putchar_UTF8; + break; + + case fc::VT100: + case fc::PC: + if ( xterm_terminal && utf8_console ) + Fputchar = &FTerm::putchar_UTF8; + // fall through + case fc::ASCII: + default: + Fputchar = &FTerm::putchar_ASCII; + } +} + +//---------------------------------------------------------------------- +std::string FTerm::getEncoding() +{ + std::map::const_iterator it, end; + end = encoding_set->end(); + + for (it = encoding_set->begin(); it != end; ++it ) + if ( it->second == Encoding ) + return it->first; + + return ""; +} + +//---------------------------------------------------------------------- +bool FTerm::scrollTermForward() +{ + if ( tcap[fc::t_scroll_forward].string ) + { + putstring (tcap[fc::t_scroll_forward].string); + std::fflush(stdout); + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +bool FTerm::scrollTermReverse() +{ + if ( tcap[fc::t_scroll_reverse].string ) + { + putstring (tcap[fc::t_scroll_reverse].string); + std::fflush(stdout); + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +const FString FTerm::getAnswerbackMsg() +{ + FString answerback = ""; + + if ( raw_mode ) + { + ssize_t n; + fd_set ifds; + struct timeval tv; + char temp[10] = {}; + + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 150000; // 150 ms + + std::putchar (ENQ[0]); // send enquiry character + std::fflush(stdout); + + // read the answerback message + if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0) + { + n = read(fileno(stdin), &temp, sizeof(temp)-1); + + if ( n > 0 ) + { + temp[n] = '\0'; + answerback = temp; + } + } + } + + return answerback; +} + +//---------------------------------------------------------------------- +const FString FTerm::getSecDA() +{ + FString sec_da_str = ""; + + if ( raw_mode ) + { + ssize_t n; + fd_set ifds; + struct timeval tv; + char temp[16] = {}; + + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 550000; // 150 ms + + // get the secondary device attributes + std::putchar (SECDA[0]); + std::putchar (SECDA[1]); + std::putchar (SECDA[2]); + std::putchar (SECDA[3]); + + std::fflush(stdout); + usleep(150000); // min. wait time 150 ms (need for mintty) + + // read the answer + if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0 ) + { + n = read(fileno(stdin), &temp, sizeof(temp)-1); + + if ( n > 0 ) + { + temp[n] = '\0'; + sec_da_str = temp; + } + } + } + + return sec_da_str; +} + +//---------------------------------------------------------------------- +void FTerm::putstringf (const char* format, ...) +{ + assert ( format != 0 ); + char buf[512]; + char* buffer; + va_list args; + + buffer = buf; + va_start (args, format); + std::vsnprintf (buffer, sizeof(buf), format, args); + va_end (args); + + tputs (buffer, 1, std::putchar); +} + +//---------------------------------------------------------------------- +inline void FTerm::putstring (const char* s, int affcnt) +{ + tputs (s, affcnt, std::putchar); +} + +//---------------------------------------------------------------------- +int FTerm::putchar_ASCII (register int c) +{ + if ( std::putchar(char(c)) == EOF ) + return 0; + else + return 1; +} + +//---------------------------------------------------------------------- +int FTerm::putchar_UTF8 (register int c) +{ + if (c < 0x80) + { + // 1 Byte (7-bit): 0xxxxxxx + std::putchar (c); + return 1; + } + else if (c < 0x800) + { + // 2 byte (11-bit): 110xxxxx 10xxxxxx + std::putchar (0xc0 | (c >> 6) ); + std::putchar (0x80 | (c & 0x3f) ); + return 2; + } + else if (c < 0x10000) + { + // 3 byte (16-bit): 1110xxxx 10xxxxxx 10xxxxxx + std::putchar (0xe0 | (c >> 12) ); + std::putchar (0x80 | ((c >> 6) & 0x3f) ); + std::putchar (0x80 | (c & 0x3f) ); + return 3; + } + else if (c < 0x200000) + { + // 4 byte (21-bit): 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + std::putchar (0xf0 | (c >> 18) ); + std::putchar (0x80 | ((c >> 12) & 0x3f) ); + std::putchar (0x80 | ((c >> 6) & 0x3f) ); + std::putchar (0x80 | (c & 0x3f)); + return 4; + } + else + return EOF; +} + +//---------------------------------------------------------------------- +int FTerm::UTF8decode(char* utf8) +{ + register int ucs=0; + + for (register int i=0; i < int(std::strlen(utf8)); ++i) + { + register uChar ch = uChar(utf8[i]); + + if ((ch & 0xc0) == 0x80) + { + // byte 2..4 = 10xxxxxx + ucs = (ucs << 6) | (ch & 0x3f); + } + else if (ch < 128) + { + // byte 1 = 0xxxxxxx (1 byte mapping) + ucs = ch & 0xff; + } + else if ((ch & 0xe0) == 0xc0) + { + // byte 1 = 110xxxxx (2 byte mapping) + ucs = ch & 0x1f; + } + else if ((ch & 0xf0) == 0xe0) + { + // byte 1 = 1110xxxx (3 byte mapping) + ucs = ch & 0x0f; + } + else if ((ch & 0xf8) == 0xf0) + { + // byte 1 = 11110xxx (4 byte mapping) + ucs = ch & 0x07; + } + else + { + // error + ucs = EOF; + } + } + + return ucs; +} + + +// protected methods of FTerm +//---------------------------------------------------------------------- +void FTerm::init_consoleCharMap() +{ + if ( NewFont || VGAFont ) + return; + + if ( screen_unicode_map.entry_ct != 0 ) + { + for (int i=0; i <= lastCharItem; i++ ) + { + bool found = false; + + for (uInt n=0; n < screen_unicode_map.entry_ct; n++) + { + if ( character[i][fc::UTF8] == screen_unicode_map.entries[n].unicode ) + { + found = true; + break; + } + } + + if ( ! found ) + character[i][fc::PC] = character[i][fc::ASCII]; + } + } +} + +//---------------------------------------------------------------------- +bool FTerm::charEncodable (uInt c) +{ + uInt ch = charEncode(c); + return bool(ch > 0 && ch != c); +} + +//---------------------------------------------------------------------- +uInt FTerm::charEncode (uInt c) +{ + return charEncode (c, Encoding); +} + +//---------------------------------------------------------------------- +uInt FTerm::charEncode (uInt c, fc::encoding enc) +{ + for (uInt i=0; i <= uInt(lastCharItem); i++) + { + if ( character[i][0] == c ) + { + c = character[i][enc]; + break; + } + } + + return c; +} + +//---------------------------------------------------------------------- +char* FTerm::changeAttribute ( char_data*& term_attr + , char_data*& next_attr ) +{ + return opti_attr->changeAttribute (term_attr, next_attr); +} + +//---------------------------------------------------------------------- +void FTerm::xtermMouse (bool on) +{ + // activate/deactivate the xterm mouse support + if ( ! mouse_support ) + return; + + if ( on ) + putstring (CSI "?1001s" // save old highlight mouse tracking + CSI "?1000h" // enable x11 mouse tracking + CSI "?1002h" // enable cell motion mouse tracking + CSI "?1015h" // enable urxvt mouse mode + CSI "?1006h"); // enable SGR mouse mode + else + putstring (CSI "?1006l" // disable SGR mouse mode + CSI "?1015l" // disable urxvt mouse mode + CSI "?1002l" // disable cell motion mouse tracking + CSI "?1000l" // disable x11 mouse tracking + CSI "?1001r"); // restore old highlight mouse tracking + + std::fflush(stdout); +} + + +#ifdef F_HAVE_LIBGPM +//---------------------------------------------------------------------- +bool FTerm::gpmMouse (bool on) +{ + // activate/deactivate the gpm mouse support + if ( ! linux_terminal ) + return false; + + if ( openConsole() == 0 ) + { + if ( ! isConsole() ) + return false; + + closeConsole(); + } + + if ( on ) + { + Gpm_Connect conn; + conn.eventMask = uInt16(~GPM_MOVE); + conn.defaultMask = GPM_MOVE; + conn.maxMod = uInt16(~0); + conn.minMod = 0; + Gpm_Open(&conn, 0); + + switch ( gpm_fd ) + { + case -1: + return false; + + case -2: + Gpm_Close(); + return false; + + default: + break; + } + } + else + { + Gpm_Close(); + } + + return on; +} +#endif // F_HAVE_LIBGPM + + // private methods of FTerm //---------------------------------------------------------------------- inline uInt16 FTerm::getInputStatusRegisterOne() @@ -552,209 +1971,6 @@ int FTerm::setUnicodeMap (struct unimapdesc* unimap) return -1; } -//---------------------------------------------------------------------- -bool FTerm::isKeyTimeout (timeval* time, register long timeout) -{ - register long diff_usec; - struct timeval now; - struct timeval diff; - - FObject::getCurrentTime(now); - diff.tv_sec = now.tv_sec - time->tv_sec; - diff.tv_usec = now.tv_usec - time->tv_usec; - - if ( diff.tv_usec < 0 ) - { - diff.tv_sec--; - diff.tv_usec += 1000000; - } - - diff_usec = (diff.tv_sec * 1000000) + diff.tv_usec; - return (diff_usec > timeout); -} - -//---------------------------------------------------------------------- -int FTerm::parseKeyString ( char* buffer - , int buf_size - , timeval* time_keypressed ) -{ - register uChar firstchar = uChar(buffer[0]); - register size_t buf_len = std::strlen(buffer); - const long key_timeout = 100000; // 100 ms - int key, len, n; - - if ( firstchar == ESC[0] ) - { - // x11 mouse tracking - if ( buf_len >= 6 && buffer[1] == '[' && buffer[2] == 'M' ) - return fc::Fkey_mouse; - - // SGR mouse tracking - if ( buffer[1] == '[' && buffer[2] == '<' && buf_len >= 9 - && (buffer[buf_len-1] == 'M' || buffer[buf_len-1] == 'm') ) - return fc::Fkey_extended_mouse; - - // urxvt mouse tracking - if ( buffer[1] == '[' && buffer[2] >= '1' && buffer[2] <= '9' - && buffer[3] >= '0' && buffer[3] <= '9' && buf_len >= 9 - && buffer[buf_len-1] == 'M' ) - return fc::Fkey_urxvt_mouse; - - // look for termcap keys - for (int i=0; Fkey[i].tname[0] != 0; i++) - { - char* k = Fkey[i].string; - len = (k) ? int(std::strlen(k)) : 0; - - if ( k && std::strncmp(k, buffer, uInt(len)) == 0 ) // found - { - n = len; - - for (; n < buf_size; n++) // Remove founded entry - buffer[n-len] = buffer[n]; - - for (; n-len < len; n++) // Fill rest with '\0' - buffer[n-len] = '\0'; - - input_data_pending = bool(buffer[0] != '\0'); - return Fkey[i].num; - } - } - - // look for meta keys - for (int i=0; Fmetakey[i].string[0] != 0; i++) - { - char* kmeta = Fmetakey[i].string; // The string is never null - len = int(std::strlen(kmeta)); - - if ( std::strncmp(kmeta, buffer, uInt(len)) == 0 ) // found - { - if ( len == 2 && ( buffer[1] == 'O' - || buffer[1] == '[' - || buffer[1] == ']') ) - { - if ( ! isKeyTimeout(time_keypressed, key_timeout) ) - return NEED_MORE_DATA; - } - n = len; - - for (; n < buf_size; n++) // Remove founded entry - buffer[n-len] = buffer[n]; - - for (; n-len < len; n++) // Fill rest with '\0' - buffer[n-len] = '\0'; - - input_data_pending = bool(buffer[0] != '\0'); - return Fmetakey[i].num; - } - } - - if ( ! isKeyTimeout(time_keypressed, key_timeout) ) - return NEED_MORE_DATA; - } - - // look for utf-8 character - - len = 1; - - if ( utf8_input && (firstchar & 0xc0) == 0xc0 ) - { - char utf8char[4] = {}; // init array with '\0' - - if ((firstchar & 0xe0) == 0xc0) - len = 2; - else if ((firstchar & 0xf0) == 0xe0) - len = 3; - else if ((firstchar & 0xf8) == 0xf0) - len = 4; - - for (n=0; n < len ; n++) - utf8char[n] = char(buffer[n] & 0xff); - - key = UTF8decode(utf8char); - } - else - key = uChar(buffer[0] & 0xff); - - n = len; - - for (; n < buf_size; n++) // remove the key from the buffer front - buffer[n-len] = buffer[n]; - - for (n=n-len; n < buf_size; n++) // fill the rest with '\0' bytes - buffer[n] = '\0'; - - input_data_pending = bool(buffer[0] != '\0'); - - if ( key == 0 ) // Ctrl+Space or Ctrl+@ - key = fc::Fckey_space; - - return int(key == 127 ? fc::Fkey_backspace : key); -} - -//---------------------------------------------------------------------- -bool& FTerm::unprocessedInput() -{ - return input_data_pending; -} - -//---------------------------------------------------------------------- -int FTerm::getLineNumber() -{ - if ( term->getHeight() == 0 ) - detectTermSize(); - - return term->getHeight(); -} - -//---------------------------------------------------------------------- -int FTerm::getColumnNumber() -{ - if ( term->getWidth() == 0 ) - detectTermSize(); - - return term->getWidth(); -} - -//---------------------------------------------------------------------- -FString FTerm::getKeyName (int keynum) -{ - for (int i=0; FkeyName[i].string[0] != 0; i++) - if ( FkeyName[i].num && FkeyName[i].num == keynum ) - return FString(FkeyName[i].string); - - if ( keynum > 32 && keynum < 127 ) - return FString(char(keynum)); - - return FString(""); -} - -//---------------------------------------------------------------------- -FTerm::modifier_key& FTerm::getModifierKey() -{ - char subcode = 6; - // fill bit field with 0 - std::memset (&mod_key, 0x00, sizeof(mod_key)); - - // TIOCLINUX, subcode=6 - if ( ioctl(0, TIOCLINUX, &subcode) >= 0 ) - { - if ( subcode & (1 << KG_SHIFT) ) - mod_key.shift = true; - - if ( subcode & (1 << KG_ALTGR) ) - mod_key.alt_gr = true; - - if ( subcode & (1 << KG_CTRL) ) - mod_key.ctrl = true; - - if ( subcode & (1 << KG_ALT) ) - mod_key.alt = true; - } - - return mod_key; -} - //---------------------------------------------------------------------- void FTerm::init_console() { @@ -808,35 +2024,6 @@ uInt FTerm::getBaudRate (const struct termios* termios_p) return ospeed[cfgetospeed(termios_p)]; } -//---------------------------------------------------------------------- -void FTerm::signal_handler (int signum) -{ - switch (signum) - { - case SIGWINCH: - if ( resize_term ) - break; - // initialize a resize event to the root element - resize_term = true; - break; - - case SIGTERM: - case SIGQUIT: - case SIGINT: - case SIGABRT: - case SIGILL: - case SIGSEGV: - init_term_object->finish(); - std::fflush (stderr); - std::fflush (stdout); - std::fprintf ( stderr - , "\nProgram stopped: signal %d (%s)\n" - , signum - , strsignal(signum) ); - std::terminate(); - } -} - //---------------------------------------------------------------------- char* FTerm::init_256colorTerminal() { @@ -2137,1218 +3324,31 @@ uInt FTerm::cp437_to_unicode (uChar c) return ucs; } - -// protected methods of FTerm //---------------------------------------------------------------------- -void FTerm::init_consoleCharMap() +void FTerm::signal_handler (int signum) { - if ( NewFont || VGAFont ) - return; - - if ( screen_unicode_map.entry_ct != 0 ) + switch (signum) { - for (int i=0; i <= lastCharItem; i++ ) - { - bool found = false; - - for (uInt n=0; n < screen_unicode_map.entry_ct; n++) - { - if ( character[i][fc::UTF8] == screen_unicode_map.entries[n].unicode ) - { - found = true; - break; - } - } - - if ( ! found ) - character[i][fc::PC] = character[i][fc::ASCII]; - } - } -} - -//---------------------------------------------------------------------- -bool FTerm::charEncodable (uInt c) -{ - uInt ch = charEncode(c); - return bool(ch > 0 && ch != c); -} - -//---------------------------------------------------------------------- -uInt FTerm::charEncode (uInt c) -{ - return charEncode (c, Encoding); -} - -//---------------------------------------------------------------------- -uInt FTerm::charEncode (uInt c, fc::encoding enc) -{ - for (uInt i=0; i <= uInt(lastCharItem); i++) - { - if ( character[i][0] == c ) - { - c = character[i][enc]; - break; - } - } - - return c; -} - -//---------------------------------------------------------------------- -char* FTerm::changeAttribute ( FOptiAttr::char_data*& term_attr - , FOptiAttr::char_data*& next_attr ) -{ - return opti_attr->changeAttribute (term_attr, next_attr); -} - -//---------------------------------------------------------------------- -void FTerm::xtermMouse (bool on) -{ - // activate/deactivate the xterm mouse support - if ( ! mouse_support ) - return; - - if ( on ) - putstring (CSI "?1001s" // save old highlight mouse tracking - CSI "?1000h" // enable x11 mouse tracking - CSI "?1002h" // enable cell motion mouse tracking - CSI "?1015h" // enable urxvt mouse mode - CSI "?1006h"); // enable SGR mouse mode - else - putstring (CSI "?1006l" // disable SGR mouse mode - CSI "?1015l" // disable urxvt mouse mode - CSI "?1002l" // disable cell motion mouse tracking - CSI "?1000l" // disable x11 mouse tracking - CSI "?1001r"); // restore old highlight mouse tracking - - std::fflush(stdout); -} - - -#ifdef F_HAVE_LIBGPM -//---------------------------------------------------------------------- -bool FTerm::gpmMouse (bool on) -{ - // activate/deactivate the gpm mouse support - if ( ! linux_terminal ) - return false; - - if ( openConsole() == 0 ) - { - if ( ! isConsole() ) - return false; - - closeConsole(); - } - - if ( on ) - { - Gpm_Connect conn; - conn.eventMask = uInt16(~GPM_MOVE); - conn.defaultMask = GPM_MOVE; - conn.maxMod = uInt16(~0); - conn.minMod = 0; - Gpm_Open(&conn, 0); - - switch ( gpm_fd ) - { - case -1: - return false; - - case -2: - Gpm_Close(); - return false; - - default: + case SIGWINCH: + if ( resize_term ) break; - } - } - else - { - Gpm_Close(); - } - - return on; -} -#endif // F_HAVE_LIBGPM - - -// public methods of FTerm -//---------------------------------------------------------------------- -bool FTerm::setVGAFont() -{ - if ( VGAFont ) - return VGAFont; - - if ( gnome_terminal - || kde_konsole - || putty_terminal - || tera_terminal - || cygwin_terminal - || mintty_terminal ) - return false; - - VGAFont = true; - - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - // Set font in xterm to vga - oscPrefix(); - putstring (OSC "50;vga" BEL); - oscPostfix(); - std::fflush(stdout); - NewFont = false; - pc_charset_console = true; - Encoding = fc::PC; - - if ( xterm_terminal && utf8_console ) - Fputchar = &FTerm::putchar_UTF8; - else - Fputchar = &FTerm::putchar_ASCII; - } - else if ( linux_terminal ) - { - if ( openConsole() == 0 ) - { - if ( isConsole() ) - { - // standard vga font 8x16 - int ret = setScreenFont(__8x16std, 256, 8, 16); - - if ( ret != 0 ) - VGAFont = false; - - // unicode character mapping - struct unimapdesc unimap; - unimap.entry_ct = uChar ( sizeof(unicode_cp437_pairs) - / sizeof(unipair) ); - unimap.entries = &unicode_cp437_pairs[0]; - setUnicodeMap(&unimap); - } - else - VGAFont = false; - - detectTermSize(); - closeConsole(); - } - else - VGAFont = false; - - pc_charset_console = true; - Encoding = fc::PC; - Fputchar = &FTerm::putchar_ASCII; - } - else - VGAFont = false; - - return VGAFont; -} - -//---------------------------------------------------------------------- -bool FTerm::setNewFont() -{ - if ( NewFont ) - return true; - - if ( gnome_terminal - || kde_konsole - || putty_terminal - || tera_terminal - || cygwin_terminal - || mintty_terminal ) - return false; - - if ( xterm_terminal || screen_terminal - || urxvt_terminal || FTermcap::osc_support ) - { - NewFont = true; - // Set font in xterm to 8x16graph - oscPrefix(); - putstring (OSC "50;8x16graph" BEL); - oscPostfix(); - std::fflush(stdout); - pc_charset_console = true; - Encoding = fc::PC; - - if ( xterm_terminal && utf8_console ) - Fputchar = &FTerm::putchar_UTF8; - else - Fputchar = &FTerm::putchar_ASCII; - } - else if ( linux_terminal ) - { - NewFont = true; - - if ( openConsole() == 0 ) - { - if ( isConsole() ) - { - struct unimapdesc unimap; - int ret; - - // Set the graphical font 8x16 - ret = setScreenFont(__8x16graph, 256, 8, 16); - - if ( ret != 0 ) - NewFont = false; - - // unicode character mapping - unimap.entry_ct = uInt16 ( sizeof(unicode_cp437_pairs) - / sizeof(unipair) ); - unimap.entries = &unicode_cp437_pairs[0]; - setUnicodeMap(&unimap); - } - - detectTermSize(); - closeConsole(); - } - - pc_charset_console = true; - Encoding = fc::PC; - Fputchar = &FTerm::putchar_ASCII; // function pointer - } - else - NewFont = false; - - return NewFont; -} - -//---------------------------------------------------------------------- -bool FTerm::setOldFont() -{ - bool retval; - - if ( ! (NewFont || VGAFont) ) - return false; - - retval = \ - NewFont = \ - VGAFont = false; - - if ( xterm_terminal || screen_terminal - || urxvt_terminal || FTermcap::osc_support ) - { - if ( xterm_font && xterm_font->getLength() > 2 ) - { - // restore saved xterm font - oscPrefix(); - putstringf (OSC "50;%s" BEL, xterm_font->c_str() ); - oscPostfix(); - } - else - { - // Set font in xterm to vga - oscPrefix(); - putstring (OSC "50;vga" BEL); - oscPostfix(); - } - - std::fflush(stdout); - retval = true; - } - else if ( linux_terminal ) - { - if ( openConsole() == 0 ) - { - if ( isConsole() ) - { - if ( screen_font.data ) - { - int ret = setScreenFont ( screen_font.data - , screen_font.charcount - , screen_font.width - , screen_font.height - , true ); - delete[] screen_font.data; - - if ( ret == 0 ) - retval = true; - } - - if ( screen_unicode_map.entries ) - { - setUnicodeMap (&screen_unicode_map); - delete[] screen_unicode_map.entries; - } - - } - - detectTermSize(); - closeConsole(); - } - } - - return retval; -} - -//---------------------------------------------------------------------- -fc::consoleCursorStyle FTerm::getConsoleCursor() -{ - return console_cursor_style; -} - -//---------------------------------------------------------------------- -void FTerm::setConsoleCursor (fc::consoleCursorStyle style, bool hidden) -{ - // Set cursor style in linux console - if ( ! linux_terminal ) - return; - - console_cursor_style = style; - - if ( hidden ) - return; - - putstringf (CSI "?%dc", style); - std::fflush(stdout); -} - -//---------------------------------------------------------------------- -char* FTerm::moveCursor (int xold, int yold, int xnew, int ynew) -{ - // returns the cursor move string - if ( cursor_optimisation ) - return opti_move->moveCursor (xold, yold, xnew, ynew); - else - return tgoto(tcap[fc::t_cursor_address].string, xnew, ynew); -} - -//---------------------------------------------------------------------- -char* FTerm::enableCursor() -{ - char*& vs = tcap[fc::t_cursor_visible].string; - char*& ve = tcap[fc::t_cursor_normal].string; - - if ( ve ) - return ve; - else if ( vs ) - return vs; - - return 0; -} - -//---------------------------------------------------------------------- -char* FTerm::disableCursor() -{ - char*& vi = tcap[fc::t_cursor_invisible].string; - - if ( vi ) - return vi; - - return 0; -} - -//---------------------------------------------------------------------- -void FTerm::detectTermSize() -{ - struct winsize win_size; - bool close_after_detect = false; - int ret; - - if ( fd_tty < 0 ) // console is already closed - { - if ( openConsole() != 0 ) - return; - - close_after_detect = true; - } - - ret = ioctl (fd_tty, TIOCGWINSZ, &win_size); - - if ( ret != 0 || win_size.ws_col == 0 || win_size.ws_row == 0 ) - { - char* str; - term->setPos(1,1); - str = std::getenv("COLUMNS"); - term->setWidth(str ? std::atoi(str) : 80); - str = std::getenv("LINES"); - term->setHeight(str ? std::atoi(str) : 25); - } - else - { - term->setRect(1, 1, win_size.ws_col, win_size.ws_row); - } - - opti_move->setTermSize (term->getWidth(), term->getHeight()); - - if ( close_after_detect ) - closeConsole(); -} - -//---------------------------------------------------------------------- -void FTerm::setTermSize (int term_width, int term_height) -{ - // Set xterm size to {term_width} x {term_height} - if ( xterm_terminal ) - { - putstringf (CSI "8;%d;%dt", term_height, term_width); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setKDECursor (fc::kdeKonsoleCursorShape style) -{ - // Set cursor style in KDE konsole - if ( kde_konsole ) - { - oscPrefix(); - putstringf (OSC "50;CursorShape=%d" BEL, style); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -const FString FTerm::getXTermFont() -{ - FString font(""); - - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - if ( raw_mode && non_blocking_stdin ) - { - int n; - char temp[150] = {}; - oscPrefix(); - putstring (OSC "50;?" BEL); // get font - oscPostfix(); - std::fflush(stdout); - usleep(150000); // wait 150 ms - - // read the terminal answer - n = int(read(fileno(stdin), &temp, sizeof(temp)-1)); - - // BEL + '\0' = string terminator - if ( n >= 6 && temp[n-1] == BEL[0] && temp[n] == '\0' ) - { - temp[n-1] = '\0'; - font = static_cast(temp + 5); - } - } - } - - return font; -} - -//---------------------------------------------------------------------- -const FString FTerm::getXTermTitle() -{ - FString title(""); - - if ( kde_konsole ) - return title; - - if ( raw_mode && non_blocking_stdin ) - { - int n; - char temp[512] = {}; - putstring (CSI "21t"); // get title - std::fflush(stdout); - usleep(150000); // wait 150 ms - - // read the terminal answer - n = int(read(fileno(stdin), &temp, sizeof(temp)-1)); - - // Esc + \ = OSC string terminator - if ( n >= 5 && temp[n-1] == '\\' && temp[n-2] == ESC[0] ) - { - temp[n-2] = '\0'; - title = static_cast(temp + 3); - } - } - - return title; -} - -//---------------------------------------------------------------------- -void FTerm::setXTermCursorStyle (fc::xtermCursorStyle style) -{ - // Set the xterm cursor style - if ( (xterm_terminal || mintty_terminal) && ! (gnome_terminal || kde_konsole) ) - { - putstringf (CSI "%d q", style); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermTitle (const FString& title) -{ - // Set the xterm title - if ( xterm_terminal || screen_terminal - || mintty_terminal || putty_terminal - || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "0;%s" BEL, title.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermForeground (const FString& fg) -{ - // Set the VT100 text foreground color - if ( xterm_terminal || screen_terminal - || mintty_terminal || mlterm_terminal - || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "10;%s" BEL, fg.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermBackground (const FString& bg) -{ - // Set the VT100 text background color - if ( xterm_terminal || screen_terminal - || mintty_terminal || mlterm_terminal - || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "11;%s" BEL, bg.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermCursorColor (const FString& cc) -{ - // Set the text cursor color - if ( xterm_terminal || screen_terminal - || mintty_terminal || urxvt_terminal - || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "12;%s" BEL, cc.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermMouseForeground (const FString& mfg) -{ - // Set the mouse foreground color - if ( xterm_terminal || screen_terminal - || urxvt_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "13;%s" BEL, mfg.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermMouseBackground (const FString& mbg) -{ - // Set the mouse background color - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "14;%s" BEL, mbg.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setXTermHighlightBackground (const FString& hbg) -{ - // Set the highlight background color - if ( xterm_terminal || screen_terminal - || urxvt_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "17;%s" BEL, hbg.c_str()); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermColors() -{ - // Reset the entire color table - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "104" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermForeground() -{ - // Reset the VT100 text foreground color - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstring (OSC "110" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermBackground() -{ - // Reset the VT100 text background color - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstring (OSC "111" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermCursorColor() -{ - // Reset the text cursor color - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstring (OSC "112" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermMouseForeground() -{ - // Reset the mouse foreground color - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstring (OSC "113" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermMouseBackground() -{ - // Reset the mouse background color - if ( xterm_terminal || screen_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstring (OSC "114" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::resetXTermHighlightBackground() -{ - // Reset the highlight background color - if ( xterm_terminal || screen_terminal - || urxvt_terminal || FTermcap::osc_support ) - { - oscPrefix(); - putstringf (OSC "117" BEL); - oscPostfix(); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::saveColorMap() -{ - // ioctl (0, GIO_CMAP, &color_map); -} - -//---------------------------------------------------------------------- -void FTerm::resetColorMap() -{ - char*& op = tcap[fc::t_orig_pair].string; - char*& oc = tcap[fc::t_orig_colors].string; - - if ( op ) - putstring (op); - else if ( oc ) - putstring (oc); -/*else - { - dacreg CurrentColors[16] = - { - {0x00, 0x00, 0x00}, {0xAA, 0x00, 0x00}, - {0x00, 0xAA, 0x00}, {0xAA, 0x55, 0x00}, - {0x00, 0x00, 0xAA}, {0xAA, 0x00, 0xAA}, - {0x00, 0xAA, 0xAA}, {0xAA, 0xAA, 0xAA}, - {0x55, 0x55, 0x55}, {0xFF, 0x55, 0x55}, - {0x55, 0xFF, 0x55}, {0xFF, 0xFF, 0x55}, - {0x55, 0x55, 0xFF}, {0xFF, 0x55, 0xFF}, - {0x55, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF} - }; - for (int x=0; x<16; x++) - { - color_map.d[x].red = CurrentColors[x].red; - color_map.d[x].green = CurrentColors[x].green; - color_map.d[x].blue = CurrentColors[x].blue; - } - ioctl (0, PIO_CMAP, &color_map); - }*/ - - std::fflush(stdout); -} - -//---------------------------------------------------------------------- -void FTerm::setPalette (short index, int r, int g, int b) -{ - char*& Ic = tcap[fc::t_initialize_color].string; - char*& Ip = tcap[fc::t_initialize_pair].string; - - index = FOptiAttr::vga2ansi(index); - - if ( Ic || Ip ) - { - int rr, gg, bb; - const char* color_str = ""; - - rr = (r * 1001) / 256; - gg = (g * 1001) / 256; - bb = (b * 1001) / 256; - - if ( Ic ) - color_str = tparm(Ic, index, rr, gg, bb, 0, 0, 0, 0, 0); - else if ( Ip ) - color_str = tparm(Ip, index, 0, 0, 0, rr, gg, bb, 0, 0); - - putstring (color_str); - } - else if ( linux_terminal ) - { -/* // direct vga-register set - if ( r>=0 && r<256 - && g>=0 && g<256 - && b>=0 && b<256 ) - { - map.d[index].red = r; - map.d[index].green = g; - map.d[index].blue = b; - } - ioctl (0, PIO_CMAP, &map); */ - } - - std::fflush(stdout); -} - -//---------------------------------------------------------------------- -void FTerm::setBeep (int Hz, int ms) -{ - if ( ! linux_terminal ) - return; - - // range for frequency: 21-32766 - if ( Hz < 21 || Hz > 32766 ) - return; - - // range for duration: 0-1999 - if ( ms < 0 || ms > 1999 ) - return; - - putstringf ( CSI "10;%d]" - CSI "11;%d]" - , Hz, ms ); - std::fflush(stdout); -} - -//---------------------------------------------------------------------- -void FTerm::resetBeep() -{ - if ( ! linux_terminal ) - return; - - // default frequency: 750 Hz - // default duration: 125 ms - putstring ( CSI "10;750]" - CSI "11;125]" ); - std::fflush(stdout); -} - -//---------------------------------------------------------------------- -void FTerm::beep() -{ - if ( tcap[fc::t_bell].string ) - { - putstring (tcap[fc::t_bell].string); - std::fflush(stdout); - } -} - -//---------------------------------------------------------------------- -void FTerm::setEncoding (std::string enc) -{ - std::map::const_iterator it; - - // available encodings: "UTF8", "VT100", "PC" and "ASCII" - it = encoding_set->find(enc); - - if ( it == encoding_set->end() ) // not found - return; - - Encoding = it->second; - - assert ( Encoding == fc::UTF8 - || Encoding == fc::VT100 - || Encoding == fc::PC - || Encoding == fc::ASCII ); - - // set the new Fputchar function pointer - switch ( int(Encoding) ) - { - case fc::UTF8: - Fputchar = &FTerm::putchar_UTF8; + // initialize a resize event to the root element + resize_term = true; break; - case fc::VT100: - case fc::PC: - if ( xterm_terminal && utf8_console ) - Fputchar = &FTerm::putchar_UTF8; - // fall through - case fc::ASCII: - default: - Fputchar = &FTerm::putchar_ASCII; + case SIGTERM: + case SIGQUIT: + case SIGINT: + case SIGABRT: + case SIGILL: + case SIGSEGV: + init_term_object->finish(); + std::fflush (stderr); + std::fflush (stdout); + std::fprintf ( stderr + , "\nProgram stopped: signal %d (%s)\n" + , signum + , strsignal(signum) ); + std::terminate(); } } - -//---------------------------------------------------------------------- -std::string FTerm::getEncoding() -{ - std::map::const_iterator it, end; - end = encoding_set->end(); - - for (it = encoding_set->begin(); it != end; ++it ) - if ( it->second == Encoding ) - return it->first; - - return ""; -} - -//---------------------------------------------------------------------- -bool FTerm::setNonBlockingInput (bool on) -{ - if ( on == non_blocking_stdin ) - return non_blocking_stdin; - - if ( on ) // make stdin non-blocking - { - stdin_status_flags |= O_NONBLOCK; - - if ( fcntl (stdin_no, F_SETFL, stdin_status_flags) != -1 ) - non_blocking_stdin = true; - } - else - { - stdin_status_flags &= ~O_NONBLOCK; - - if ( fcntl (stdin_no, F_SETFL, stdin_status_flags) != -1 ) - non_blocking_stdin = false; - } - - return non_blocking_stdin; -} - -//---------------------------------------------------------------------- -bool FTerm::scrollTermForward() -{ - if ( tcap[fc::t_scroll_forward].string ) - { - putstring (tcap[fc::t_scroll_forward].string); - std::fflush(stdout); - return true; - } - - return false; -} - -//---------------------------------------------------------------------- -bool FTerm::scrollTermReverse() -{ - if ( tcap[fc::t_scroll_reverse].string ) - { - putstring (tcap[fc::t_scroll_reverse].string); - std::fflush(stdout); - return true; - } - - return false; -} - -//---------------------------------------------------------------------- -bool FTerm::setUTF8 (bool on) // UTF-8 (Unicode) -{ - if ( on == utf8_state ) - return utf8_state; - - if ( on ) - utf8_state = true; - else - utf8_state = false; - - if ( linux_terminal ) - { - if ( on ) - putstring (ESC "%G"); - else - putstring (ESC "%@"); - } - - std::fflush(stdout); - return utf8_state; -} - -//---------------------------------------------------------------------- -bool FTerm::setRawMode (bool on) -{ - if ( on == raw_mode ) - return raw_mode; - - std::fflush(stdout); - - if ( on ) - { - // Info under: man 3 termios - struct termios t; - tcgetattr (stdin_no, &t); - - /* set + unset flags for raw mode */ - // input mode - t.c_iflag &= uInt(~(IGNBRK | BRKINT | PARMRK | ISTRIP - | INLCR | IGNCR | ICRNL | IXON)); - // output mode - t.c_oflag &= uInt(~OPOST); - - // local mode -#if DEBUG - // Exit with ctrl-c only if compiled with "DEBUG" option - t.c_lflag &= uInt(~(ECHO | ECHONL | ICANON | IEXTEN)); -#else - // Plus disable signals. - t.c_lflag &= uInt(~(ECHO | ECHONL | ICANON | IEXTEN | ISIG)); -#endif - - // control mode - t.c_cflag &= uInt(~(CSIZE | PARENB)); - t.c_cflag |= uInt(CS8); - - // defines the terminal special characters for noncanonical read - t.c_cc[VTIME] = 0; // Timeout in deciseconds - t.c_cc[VMIN] = 1; // Minimum number of characters - - // set the new termios settings - tcsetattr (stdin_no, TCSAFLUSH, &t); - raw_mode = true; - } - else - { - // restore termios settings - tcsetattr (stdin_no, TCSAFLUSH, &term_init); - raw_mode = false; - } - - return raw_mode; -} - -//---------------------------------------------------------------------- -const FString FTerm::getAnswerbackMsg() -{ - FString answerback = ""; - - if ( raw_mode ) - { - ssize_t n; - fd_set ifds; - struct timeval tv; - char temp[10] = {}; - - FD_ZERO(&ifds); - FD_SET(stdin_no, &ifds); - tv.tv_sec = 0; - tv.tv_usec = 150000; // 150 ms - - std::putchar (ENQ[0]); // send enquiry character - std::fflush(stdout); - - // read the answerback message - if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0) - { - n = read(fileno(stdin), &temp, sizeof(temp)-1); - - if ( n > 0 ) - { - temp[n] = '\0'; - answerback = temp; - } - } - } - - return answerback; -} - -//---------------------------------------------------------------------- -const FString FTerm::getSecDA() -{ - FString sec_da_str = ""; - - if ( raw_mode ) - { - ssize_t n; - fd_set ifds; - struct timeval tv; - char temp[16] = {}; - - FD_ZERO(&ifds); - FD_SET(stdin_no, &ifds); - tv.tv_sec = 0; - tv.tv_usec = 550000; // 150 ms - - // get the secondary device attributes - std::putchar (SECDA[0]); - std::putchar (SECDA[1]); - std::putchar (SECDA[2]); - std::putchar (SECDA[3]); - - std::fflush(stdout); - usleep(150000); // min. wait time 150 ms (need for mintty) - - // read the answer - if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0 ) - { - n = read(fileno(stdin), &temp, sizeof(temp)-1); - - if ( n > 0 ) - { - temp[n] = '\0'; - sec_da_str = temp; - } - } - } - - return sec_da_str; -} - -//---------------------------------------------------------------------- -void FTerm::putstringf (const char* format, ...) -{ - assert ( format != 0 ); - char buf[512]; - char* buffer; - va_list args; - - buffer = buf; - va_start (args, format); - std::vsnprintf (buffer, sizeof(buf), format, args); - va_end (args); - - tputs (buffer, 1, std::putchar); -} -//---------------------------------------------------------------------- -inline void FTerm::putstring (const char* s, int affcnt) -{ - tputs (s, affcnt, std::putchar); -} - -//---------------------------------------------------------------------- -int FTerm::putchar_ASCII (register int c) -{ - if ( std::putchar(char(c)) == EOF ) - return 0; - else - return 1; -} - -//---------------------------------------------------------------------- -int FTerm::putchar_UTF8 (register int c) -{ - if (c < 0x80) - { - // 1 Byte (7-bit): 0xxxxxxx - std::putchar (c); - return 1; - } - else if (c < 0x800) - { - // 2 byte (11-bit): 110xxxxx 10xxxxxx - std::putchar (0xc0 | (c >> 6) ); - std::putchar (0x80 | (c & 0x3f) ); - return 2; - } - else if (c < 0x10000) - { - // 3 byte (16-bit): 1110xxxx 10xxxxxx 10xxxxxx - std::putchar (0xe0 | (c >> 12) ); - std::putchar (0x80 | ((c >> 6) & 0x3f) ); - std::putchar (0x80 | (c & 0x3f) ); - return 3; - } - else if (c < 0x200000) - { - // 4 byte (21-bit): 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - std::putchar (0xf0 | (c >> 18) ); - std::putchar (0x80 | ((c >> 12) & 0x3f) ); - std::putchar (0x80 | ((c >> 6) & 0x3f) ); - std::putchar (0x80 | (c & 0x3f)); - return 4; - } - else - return EOF; -} - -//---------------------------------------------------------------------- -int FTerm::UTF8decode(char* utf8) -{ - register int ucs=0; - - for (register int i=0; i < int(std::strlen(utf8)); ++i) - { - register uChar ch = uChar(utf8[i]); - - if ((ch & 0xc0) == 0x80) - { - // byte 2..4 = 10xxxxxx - ucs = (ucs << 6) | (ch & 0x3f); - } - else if (ch < 128) - { - // byte 1 = 0xxxxxxx (1 byte mapping) - ucs = ch & 0xff; - } - else if ((ch & 0xe0) == 0xc0) - { - // byte 1 = 110xxxxx (2 byte mapping) - ucs = ch & 0x1f; - } - else if ((ch & 0xf0) == 0xe0) - { - // byte 1 = 1110xxxx (3 byte mapping) - ucs = ch & 0x0f; - } - else if ((ch & 0xf8) == 0xf0) - { - // byte 1 = 11110xxx (4 byte mapping) - ucs = ch & 0x07; - } - else - { - // error - ucs = EOF; - } - } - - return ucs; -} diff --git a/src/fterm.h b/src/fterm.h index 092b9c87..7f571015 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -75,9 +75,6 @@ #define OSC ESC "]" // Operating system command (7-bit) #define SECDA ESC "[>c" // Secondary Device Attributes -// parseKeyString return value -#define NEED_MORE_DATA -1 - //---------------------------------------------------------------------- // class FTerm @@ -88,7 +85,221 @@ class FTerm { + public: + static struct modifier_key // bit field + { + uChar shift : 1; // 0..1 + uChar alt_gr : 1; // 0..1 + uChar ctrl : 1; // 0..1 + uChar alt : 1; // 0..1 + uChar : 4; // padding bits + } mod_key; + + // Constructor + FTerm (); + + // Destructor + virtual ~FTerm(); + + // Accessors + virtual const char* getClassName() const; + static int getLineNumber(); + static int getColumnNumber(); + static FString getKeyName (int); + static modifier_key& getModifierKey(); + static char* getTermType(); + static char* getTermName(); + static uInt getTabstop(); + static int getMaxColor(); + static fc::consoleCursorStyle getConsoleCursor(); + + // Inquiries + static bool isKeyTimeout (timeval*, register long); + static bool isRaw(); + static bool hasPCcharset(); + static bool hasUTF8(); + static bool hasVT100(); + static bool hasASCII(); + static bool isMonochron(); + static bool isXTerminal(); + static bool isRxvtTerminal(); + static bool isUrxvtTerminal(); + static bool isMltermTerminal(); + static bool isPuttyTerminal(); + static bool isKdeTerminal(); + static bool isGnomeTerminal(); + static bool isKtermTerminal(); + static bool isTeraTerm(); + static bool isCygwinTerminal(); + static bool isMinttyTerm(); + static bool isLinuxTerm(); + static bool isScreenTerm(); + static bool isTmuxTerm(); + static bool isInputDataPending(); + static bool isNewFont(); + static bool isUTF8(); + static bool isUTF8_linux_terminal(); + + // Mutators + static bool setCursorOptimisation (bool); + static void setConsoleCursor (fc::consoleCursorStyle, bool); + static bool setRawMode (bool); + static bool setRawMode(); + static bool unsetRawMode(); + static bool setCookedMode(); + static bool setUTF8 (bool); + static bool setUTF8(); + static bool unsetUTF8(); + static bool setNonBlockingInput (bool); + static bool setNonBlockingInput(); + static bool unsetNonBlockingInput(); + + // Methods + static int parseKeyString (char*, int, timeval*); + static bool& unprocessedInput(); + static bool setVGAFont(); + static bool setNewFont(); + static bool setOldFont(); + static char* moveCursor (int, int, int, int); + static char* enableCursor(); + static char* disableCursor(); + static void detectTermSize(); + static void setTermSize (int, int); + static void setKDECursor (fc::kdeKonsoleCursorShape); + static const FString getXTermFont(); + static const FString getXTermTitle(); + static void setXTermCursorStyle (fc::xtermCursorStyle); + static void setXTermTitle (const FString&); + static void setXTermForeground (const FString&); + static void setXTermBackground (const FString&); + static void setXTermCursorColor (const FString&); + static void setXTermMouseForeground (const FString&); + static void setXTermMouseBackground (const FString&); + static void setXTermHighlightBackground (const FString&); + static void resetXTermColors(); + static void resetXTermForeground(); + static void resetXTermBackground(); + static void resetXTermCursorColor(); + static void resetXTermMouseForeground(); + static void resetXTermMouseBackground(); + static void resetXTermHighlightBackground(); + static void saveColorMap(); + static void resetColorMap(); + static void setPalette (short, int, int, int); + static void setBeep (int, int); + static void resetBeep(); + static void beep(); + + static void setEncoding (std::string); + static std::string getEncoding(); + + static bool scrollTermForward(); + static bool scrollTermReverse(); + + static const FString getAnswerbackMsg(); + static const FString getSecDA(); + + // function pointer -> static function + static int (*Fputchar)(int); + static void putstringf (const char*, ...) + #if defined(__clang__) + __attribute__((__format__ (__printf__, 1, 2))) + #elif defined(__GNUC__) + __attribute__ ((format (printf, 1, 2))) + #endif + ; + static void putstring (const char*, int = 1); + static int putchar_ASCII (register int); + static int putchar_UTF8 (register int); + static int UTF8decode (char*); + + protected: + // Typedefs + typedef FOptiAttr::char_data char_data; + + // Methods + static void init_consoleCharMap(); + static bool charEncodable (uInt); + static uInt charEncode (uInt); + static uInt charEncode (uInt, fc::encoding); + static char* changeAttribute ( char_data*& + , char_data*& ); + static bool hasChangedTermSize(); + static void changeTermSizeFinished(); + static void xtermMouse (bool); + static void enableXTermMouse(); + static void disableXTermMouse(); + +#ifdef F_HAVE_LIBGPM + static bool gpmMouse (bool); + static bool enableGpmMouse(); + static bool disableGpmMouse(); + static bool isGpmMouseEnabled(); +#endif // F_HAVE_LIBGPM + static FPoint& getMousePos(); + static void setMousePos (FPoint&); + static void setMousePos (short, short); + + // Data Members + static int stdin_no; + static int stdout_no; + static bool NewFont; + static bool VGAFont; + static bool cursor_optimisation; + static fc::encoding Encoding; + static char exit_message[8192]; + private: + // Typedefs + typedef FTermcap::tcap_map termcap_map; + typedef struct + { + uChar red; + uChar green; + uChar blue; + } dacreg; + + // Constants + static const int NEED_MORE_DATA = -1; // parseKeyString return value + + // Disable copy constructor + FTerm (const FTerm&); + // Disable assignment operator (=) + FTerm& operator = (const FTerm&); + + // Methods + static uInt16 getInputStatusRegisterOne(); + static uChar readAttributeController (uChar); + static void writeAttributeController (uChar, uChar); + static uChar getAttributeMode(); + static void setAttributeMode (uChar); + static int setBlinkAsIntensity (bool); + static int getFramebuffer_bpp(); + static int openConsole(); + static int closeConsole(); + static int isConsole(); + static void identifyTermType(); + static int getScreenFont(); + static int setScreenFont (uChar*, uInt, uInt, uInt, bool = false); + static int setUnicodeMap (struct unimapdesc*); + static int getUnicodeMap (); + static void init_console(); + static uInt getBaudRate (const struct termios*); + static char* init_256colorTerminal(); + static char* parseAnswerbackMsg (char*&); + static char* parseSecDA (char*&); + static void oscPrefix(); + static void oscPostfix(); + static void init_alt_charset(); + static void init_pc_charset(); + static void init_termcaps(); + static void init_encoding(); + void init(); + void finish(); + static uInt cp437_to_unicode (uChar); + static void signal_handler (int); + + // Data Members static std::map * vt100_alt_char; static std::map * encoding_set; static FTermcap::tcap_map* tcap; @@ -147,260 +358,15 @@ class FTerm static const FString* answer_back; static const FString* sec_da; - typedef struct - { - uChar red; - uChar green; - uChar blue; - } dacreg; - struct { dacreg d[16]; } color_map; - - protected: - static int stdin_no; - static int stdout_no; - static bool NewFont; - static bool VGAFont; - static bool cursor_optimisation; - static fc::encoding Encoding; - static char exit_message[8192]; - - static struct modifier_key // bit field - { - uChar shift : 1; // 0..1 - uChar alt_gr : 1; // 0..1 - uChar ctrl : 1; // 0..1 - uChar alt : 1; // 0..1 - uChar : 4; // padding bits - } mod_key; - - private: - // Disable copy constructor - FTerm (const FTerm&); - // Disable assignment operator (=) - FTerm& operator = (const FTerm&); - - static uInt16 getInputStatusRegisterOne(); - static uChar readAttributeController (uChar); - static void writeAttributeController (uChar, uChar); - static uChar getAttributeMode(); - static void setAttributeMode (uChar); - static int setBlinkAsIntensity (bool); - static int getFramebuffer_bpp(); - static int openConsole(); - static int closeConsole(); - static int isConsole(); - static void identifyTermType(); - static int getScreenFont(); - static int setScreenFont (uChar*, uInt, uInt, uInt, bool = false); - static int setUnicodeMap (struct unimapdesc*); - static int getUnicodeMap (); - static void init_console(); - static uInt getBaudRate (const struct termios*); - static char* init_256colorTerminal(); - static char* parseAnswerbackMsg (char*&); - static char* parseSecDA (char*&); - static void oscPrefix(); - static void oscPostfix(); - static void init_alt_charset(); - static void init_pc_charset(); - static void init_termcaps(); - static void init_encoding(); - void init(); - void finish(); - static uInt cp437_to_unicode (uChar); - static void signal_handler (int); - - protected: - static void init_consoleCharMap(); - static bool charEncodable (uInt); - static uInt charEncode (uInt); - static uInt charEncode (uInt, fc::encoding); - static char* changeAttribute ( FOptiAttr::char_data*& - , FOptiAttr::char_data*& ); - static bool hasChangedTermSize(); - static void changeTermSizeFinished(); - static void xtermMouse (bool); - static void enableXTermMouse(); - static void disableXTermMouse(); - -#ifdef F_HAVE_LIBGPM - static bool gpmMouse (bool); - static bool enableGpmMouse(); - static bool disableGpmMouse(); - static bool isGpmMouseEnabled(); -#endif // F_HAVE_LIBGPM - static FPoint& getMousePos(); - static void setMousePos (FPoint&); - static void setMousePos (short, short); - - public: - // Constructor - FTerm (); - // Destructor - virtual ~FTerm(); - - virtual const char* getClassName() const; - static bool isKeyTimeout (timeval*, register long); - static int parseKeyString (char*, int, timeval*); - static bool& unprocessedInput(); - static int getLineNumber(); - static int getColumnNumber(); - static FString getKeyName (int); - static modifier_key& getModifierKey(); - static char* getTermType(); - static char* getTermName(); - static uInt getTabstop(); - static bool hasPCcharset(); - static bool hasUTF8(); - static bool hasVT100(); - static bool hasASCII(); - static bool isMonochron(); - static bool isXTerminal(); - static bool isRxvtTerminal(); - static bool isUrxvtTerminal(); - static bool isMltermTerminal(); - static bool isPuttyTerminal(); - static bool isKdeTerminal(); - static bool isGnomeTerminal(); - static bool isKtermTerminal(); - static bool isTeraTerm(); - static bool isCygwinTerminal(); - static bool isMinttyTerm(); - static bool isLinuxTerm(); - static bool isScreenTerm(); - static bool isTmuxTerm(); - static bool isInputDataPending(); - static bool setVGAFont(); - static bool setNewFont(); - static bool isNewFont(); - static bool setOldFont(); - static bool setCursorOptimisation (bool); - static fc::consoleCursorStyle getConsoleCursor(); - static void setConsoleCursor (fc::consoleCursorStyle, bool); - static char* moveCursor (int, int, int, int); - static char* enableCursor(); - static char* disableCursor(); - static void detectTermSize(); - static void setTermSize (int, int); - static void setKDECursor (fc::kdeKonsoleCursorShape); - static const FString getXTermFont(); - static const FString getXTermTitle(); - static void setXTermCursorStyle (fc::xtermCursorStyle); - static void setXTermTitle (const FString&); - static void setXTermForeground (const FString&); - static void setXTermBackground (const FString&); - static void setXTermCursorColor (const FString&); - static void setXTermMouseForeground (const FString&); - static void setXTermMouseBackground (const FString&); - static void setXTermHighlightBackground (const FString&); - static void resetXTermColors(); - static void resetXTermForeground(); - static void resetXTermBackground(); - static void resetXTermCursorColor(); - static void resetXTermMouseForeground(); - static void resetXTermMouseBackground(); - static void resetXTermHighlightBackground(); - static void saveColorMap(); - static void resetColorMap(); - static void setPalette (short, int, int, int); - static int getMaxColor(); - static void setBeep (int, int); - static void resetBeep(); - static void beep(); - - static void setEncoding (std::string); - static std::string getEncoding(); - - static bool setNonBlockingInput (bool); - static bool setNonBlockingInput(); - static bool unsetNonBlockingInput(); - - static bool scrollTermForward(); - static bool scrollTermReverse(); - - static bool setUTF8 (bool); - static bool setUTF8(); - static bool unsetUTF8(); - static bool isUTF8(); - static bool isUTF8_linux_terminal(); - - static bool setRawMode (bool); - static bool setRawMode(); - static bool unsetRawMode(); - static bool setCookedMode(); - static bool isRaw(); - - static const FString getAnswerbackMsg(); - static const FString getSecDA(); - - // function pointer -> static function - static int (*Fputchar)(int); - static void putstringf (const char*, ...) - #if defined(__clang__) - __attribute__((__format__ (__printf__, 1, 2))) - #elif defined(__GNUC__) - __attribute__ ((format (printf, 1, 2))) - #endif - ; - static void putstring (const char*, int = 1); - static int putchar_ASCII (register int); - static int putchar_UTF8 (register int); - static int UTF8decode (char*); }; #pragma pack(pop) // FTerm inline functions -//---------------------------------------------------------------------- -inline bool FTerm::hasChangedTermSize() -{ return resize_term; } - -//---------------------------------------------------------------------- -inline void FTerm::changeTermSizeFinished() -{ resize_term = false; } - -//---------------------------------------------------------------------- -inline void FTerm::enableXTermMouse() -{ xtermMouse(true); } - -//---------------------------------------------------------------------- -inline void FTerm::disableXTermMouse() -{ xtermMouse(false); } - -#ifdef F_HAVE_LIBGPM -//---------------------------------------------------------------------- -inline bool FTerm::enableGpmMouse() -{ return gpmMouse(true); } - -//---------------------------------------------------------------------- -inline bool FTerm::disableGpmMouse() -{ return gpmMouse(false); } - -//---------------------------------------------------------------------- -inline bool FTerm::isGpmMouseEnabled() -{ return gpm_mouse_enabled; } -#endif // F_HAVE_LIBGPM - -//---------------------------------------------------------------------- -inline FPoint& FTerm::getMousePos() -{ return *mouse; } - -//---------------------------------------------------------------------- -inline void FTerm::setMousePos (FPoint& m) -{ *mouse = m; } - -//---------------------------------------------------------------------- -inline void FTerm::setMousePos (short x, short y) -{ mouse->setPoint (x, y); } - -//---------------------------------------------------------------------- -inline bool FTerm::setNonBlockingInput() -{ return setNonBlockingInput(true); } - //---------------------------------------------------------------------- inline const char* FTerm::getClassName() const { return "FTerm"; } @@ -417,6 +383,14 @@ inline char* FTerm::getTermName() inline uInt FTerm::getTabstop() { return FTermcap::tabstop; } +//---------------------------------------------------------------------- +inline int FTerm::getMaxColor() +{ return FTermcap::max_color; } + +//---------------------------------------------------------------------- +inline bool FTerm::isRaw() +{ return raw_mode; } + //---------------------------------------------------------------------- inline bool FTerm::hasPCcharset() { return pc_charset_console; } @@ -433,10 +407,6 @@ inline bool FTerm::hasVT100() inline bool FTerm::hasASCII() { return ascii_console; } -//---------------------------------------------------------------------- -inline bool FTerm::isNewFont() -{ return NewFont; } - //---------------------------------------------------------------------- inline bool FTerm::isMonochron() { return monochron; } @@ -502,28 +472,8 @@ inline bool FTerm::isInputDataPending() { return input_data_pending; } //---------------------------------------------------------------------- -inline bool FTerm::setCursorOptimisation (bool on) -{ return cursor_optimisation = (on) ? true : false; } - -//---------------------------------------------------------------------- -inline bool FTerm::isRaw() -{ return raw_mode; } - -//---------------------------------------------------------------------- -inline int FTerm::getMaxColor() -{ return FTermcap::max_color; } - -//---------------------------------------------------------------------- -inline bool FTerm::unsetNonBlockingInput() -{ return setNonBlockingInput(false); } - -//---------------------------------------------------------------------- -inline bool FTerm::setUTF8() -{ return setUTF8(true); } - -//---------------------------------------------------------------------- -inline bool FTerm::unsetUTF8() -{ return setUTF8(false); } +inline bool FTerm::isNewFont() +{ return NewFont; } //---------------------------------------------------------------------- inline bool FTerm::isUTF8() @@ -533,6 +483,10 @@ inline bool FTerm::isUTF8() inline bool FTerm::isUTF8_linux_terminal() { return utf8_linux_terminal; } +//---------------------------------------------------------------------- +inline bool FTerm::setCursorOptimisation (bool on) +{ return cursor_optimisation = (on) ? true : false; } + //---------------------------------------------------------------------- inline bool FTerm::setRawMode() { return setRawMode(true); } @@ -545,5 +499,63 @@ inline bool FTerm::unsetRawMode() inline bool FTerm::setCookedMode() { return setRawMode(false); } +//---------------------------------------------------------------------- +inline bool FTerm::setUTF8() +{ return setUTF8(true); } + +//---------------------------------------------------------------------- +inline bool FTerm::unsetUTF8() +{ return setUTF8(false); } + +//---------------------------------------------------------------------- +inline bool FTerm::setNonBlockingInput() +{ return setNonBlockingInput(true); } + +//---------------------------------------------------------------------- +inline bool FTerm::unsetNonBlockingInput() +{ return setNonBlockingInput(false); } + +//---------------------------------------------------------------------- +inline bool FTerm::hasChangedTermSize() +{ return resize_term; } + +//---------------------------------------------------------------------- +inline void FTerm::changeTermSizeFinished() +{ resize_term = false; } + +//---------------------------------------------------------------------- +inline void FTerm::enableXTermMouse() +{ xtermMouse(true); } + +//---------------------------------------------------------------------- +inline void FTerm::disableXTermMouse() +{ xtermMouse(false); } + +#ifdef F_HAVE_LIBGPM +//---------------------------------------------------------------------- +inline bool FTerm::enableGpmMouse() +{ return gpmMouse(true); } + +//---------------------------------------------------------------------- +inline bool FTerm::disableGpmMouse() +{ return gpmMouse(false); } + +//---------------------------------------------------------------------- +inline bool FTerm::isGpmMouseEnabled() +{ return gpm_mouse_enabled; } +#endif // F_HAVE_LIBGPM + +//---------------------------------------------------------------------- +inline FPoint& FTerm::getMousePos() +{ return *mouse; } + +//---------------------------------------------------------------------- +inline void FTerm::setMousePos (FPoint& m) +{ *mouse = m; } + +//---------------------------------------------------------------------- +inline void FTerm::setMousePos (short x, short y) +{ mouse->setPoint (x, y); } + #endif // _FTERM_H diff --git a/src/ftermcap.h b/src/ftermcap.h index ebfefcb7..7aa0b562 100644 --- a/src/ftermcap.h +++ b/src/ftermcap.h @@ -15,13 +15,13 @@ //---------------------------------------------------------------------- // class FTermcap //---------------------------------------------------------------------- - #pragma pack(push) #pragma pack(1) class FTermcap { public: + // Typedef typedef struct { char* string; @@ -29,6 +29,27 @@ class FTermcap } tcap_map; + // Constructors + FTermcap() + { } + + // Destructor + ~FTermcap() + { } + + // Accessor + tcap_map* getTermcapMap() + { + return tcap; + } + + // Mutator + void setTermcapMap (tcap_map* t) + { + tcap = t; + } + + // Data Members static bool background_color_erase; static bool automatic_left_margin; static bool automatic_right_margin; @@ -40,24 +61,8 @@ class FTermcap static uInt attr_without_color; private: + // Data Members static tcap_map* tcap; - - public: - FTermcap() - { } - - ~FTermcap() - { } - - tcap_map* getTermcapMap() - { - return tcap; - } - - void setTermcapMap (tcap_map* t) - { - tcap = t; - } }; #pragma pack(pop) diff --git a/src/ftextview.cpp b/src/ftextview.cpp index d8971e6e..f3f7ed35 100644 --- a/src/ftextview.cpp +++ b/src/ftextview.cpp @@ -32,207 +32,94 @@ FTextView::~FTextView() // destructor delete hbar; } -// private methods of FTextView + +// public methods of FTextView //---------------------------------------------------------------------- -void FTextView::init() +FString FTextView::getText() const { - nf_offset = isNewFont() ? 1 : 0; + uInt len, rows, idx; - setForegroundColor (wc.dialog_fg); - setBackgroundColor (wc.dialog_bg); + if ( data.empty() ) + return FString(""); - vbar = new FScrollbar(fc::vertical, this); - vbar->setMinimum(0); - vbar->setValue(0); - vbar->hide(); + len = 0; + rows = getRows(); - hbar = new FScrollbar(fc::horizontal, this); - hbar->setMinimum(0); - hbar->setValue(0); - hbar->hide(); + for (uInt i=0 ; i < rows; i++) + len += data[i].getLength() + 1; - vbar->addCallback - ( - "change-value", - _METHOD_CALLBACK (this, &FTextView::cb_VBarChange) - ); - hbar->addCallback - ( - "change-value", - _METHOD_CALLBACK (this, &FTextView::cb_HBarChange) - ); -} + FString s(len + 1); + idx = 0; -//---------------------------------------------------------------------- -void FTextView::draw() -{ - FWidget* parent = getParentWidget(); - bool is_text_dialog; - updateVTerm(false); - setColor(); - - if ( isMonochron() ) - setReverse(true); - - if ( parent - && parent->isDialogWidget() - && isPaddingIgnored() - && getGeometry() == FRect ( 1 - , 2 - , parent->getWidth() - , parent->getHeight()-1) ) + for (uInt i=0 ; i < rows; i++) { - is_text_dialog = true; - } - else - is_text_dialog = false; + const wchar_t* p = data[i].wc_str(); - if ( ! (is_text_dialog || isNewFont()) ) - drawBorder(); - - if ( isMonochron() ) - setReverse(false); - - if ( vbar->isVisible() ) - vbar->redraw(); - - if ( hbar->isVisible() ) - hbar->redraw(); - - updateVTerm(true); - drawText(); - - if ( hasFocus() && statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) + if ( p ) { - updateVTerm(false); - statusBar()->setMessage(msg); - statusBar()->drawMessage(); - updateVTerm(true); + while ( (s[idx++] = *p++) != 0 ); + s[idx-1] = '\n'; + } + else + { + s[idx++] = '\n'; } } - setCursorPos (getWidth(), getHeight()); - updateTerminal(); + s[idx-1] = 0; + return s; +} + +//---------------------------------------------------------------------- +void FTextView::setGeometry (int x, int y, int w, int h, bool adjust) +{ + FWidget::setGeometry(x, y, w, h, adjust); + int width = getWidth(); + int height = getHeight(); + + if ( isNewFont() ) + { + vbar->setGeometry (width, 1, 2, height-1); + hbar->setGeometry (1, height, width-2, 1); + } + else + { + vbar->setGeometry (width, 2, 1, height-2); + hbar->setGeometry (2, height, width-2, 1); + } + + vbar->resize(); + hbar->resize(); +} + +//---------------------------------------------------------------------- +void FTextView::setPosition (int pos) +{ + int last_line = int(getRows()); + + if ( pos < 0 || pos > last_line - getHeight() + 2 ) + return; + + yoffset = pos; + + if ( isVisible() ) + drawText(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() ) + vbar->drawBar(); + flush_out(); } //---------------------------------------------------------------------- -void FTextView::drawText() +void FTextView::setText (const FString& str) { - uInt start, end; - - if ( data.empty() || getHeight() <= 2 || getWidth() <= 2 ) - return; - - start = 0; - end = uInt(getHeight() + nf_offset - 2); - - if ( end > getRows() ) - end = getRows(); - - updateVTerm(false); - setColor(); - - if ( isMonochron() ) - setReverse(true); - - for (uInt y=start; y < end; y++) - { - uInt i, len; - FString line; - const wchar_t* line_str; - setPrintPos (2, 2 - nf_offset + int(y)); - line = data[y+uInt(yoffset)].mid ( uInt(1 + xoffset) - , uInt(getWidth() - nf_offset - 2) ); - line_str = line.wc_str(); - len = line.getLength(); - - for (i=0; i < len; i++) - { - wchar_t ch = line_str[i]; - bool utf8 = (Encoding == fc::UTF8) ? true : false; - - // only printable and 1 column per character - if ( ( (utf8 && std::iswprint(wint_t(ch))) - || (!utf8 && ch < 256 && std::isprint(ch)) ) - && wcwidth(ch) == 1 ) - { - print (ch); - } - else - print ('.'); - } - - for (; i < uInt(getWidth() - nf_offset - 2); i++) - print (' '); - } - - if ( isMonochron() ) - setReverse(false); - - updateVTerm(true); + clear(); + insert(str, -1); } -//---------------------------------------------------------------------- -void FTextView::processChanged() -{ - emitCallback("changed"); -} - -// protected methods of FTextView -//---------------------------------------------------------------------- -void FTextView::adjustSize() -{ - FWidget::adjustSize(); - int width = getWidth(); - int height = getHeight(); - int last_line = int(getRows()); - int max_width = int(maxLineWidth); - - if ( xoffset >= max_width - width - nf_offset ) - xoffset = max_width - width - nf_offset - 1; - - if ( xoffset < 0 ) - xoffset = 0; - - if ( yoffset > last_line - height - nf_offset + 2 ) - yoffset = last_line - height - nf_offset + 2; - - if ( yoffset < 0 ) - yoffset = 0; - - vbar->setMaximum (last_line - height + 2 - nf_offset); - vbar->setPageSize (last_line, height - 2 + nf_offset); - vbar->setX (width); - vbar->setHeight (height - 2 + nf_offset, false); - vbar->setValue (yoffset); - vbar->resize(); - - hbar->setMaximum (max_width - width + nf_offset + 2); - hbar->setPageSize (max_width, width - nf_offset - 2); - hbar->setY (height); - hbar->setWidth (width - 2, false); - hbar->setValue (xoffset); - hbar->resize(); - - if ( last_line < height + nf_offset - 1 ) - vbar->hide(); - else - vbar->setVisible(); - - if ( max_width < width - nf_offset - 1 ) - hbar->hide(); - else - hbar->setVisible(); -} - - -// public methods of FTextView //---------------------------------------------------------------------- void FTextView::hide() { @@ -275,6 +162,132 @@ void FTextView::hide() flush_out(); } +//---------------------------------------------------------------------- +void FTextView::append (const FString& str) +{ + insert(str, -1); +} + +//---------------------------------------------------------------------- +void FTextView::insert (const FString& str, int pos) +{ + stringLines::iterator iter; + stringLines text_split; + FString s; + uLong end; + + if ( pos < 0 || pos >= int(getRows()) ) + pos = int(getRows()); + + if ( str.isEmpty() ) + s = "\n"; + else + s = FString(str).rtrim().expandTabs(getTabstop()); + + iter = data.begin(); + text_split = s.split("\r\n"); + end = text_split.size(); + + for (uInt i=0; i < end; i++) + { + uInt len; + text_split[i] = text_split[i].removeBackspaces() + .removeDel() + .replaceControlCodes() + .rtrim(); + len = text_split[i].getLength(); + + if ( len > maxLineWidth ) + { + maxLineWidth = len; + + if ( len > uInt(getWidth() - nf_offset - 2) ) + { + hbar->setMaximum (int(maxLineWidth) - getWidth() + nf_offset + 2); + hbar->setPageSize (int(maxLineWidth), getWidth() - nf_offset - 2); + hbar->calculateSliderValues(); + + if ( ! hbar->isVisible() ) + hbar->setVisible(); + } + } + } + + data.insert (iter + pos, text_split.begin(), text_split.end()); + vbar->setMaximum (int(getRows()) - getHeight() + 2 - nf_offset); + vbar->setPageSize (int(getRows()), getHeight() - 2 + nf_offset); + vbar->calculateSliderValues(); + + if ( ! vbar->isVisible() && int(getRows()) >= getHeight() + nf_offset - 1 ) + vbar->setVisible(); + + if ( vbar->isVisible() && int(getRows()) < getHeight() + nf_offset - 1 ) + vbar->hide(); + + processChanged(); +} + +//---------------------------------------------------------------------- +void FTextView::replaceRange (const FString& str, int start, int end) +{ + stringLines::iterator iter; + + if ( start > end ) + return; + + if ( start < 0 || start >= int(getRows()) ) + return; + + if ( end < 0 || end >= int(getRows()) ) + return; + + iter = data.begin(); + data.erase (iter+start, iter+end+1); + + if ( ! str.isNull() ) + insert(str, start); +} + +//---------------------------------------------------------------------- +void FTextView::clear() +{ + int size; + char* blank; + + data.clear(); + xoffset = 0; + yoffset = 0; + maxLineWidth = 0; + + vbar->setMinimum(0); + vbar->setValue(0); + vbar->hide(); + + hbar->setMinimum(0); + hbar->setValue(0); + hbar->hide(); + + // clear list from screen + setColor(); + size = getWidth() - 2; + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset(blank, ' ', uLong(size)); + blank[size] = '\0'; + + for (int y=0; y < getHeight() + nf_offset - 2; y++) + { + setPrintPos (2, 2 - nf_offset + y); + print (blank); + } + + delete[] blank; + processChanged(); +} + //---------------------------------------------------------------------- void FTextView::onKeyPress (FKeyEvent* ev) { @@ -388,8 +401,8 @@ void FTextView::onMouseDown (FMouseEvent* ev) if ( focused_widget ) focused_widget->redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); } parent = getParentWidget(); @@ -519,20 +532,221 @@ void FTextView::onWheel (FWheelEvent* ev) //---------------------------------------------------------------------- void FTextView::onFocusIn (FFocusEvent*) { - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); } //---------------------------------------------------------------------- void FTextView::onFocusOut (FFocusEvent*) { - if ( statusBar() ) + if ( getStatusBar() ) { - statusBar()->clearMessage(); - statusBar()->drawMessage(); + getStatusBar()->clearMessage(); + getStatusBar()->drawMessage(); } } + +// protected methods of FTextView +//---------------------------------------------------------------------- +void FTextView::adjustSize() +{ + FWidget::adjustSize(); + int width = getWidth(); + int height = getHeight(); + int last_line = int(getRows()); + int max_width = int(maxLineWidth); + + if ( xoffset >= max_width - width - nf_offset ) + xoffset = max_width - width - nf_offset - 1; + + if ( xoffset < 0 ) + xoffset = 0; + + if ( yoffset > last_line - height - nf_offset + 2 ) + yoffset = last_line - height - nf_offset + 2; + + if ( yoffset < 0 ) + yoffset = 0; + + vbar->setMaximum (last_line - height + 2 - nf_offset); + vbar->setPageSize (last_line, height - 2 + nf_offset); + vbar->setX (width); + vbar->setHeight (height - 2 + nf_offset, false); + vbar->setValue (yoffset); + vbar->resize(); + + hbar->setMaximum (max_width - width + nf_offset + 2); + hbar->setPageSize (max_width, width - nf_offset - 2); + hbar->setY (height); + hbar->setWidth (width - 2, false); + hbar->setValue (xoffset); + hbar->resize(); + + if ( last_line < height + nf_offset - 1 ) + vbar->hide(); + else + vbar->setVisible(); + + if ( max_width < width - nf_offset - 1 ) + hbar->hide(); + else + hbar->setVisible(); +} + + +// private methods of FTextView +//---------------------------------------------------------------------- +void FTextView::init() +{ + nf_offset = isNewFont() ? 1 : 0; + + setForegroundColor (wc.dialog_fg); + setBackgroundColor (wc.dialog_bg); + + vbar = new FScrollbar(fc::vertical, this); + vbar->setMinimum(0); + vbar->setValue(0); + vbar->hide(); + + hbar = new FScrollbar(fc::horizontal, this); + hbar->setMinimum(0); + hbar->setValue(0); + hbar->hide(); + + vbar->addCallback + ( + "change-value", + _METHOD_CALLBACK (this, &FTextView::cb_VBarChange) + ); + hbar->addCallback + ( + "change-value", + _METHOD_CALLBACK (this, &FTextView::cb_HBarChange) + ); +} + +//---------------------------------------------------------------------- +void FTextView::draw() +{ + FWidget* parent = getParentWidget(); + bool is_text_dialog; + updateVTerm(false); + setColor(); + + if ( isMonochron() ) + setReverse(true); + + if ( parent + && parent->isDialogWidget() + && isPaddingIgnored() + && getGeometry() == FRect ( 1 + , 2 + , parent->getWidth() + , parent->getHeight() - 1) ) + { + is_text_dialog = true; + } + else + is_text_dialog = false; + + if ( ! (is_text_dialog || isNewFont()) ) + drawBorder(); + + if ( isMonochron() ) + setReverse(false); + + if ( vbar->isVisible() ) + vbar->redraw(); + + if ( hbar->isVisible() ) + hbar->redraw(); + + updateVTerm(true); + drawText(); + + if ( hasFocus() && getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + { + updateVTerm(false); + getStatusBar()->setMessage(msg); + getStatusBar()->drawMessage(); + updateVTerm(true); + } + } + + setCursorPos (getWidth(), getHeight()); + updateTerminal(); + flush_out(); +} + +//---------------------------------------------------------------------- +void FTextView::drawText() +{ + uInt start, end; + + if ( data.empty() || getHeight() <= 2 || getWidth() <= 2 ) + return; + + start = 0; + end = uInt(getHeight() + nf_offset - 2); + + if ( end > getRows() ) + end = getRows(); + + updateVTerm(false); + setColor(); + + if ( isMonochron() ) + setReverse(true); + + for (uInt y=start; y < end; y++) + { + uInt i, len; + FString line; + const wchar_t* line_str; + setPrintPos (2, 2 - nf_offset + int(y)); + line = data[y+uInt(yoffset)].mid ( uInt(1 + xoffset) + , uInt(getWidth() - nf_offset - 2) ); + line_str = line.wc_str(); + len = line.getLength(); + + for (i=0; i < len; i++) + { + wchar_t ch = line_str[i]; + bool utf8 = (Encoding == fc::UTF8) ? true : false; + + // only printable and 1 column per character + if ( ( (utf8 && std::iswprint(wint_t(ch))) + || (!utf8 && ch < 256 && std::isprint(ch)) ) + && wcwidth(ch) == 1 ) + { + print (ch); + } + else + print ('.'); + } + + for (; i < uInt(getWidth() - nf_offset - 2); i++) + print (' '); + } + + if ( isMonochron() ) + setReverse(false); + + updateVTerm(true); +} + +//---------------------------------------------------------------------- +void FTextView::processChanged() +{ + emitCallback("changed"); +} + //---------------------------------------------------------------------- void FTextView::cb_VBarChange (FWidget*, void*) { @@ -716,215 +930,3 @@ void FTextView::cb_HBarChange (FWidget*, void*) updateTerminal(); } } - -//---------------------------------------------------------------------- -void FTextView::setGeometry (int x, int y, int w, int h, bool adjust) -{ - FWidget::setGeometry(x, y, w, h, adjust); - int width = getWidth(); - int height = getHeight(); - - if ( isNewFont() ) - { - vbar->setGeometry (width, 1, 2, height-1); - hbar->setGeometry (1, height, width-2, 1); - } - else - { - vbar->setGeometry (width, 2, 1, height-2); - hbar->setGeometry (2, height, width-2, 1); - } - - vbar->resize(); - hbar->resize(); -} - -//---------------------------------------------------------------------- -void FTextView::setPosition (int pos) -{ - int last_line = int(getRows()); - - if ( pos < 0 || pos > last_line - getHeight() + 2 ) - return; - - yoffset = pos; - - if ( isVisible() ) - drawText(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() ) - vbar->drawBar(); - - flush_out(); -} - -//---------------------------------------------------------------------- -void FTextView::setText (const FString& str) -{ - clear(); - insert(str, -1); -} - -//---------------------------------------------------------------------- -FString FTextView::getText() const -{ - uInt len, rows, idx; - - if ( data.empty() ) - return FString(""); - - len = 0; - rows = getRows(); - - for (uInt i=0 ; i < rows; i++) - len += data[i].getLength() + 1; - - FString s(len + 1); - idx = 0; - - for (uInt i=0 ; i < rows; i++) - { - const wchar_t* p = data[i].wc_str(); - - if ( p ) - { - while ( (s[idx++] = *p++) != 0 ); - s[idx-1] = '\n'; - } - else - { - s[idx++] = '\n'; - } - } - - s[idx-1] = 0; - return s; -} - -//---------------------------------------------------------------------- -void FTextView::append (const FString& str) -{ - insert(str, -1); -} - -//---------------------------------------------------------------------- -void FTextView::insert (const FString& str, int pos) -{ - stringLines::iterator iter; - stringLines text_split; - FString s; - uLong end; - - if ( pos < 0 || pos >= int(getRows()) ) - pos = int(getRows()); - - if ( str.isEmpty() ) - s = "\n"; - else - s = FString(str).rtrim().expandTabs(getTabstop()); - - iter = data.begin(); - text_split = s.split("\r\n"); - end = text_split.size(); - - for (uInt i=0; i < end; i++) - { - uInt len; - text_split[i] = text_split[i].removeBackspaces() - .removeDel() - .replaceControlCodes() - .rtrim(); - len = text_split[i].getLength(); - - if ( len > maxLineWidth ) - { - maxLineWidth = len; - - if ( len > uInt(getWidth() - nf_offset - 2) ) - { - hbar->setMaximum (int(maxLineWidth) - getWidth() + nf_offset + 2); - hbar->setPageSize (int(maxLineWidth), getWidth() - nf_offset - 2); - hbar->calculateSliderValues(); - - if ( ! hbar->isVisible() ) - hbar->setVisible(); - } - } - } - - data.insert (iter + pos, text_split.begin(), text_split.end()); - vbar->setMaximum (int(getRows()) - getHeight() + 2 - nf_offset); - vbar->setPageSize (int(getRows()), getHeight() - 2 + nf_offset); - vbar->calculateSliderValues(); - - if ( ! vbar->isVisible() && int(getRows()) >= getHeight() + nf_offset - 1 ) - vbar->setVisible(); - - if ( vbar->isVisible() && int(getRows()) < getHeight() + nf_offset - 1 ) - vbar->hide(); - - processChanged(); -} - -//---------------------------------------------------------------------- -void FTextView::replaceRange (const FString& str, int start, int end) -{ - stringLines::iterator iter; - - if ( start > end ) - return; - - if ( start < 0 || start >= int(getRows()) ) - return; - - if ( end < 0 || end >= int(getRows()) ) - return; - - iter = data.begin(); - data.erase (iter+start, iter+end+1); - - if ( ! str.isNull() ) - insert(str, start); -} - -//---------------------------------------------------------------------- -void FTextView::clear() -{ - int size; - char* blank; - - data.clear(); - xoffset = 0; - yoffset = 0; - maxLineWidth = 0; - - vbar->setMinimum(0); - vbar->setValue(0); - vbar->hide(); - - hbar->setMinimum(0); - hbar->setValue(0); - hbar->hide(); - - // clear list from screen - setColor(); - size = getWidth() - 2; - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset(blank, ' ', uLong(size)); - blank[size] = '\0'; - - for (int y=0; y < getHeight() + nf_offset - 2; y++) - { - setPrintPos (2, 2 - nf_offset + y); - print (blank); - } - - delete[] blank; - processChanged(); -} diff --git a/src/ftextview.h b/src/ftextview.h index b1ef9a4c..75ab2839 100644 --- a/src/ftextview.h +++ b/src/ftextview.h @@ -44,42 +44,39 @@ class FTextView : public FWidget { - private: - typedef std::vector stringLines; - stringLines data; - FScrollbar* vbar; - FScrollbar* hbar; - int xoffset; - int yoffset; - int nf_offset; - uInt maxLineWidth; - - private: - // Disable copy constructor - FTextView (const FTextView&); - // Disable assignment operator (=) - FTextView& operator = (const FTextView&); - - void init(); - void draw(); - void drawText(); - void processChanged(); - - // Callback methods - void cb_VBarChange (FWidget*, void*); - void cb_HBarChange (FWidget*, void*); - - protected: - void adjustSize(); - public: + // Using-declarations + using FWidget::setGeometry; + + // Typedef + typedef std::vector stringLines; + // Constructor explicit FTextView (FWidget* = 0); + // Destructor ~FTextView(); + // Accessors const char* getClassName() const; + uInt getColumns() const; + uInt getRows() const; + FString getText() const; + stringLines getLines() const; + + // Mutators + void setGeometry (int, int, int, int, bool = true); + void setPosition (int); + void setText (const FString&); + + // Methods void hide(); + void append (const FString&); + void insert (const FString&, int); + void replaceRange (const FString&, int, int); + void deleteRange (int, int); + void deleteLine (int); + void clear(); // Event handlers void onKeyPress (FKeyEvent*); @@ -90,21 +87,35 @@ class FTextView : public FWidget void onFocusIn (FFocusEvent*); void onFocusOut (FFocusEvent*); - // make every setGeometry from FWidget available - using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - uInt getColumns() const; - uInt getRows() const; - void setPosition (int); - void setText (const FString&); - FString getText() const; - void append (const FString&); - void insert (const FString&, int); - void replaceRange (const FString&, int, int); - void deleteRange (int, int); - void deleteLine (int); - stringLines getLines() const; - void clear(); + protected: + // Method + void adjustSize(); + + private: + // Disable copy constructor + FTextView (const FTextView&); + + // Disable assignment operator (=) + FTextView& operator = (const FTextView&); + + // Methods + void init(); + void draw(); + void drawText(); + void processChanged(); + + // Callback methods + void cb_VBarChange (FWidget*, void*); + void cb_HBarChange (FWidget*, void*); + + // Data Members + stringLines data; + FScrollbar* vbar; + FScrollbar* hbar; + int xoffset; + int yoffset; + int nf_offset; + uInt maxLineWidth; }; #pragma pack(pop) @@ -122,6 +133,10 @@ inline uInt FTextView::getColumns() const inline uInt FTextView::getRows() const { return uInt(data.size()); } +//---------------------------------------------------------------------- +inline FTextView::stringLines FTextView::getLines() const +{ return data; } + //---------------------------------------------------------------------- inline void FTextView::deleteRange (int start, int end) { replaceRange (FString(), start, end); } @@ -130,8 +145,4 @@ inline void FTextView::deleteRange (int start, int end) inline void FTextView::deleteLine (int pos) { deleteRange (pos, pos); } -//---------------------------------------------------------------------- -inline FTextView::stringLines FTextView::getLines() const -{ return data; } - #endif // _FTEXTVIEW_H diff --git a/src/ftogglebutton.cpp b/src/ftogglebutton.cpp index d9012200..f33b95ab 100644 --- a/src/ftogglebutton.cpp +++ b/src/ftogglebutton.cpp @@ -15,12 +15,12 @@ //---------------------------------------------------------------------- FToggleButton::FToggleButton(FWidget* parent) : FWidget(parent) - , focus_inside_group(true) - , text() , checked(false) , label_offset_pos(0) , button_width(0) , button_group(0) + , focus_inside_group(true) + , text() { init(); @@ -29,20 +29,20 @@ FToggleButton::FToggleButton(FWidget* parent) { setGroup( static_cast(parent) ); - if ( group() ) - group()->insert(this); // insert into button group + if ( getGroup() ) + getGroup()->insert(this); // insert into button group } } //---------------------------------------------------------------------- FToggleButton::FToggleButton (const FString& txt, FWidget* parent) : FWidget(parent) - , focus_inside_group(true) - , text() , checked(false) , label_offset_pos(0) , button_width(0) , button_group(0) + , focus_inside_group(true) + , text() { init(); setText(txt); @@ -52,8 +52,8 @@ FToggleButton::FToggleButton (const FString& txt, FWidget* parent) { setGroup( static_cast(parent) ); - if ( group() ) - group()->insert( this ); // insert into button group + if ( getGroup() ) + getGroup()->insert( this ); // insert into button group } } @@ -62,23 +62,43 @@ FToggleButton::~FToggleButton() // destructor { delAccelerator(); - if ( group() ) - group()->remove(this); + if ( getGroup() ) + getGroup()->remove(this); } -// private methods of FToggleButton +// public methods of FToggleButton //---------------------------------------------------------------------- -void FToggleButton::init() +void FToggleButton::setGeometry (int x, int y, int w, int h, bool adjust) { - setGeometry (1, 1, 4, 1, false); // initialize geometry values + int min_width = button_width + int(text.getLength()); - if ( hasFocus() ) - flags = fc::focus; + if ( w < min_width ) + w = min_width; - if ( isEnabled() ) + FWidget::setGeometry(x, y, w, h, adjust); +} + +//---------------------------------------------------------------------- +bool FToggleButton::setNoUnderline (bool on) +{ + if ( on ) + flags |= fc::no_underline; + else + flags &= ~fc::no_underline; + + return on; +} + +//---------------------------------------------------------------------- +bool FToggleButton::setEnable (bool on) +{ + FWidget::setEnable(on); + + if ( on ) { flags |= fc::active; + setHotkeyAccelerator(); if ( hasFocus() ) { @@ -91,17 +111,265 @@ void FToggleButton::init() setBackgroundColor (wc.toggle_button_active_bg); } } - else // inactive + else { - setForegroundColor (wc.label_inactive_fg); - setBackgroundColor (wc.label_inactive_bg); + flags &= ~fc::active; + delAccelerator(); + setForegroundColor (wc.toggle_button_inactive_fg); + setBackgroundColor (wc.toggle_button_inactive_bg); + } + + return on; +} + +//---------------------------------------------------------------------- +bool FToggleButton::setFocus (bool on) +{ + FWidget::setFocus(on); + + if ( on ) + { + flags |= fc::focus; + + if ( isEnabled() ) + { + if ( isRadioButton() ) + focus_inside_group = false; + + setForegroundColor (wc.toggle_button_active_focus_fg); + setBackgroundColor (wc.toggle_button_active_focus_bg); + + if ( getStatusBar() ) + { + FString msg = getStatusbarMessage(); + FString curMsg = getStatusBar()->getMessage(); + + if ( curMsg != msg ) + getStatusBar()->setMessage(msg); + } + } + } + else + { + flags &= ~fc::focus; + + if ( isEnabled() ) + { + setForegroundColor (wc.toggle_button_active_fg); + setBackgroundColor (wc.toggle_button_active_bg); + + if ( getStatusBar() ) + getStatusBar()->clearMessage(); + } + } + + return on; +} + +//---------------------------------------------------------------------- +bool FToggleButton::setChecked (bool on) +{ + if ( checked != on ) + { + checked = on; + processToggle(); + } + + return checked; +} + +//---------------------------------------------------------------------- +void FToggleButton::setText (FString txt) +{ + text = txt; + setWidth(button_width + int(text.getLength())); + + if ( isEnabled() ) + { + delAccelerator(); + setHotkeyAccelerator(); } } //---------------------------------------------------------------------- -void FToggleButton::setGroup (FButtonGroup* btngroup) +void FToggleButton::hide() { - button_group = btngroup; + int size; + short fg, bg; + char* blank; + FWidget* parent_widget = getParentWidget(); + + FWidget::hide(); + + if ( parent_widget ) + { + fg = parent_widget->getForegroundColor(); + bg = parent_widget->getBackgroundColor(); + } + else + { + fg = wc.dialog_fg; + bg = wc.dialog_bg; + } + + setColor (fg, bg); + size = getWidth(); + + if ( size < 0 ) + return; + + blank = new char[size+1]; + std::memset(blank, ' ', uLong(size)); + blank[size] = '\0'; + setPrintPos (1, 1); + print (blank); + delete[] blank; +} + +//---------------------------------------------------------------------- +void FToggleButton::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( hasFocus() ) + return; + + FWidget* focused_widget = getFocusWidget(); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + redraw(); + + if ( getStatusBar() ) + { + getStatusBar()->drawMessage(); + updateTerminal(); + flush_out(); + } +} + +//---------------------------------------------------------------------- +void FToggleButton::onMouseUp (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( ! getTermGeometry().contains(ev->getTermPos()) ) + return; + + if ( isRadioButton() ) + { + if ( ! checked ) + { + checked = true; + processToggle(); + } + } + else + { + checked = not checked; + processToggle(); + } + + redraw(); + processClick(); +} + +//---------------------------------------------------------------------- +void FToggleButton::onAccel (FAccelEvent* ev) +{ + if ( ! isEnabled() ) + return; + + if ( ! hasFocus() ) + { + FWidget* focused_widget = static_cast(ev->focusedWidget()); + FFocusEvent out (fc::FocusOut_Event); + FApplication::queueEvent(focused_widget, &out); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + } + + if ( isRadioButton() ) + { + if ( ! checked ) + { + checked = true; + processToggle(); + } + } + else + { + checked = not checked; + processToggle(); + } + + redraw(); + + if ( getStatusBar() ) + { + getStatusBar()->drawMessage(); + updateTerminal(); + flush_out(); + } + + processClick(); + ev->accept(); +} + +//---------------------------------------------------------------------- +void FToggleButton::onFocusIn (FFocusEvent*) +{ + if ( getStatusBar() ) + getStatusBar()->drawMessage(); +} + +//---------------------------------------------------------------------- +void FToggleButton::onFocusOut (FFocusEvent* out_ev) +{ + if ( getStatusBar() ) + { + getStatusBar()->clearMessage(); + getStatusBar()->drawMessage(); + } + + if ( ! getGroup() ) + return; + + if ( ! focus_inside_group && isRadioButton() ) + { + focus_inside_group = true; + out_ev->ignore(); + + if ( out_ev->getFocusType() == fc::FocusNextWidget ) + getGroup()->focusNextChild(); + + if ( out_ev->getFocusType() == fc::FocusPreviousWidget ) + getGroup()->focusPrevChild(); + + redraw(); + } + else if ( this == getGroup()->getLastButton() + && out_ev->getFocusType() == fc::FocusNextWidget ) + { + out_ev->ignore(); + getGroup()->focusNextChild(); + redraw(); + } + else if ( this == getGroup()->getFirstButton() + && out_ev->getFocusType() == fc::FocusPreviousWidget ) + { + out_ev->ignore(); + getGroup()->focusPrevChild(); + redraw(); + } } @@ -153,20 +421,34 @@ void FToggleButton::setHotkeyAccelerator() delAccelerator(); } +//---------------------------------------------------------------------- +bool FToggleButton::isRadioButton() const +{ + return ( std::strcmp ( getClassName() + , const_cast("FRadioButton") ) == 0 ); +} + +//---------------------------------------------------------------------- +bool FToggleButton::isCheckboxButton() const +{ + return ( std::strcmp ( getClassName() + , const_cast("FCheckBox") ) == 0 ); +} + //---------------------------------------------------------------------- void FToggleButton::draw() { bool isFocus = ((flags & fc::focus) != 0); - if ( isFocus && statusBar() ) + if ( isFocus && getStatusBar() ) { FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); + FString curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { - statusBar()->setMessage(msg); - statusBar()->drawMessage(); + getStatusBar()->setMessage(msg); + getStatusBar()->drawMessage(); } } @@ -267,26 +549,6 @@ void FToggleButton::processToggle() emitCallback("toggled"); } -//---------------------------------------------------------------------- -FButtonGroup* FToggleButton::group() const -{ - return button_group; -} - -//---------------------------------------------------------------------- -bool FToggleButton::isRadioButton() const -{ - return ( std::strcmp ( getClassName() - , const_cast("FRadioButton") ) == 0 ); -} - -//---------------------------------------------------------------------- -bool FToggleButton::isCheckboxButton() const -{ - return ( std::strcmp ( getClassName() - , const_cast("FCheckBox") ) == 0 ); -} - //---------------------------------------------------------------------- void FToggleButton::onKeyPress (FKeyEvent* ev) { @@ -345,73 +607,24 @@ void FToggleButton::onKeyPress (FKeyEvent* ev) } -// public methods of FToggleButton +// private methods of FToggleButton //---------------------------------------------------------------------- -void FToggleButton::hide() +void FToggleButton::setGroup (FButtonGroup* btngroup) { - int size; - short fg, bg; - char* blank; - FWidget* parent_widget = getParentWidget(); - - FWidget::hide(); - - if ( parent_widget ) - { - fg = parent_widget->getForegroundColor(); - bg = parent_widget->getBackgroundColor(); - } - else - { - fg = wc.dialog_fg; - bg = wc.dialog_bg; - } - - setColor (fg, bg); - size = getWidth(); - - if ( size < 0 ) - return; - - blank = new char[size+1]; - std::memset(blank, ' ', uLong(size)); - blank[size] = '\0'; - setPrintPos (1, 1); - print (blank); - delete[] blank; + button_group = btngroup; } //---------------------------------------------------------------------- -void FToggleButton::setGeometry (int x, int y, int w, int h, bool adjust) +void FToggleButton::init() { - int min_width = button_width + int(text.getLength()); + setGeometry (1, 1, 4, 1, false); // initialize geometry values - if ( w < min_width ) - w = min_width; + if ( hasFocus() ) + flags = fc::focus; - FWidget::setGeometry(x, y, w, h, adjust); -} - -//---------------------------------------------------------------------- -bool FToggleButton::setNoUnderline (bool on) -{ - if ( on ) - flags |= fc::no_underline; - else - flags &= ~fc::no_underline; - - return on; -} - -//---------------------------------------------------------------------- -bool FToggleButton::setEnable (bool on) -{ - FWidget::setEnable(on); - - if ( on ) + if ( isEnabled() ) { flags |= fc::active; - setHotkeyAccelerator(); if ( hasFocus() ) { @@ -424,228 +637,9 @@ bool FToggleButton::setEnable (bool on) setBackgroundColor (wc.toggle_button_active_bg); } } - else + else // inactive { - flags &= ~fc::active; - delAccelerator(); - setForegroundColor (wc.toggle_button_inactive_fg); - setBackgroundColor (wc.toggle_button_inactive_bg); - } - - return on; -} - -//---------------------------------------------------------------------- -bool FToggleButton::setFocus (bool on) -{ - FWidget::setFocus(on); - - if ( on ) - { - flags |= fc::focus; - - if ( isEnabled() ) - { - if ( isRadioButton() ) - focus_inside_group = false; - - setForegroundColor (wc.toggle_button_active_focus_fg); - setBackgroundColor (wc.toggle_button_active_focus_bg); - - if ( statusBar() ) - { - FString msg = getStatusbarMessage(); - FString curMsg = statusBar()->getMessage(); - - if ( curMsg != msg ) - statusBar()->setMessage(msg); - } - } - } - else - { - flags &= ~fc::focus; - - if ( isEnabled() ) - { - setForegroundColor (wc.toggle_button_active_fg); - setBackgroundColor (wc.toggle_button_active_bg); - - if ( statusBar() ) - statusBar()->clearMessage(); - } - } - - return on; -} - -//---------------------------------------------------------------------- -void FToggleButton::onMouseDown (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( hasFocus() ) - return; - - FWidget* focused_widget = getFocusWidget(); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - - redraw(); - - if ( statusBar() ) - { - statusBar()->drawMessage(); - updateTerminal(); - flush_out(); - } -} - -//---------------------------------------------------------------------- -void FToggleButton::onMouseUp (FMouseEvent* ev) -{ - if ( ev->getButton() != fc::LeftButton ) - return; - - if ( ! getTermGeometry().contains(ev->getTermPos()) ) - return; - - if ( isRadioButton() ) - { - if ( ! checked ) - { - checked = true; - processToggle(); - } - } - else - { - checked = not checked; - processToggle(); - } - - redraw(); - processClick(); -} - -//---------------------------------------------------------------------- -void FToggleButton::onAccel (FAccelEvent* ev) -{ - if ( ! isEnabled() ) - return; - - if ( ! hasFocus() ) - { - FWidget* focused_widget = static_cast(ev->focusedWidget()); - FFocusEvent out (fc::FocusOut_Event); - FApplication::queueEvent(focused_widget, &out); - setFocus(); - - if ( focused_widget ) - focused_widget->redraw(); - } - - if ( isRadioButton() ) - { - if ( ! checked ) - { - checked = true; - processToggle(); - } - } - else - { - checked = not checked; - processToggle(); - } - - redraw(); - - if ( statusBar() ) - { - statusBar()->drawMessage(); - updateTerminal(); - flush_out(); - } - - processClick(); - ev->accept(); -} - -//---------------------------------------------------------------------- -void FToggleButton::onFocusIn (FFocusEvent*) -{ - if ( statusBar() ) - statusBar()->drawMessage(); -} - -//---------------------------------------------------------------------- -void FToggleButton::onFocusOut (FFocusEvent* out_ev) -{ - if ( statusBar() ) - { - statusBar()->clearMessage(); - statusBar()->drawMessage(); - } - - if ( ! group() ) - return; - - if ( ! focus_inside_group && isRadioButton() ) - { - focus_inside_group = true; - out_ev->ignore(); - - if ( out_ev->getFocusType() == fc::FocusNextWidget ) - group()->focusNextChild(); - - if ( out_ev->getFocusType() == fc::FocusPreviousWidget ) - group()->focusPrevChild(); - - redraw(); - } - else if ( this == group()->getLastButton() - && out_ev->getFocusType() == fc::FocusNextWidget ) - { - out_ev->ignore(); - group()->focusNextChild(); - redraw(); - } - else if ( this == group()->getFirstButton() - && out_ev->getFocusType() == fc::FocusPreviousWidget ) - { - out_ev->ignore(); - group()->focusPrevChild(); - redraw(); - } -} - -//---------------------------------------------------------------------- -bool FToggleButton::setChecked (bool on) -{ - if ( checked != on ) - { - checked = on; - processToggle(); - } - - return checked; -} - -//---------------------------------------------------------------------- -void FToggleButton::setText (FString txt) -{ - text = txt; - setWidth(button_width + int(text.getLength())); - - if ( isEnabled() ) - { - delAccelerator(); - setHotkeyAccelerator(); + setForegroundColor (wc.label_inactive_fg); + setBackgroundColor (wc.label_inactive_bg); } } diff --git a/src/ftogglebutton.h b/src/ftogglebutton.h index ef591cf5..ec4ceacf 100644 --- a/src/ftogglebutton.h +++ b/src/ftogglebutton.h @@ -43,75 +43,97 @@ class FButtonGroup; class FToggleButton : public FWidget { - private: - bool focus_inside_group; + public: + // Using-declaration + using FWidget::setGeometry; + + // Constructors + explicit FToggleButton (FWidget* = 0); + FToggleButton (const FString&, FWidget* = 0); + + // Destructor + virtual ~FToggleButton(); + + // Accessors + virtual const char* getClassName() const; + FString& getText(); + + // Mutators + void setGeometry (int, int, int, int, bool = true); + bool setNoUnderline (bool); + bool setNoUnderline(); + bool unsetNoUnderline(); + bool setEnable (bool); + bool setEnable(); + bool unsetEnable(); + bool setDisable(); + bool setFocus (bool); + bool setFocus(); + bool unsetFocus(); + bool setChecked (bool); + bool setChecked(); + bool unsetChecked(); + virtual void setText (const FString); + + // Inquiries + bool isChecked(); + + // Methods + void hide(); + + // Event handlers + void onMouseDown (FMouseEvent*); + void onMouseUp (FMouseEvent*); + void onAccel (FAccelEvent*); + void onFocusIn (FFocusEvent*); + void onFocusOut (FFocusEvent*); protected: - FString text; + // Accessor + uChar getHotkey(); + FButtonGroup* getGroup() const; + + // Mutator + void setHotkeyAccelerator(); + + // Inquiries + bool isRadioButton() const; + bool isCheckboxButton() const; + + // Methods + virtual void draw(); + void drawLabel(); + void processClick(); + void processToggle(); + + // Event handler + virtual void onKeyPress (FKeyEvent*); + + // Data Members bool checked; int label_offset_pos; int button_width; // plus margin spaces - FButtonGroup* button_group; private: // Disable copy constructor FToggleButton (const FToggleButton&); + // Disable assignment operator (=) FToggleButton& operator = (const FToggleButton&); - void init(); + // Mutator + void setGroup (FButtonGroup*); + + // Methods + void init(); + + // Friend classes friend class FButtonGroup; - void setGroup (FButtonGroup*); - protected: - virtual void draw(); - uChar getHotkey(); - void setHotkeyAccelerator(); - void drawLabel(); - void processClick(); - void processToggle(); - FButtonGroup* group() const; - bool isRadioButton() const; - bool isCheckboxButton() const; - virtual void onKeyPress (FKeyEvent*); - - public: - // Constructors - explicit FToggleButton (FWidget* = 0); - FToggleButton (const FString&, FWidget* = 0); - // Destructor - virtual ~FToggleButton(); - - virtual const char* getClassName() const; - void hide(); - // make every setGeometry from FWidget available - using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - - // Event handlers - void onMouseDown (FMouseEvent*); - void onMouseUp (FMouseEvent*); - void onAccel (FAccelEvent*); - void onFocusIn (FFocusEvent*); - void onFocusOut (FFocusEvent*); - - bool setNoUnderline (bool); - bool setNoUnderline(); - bool unsetNoUnderline(); - bool setEnable (bool); - bool setEnable(); - bool unsetEnable(); - bool setDisable(); - bool setFocus (bool); - bool setFocus(); - bool unsetFocus(); - bool setChecked (bool); - bool setChecked(); - bool unsetChecked(); - bool isChecked(); - - virtual void setText (const FString); - FString& getText(); + // Data Members + FButtonGroup* button_group; + bool focus_inside_group; + FString text; }; #pragma pack(pop) @@ -121,6 +143,10 @@ class FToggleButton : public FWidget inline const char* FToggleButton::getClassName() const { return "FToggleButton"; } +//---------------------------------------------------------------------- +inline FString& FToggleButton::getText() +{ return text; } + //---------------------------------------------------------------------- inline bool FToggleButton::setNoUnderline() { return setNoUnderline(true); } @@ -162,7 +188,7 @@ inline bool FToggleButton::isChecked() { return checked; } //---------------------------------------------------------------------- -inline FString& FToggleButton::getText() -{ return text; } +inline FButtonGroup* FToggleButton::getGroup() const +{ return button_group; } #endif // _FTOGGLEBUTTON_H diff --git a/src/ftooltip.cpp b/src/ftooltip.cpp index 7ace7232..5cc20f36 100644 --- a/src/ftooltip.cpp +++ b/src/ftooltip.cpp @@ -54,6 +54,73 @@ FToolTip::~FToolTip() // destructor } +// public methods of FToolTip +//---------------------------------------------------------------------- +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); +} + +//---------------------------------------------------------------------- +void FToolTip::draw() +{ + updateVTerm(false); + setColor(); + + if ( getMaxColor() < 16 ) + setBold(); + + clearArea (vwin); + drawBorder(); + + for (int i=0; i < int(text_num_lines); i++) + { + setPrintPos (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(); +} + + // private methods of FToolTip //---------------------------------------------------------------------- void FToolTip::init() @@ -106,70 +173,3 @@ void FToolTip::adjustSize() calculateDimensions(); FWindow::adjustSize(); } - - -// public methods of FToolTip -//---------------------------------------------------------------------- -void FToolTip::draw() -{ - updateVTerm(false); - setColor(); - - if ( getMaxColor() < 16 ) - setBold(); - - clearArea (vwin); - drawBorder(); - - for (int i=0; i < int(text_num_lines); i++) - { - setPrintPos (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 index 1fe66ee8..202f47e3 100644 --- a/src/ftooltip.h +++ b/src/ftooltip.h @@ -45,40 +45,52 @@ 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 (); + // Accessors const char* getClassName() const; - virtual void draw(); - void show(); - void hide(); - // Event handler - void onMouseDown (FMouseEvent*); const FString getText() const; + + // Mutators void setText (const FString&); void setText (const std::string&); void setText (const char*); + + // Methods + virtual void draw(); + void show(); + void hide(); + + // Event handler + void onMouseDown (FMouseEvent*); + + private: + // Typedef + typedef std::vector textLines; + + // Disable copy constructor + FToolTip (const FToolTip&); + + // Disable assignment operator (=) + FToolTip& operator = (const FToolTip&); + + // Methods + void init(); + void calculateDimensions(); + virtual void adjustSize(); + + // Data Members + FString text; + FString* text_components; + textLines text_split; + uInt max_line_width; + uInt text_num_lines; }; #pragma pack(pop) diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 8a8d83cb..9f1339a0 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -23,9 +23,10 @@ FVTerm::term_area* FVTerm::vterm = 0; FVTerm::term_area* FVTerm::vdesktop = 0; FVTerm::term_area* FVTerm::last_area = 0; FVTerm::term_area* FVTerm::active_area = 0; -FTermcap::tcap_map* FVTerm::tcap = 0; -FOptiAttr::char_data FVTerm::term_attribute; -FOptiAttr::char_data FVTerm::next_attribute; +FVTerm::termcap_map* FVTerm::tcap = 0; +FTermcap::tcap_map* FTermcap::tcap = 0; +FVTerm::char_data FVTerm::term_attribute; +FVTerm::char_data FVTerm::next_attribute; //---------------------------------------------------------------------- @@ -57,1246 +58,18 @@ FVTerm::~FVTerm() // destructor } } + +// public methods of FVTerm //---------------------------------------------------------------------- -void FVTerm::init() +FPoint FVTerm::getPrintCursor() { - init_object = this; - vterm = 0; - vdesktop = 0; - last_area = 0; - term_pos = new FPoint(-1,-1); - output_buffer = new std::queue; + term_area* win = getPrintArea(); - // Preset to false - hidden_cursor = \ - terminal_update_pending = \ - force_terminal_update = \ - stop_terminal_updates = false; + if ( win ) + return FPoint ( win->x_offset + win->cursor_x + , win->y_offset + win->cursor_y ); - // term_attribute stores the current state of the terminal - term_attribute.code = '\0'; - term_attribute.fg_color = fc::Default; - term_attribute.bg_color = fc::Default; - term_attribute.bold = \ - term_attribute.dim = \ - term_attribute.italic = \ - term_attribute.underline = \ - term_attribute.blink = \ - term_attribute.reverse = \ - term_attribute.standout = \ - term_attribute.invisible = \ - term_attribute.protect = \ - term_attribute.crossed_out = \ - term_attribute.dbl_underline = \ - term_attribute.alt_charset = \ - term_attribute.pc_charset = \ - term_attribute.transparent = \ - term_attribute.trans_shadow = \ - term_attribute.inherit_bg = false; - - // next_attribute contains the state of the next printed character - std::memcpy (&next_attribute, &term_attribute, sizeof(FOptiAttr::char_data)); - - // receive the terminal capabilities - tcap = FTermcap().getTermcapMap(); - - // create virtual terminal - FRect term_geometry (0, 0, getColumnNumber(), getLineNumber()); - createVTerm (term_geometry); - - // create virtual desktop area - FPoint shadow_size(0,0); - createArea (term_geometry, shadow_size, vdesktop); - vdesktop->visible = true; - active_area = vdesktop; - - // Hide the input cursor - hideCursor(); -} - -//---------------------------------------------------------------------- -void FVTerm::finish() -{ - // Show the input cursor - showCursor(); - - if ( output_buffer ) - delete output_buffer; - - // remove virtual terminal + virtual desktop area - removeArea (vdesktop); - removeArea (vterm); - - if ( term_pos ) - delete term_pos; -} - -//---------------------------------------------------------------------- -FVTerm::term_area* FVTerm::getPrintArea() -{ - // returns the print area of this object - if ( print_area ) - return print_area; - else - { - FVTerm* obj = static_cast(this); - FVTerm* p_obj = static_cast(obj->getParent()); - - while ( ! obj->vwin && p_obj ) - { - obj = p_obj; - p_obj = static_cast(p_obj->getParent()); - } - - if ( obj->vwin ) - { - print_area = obj->vwin; - return print_area; - } - } - - return vdesktop; -} - -//---------------------------------------------------------------------- -void FVTerm::createArea ( const FRect& r - , const FPoint& p - , FVTerm::term_area*& area ) -{ - createArea ( r.getX() - , r.getY() - , r.getWidth() - , r.getHeight() - , p.getX() - , p.getY() - , area ); -} - -//---------------------------------------------------------------------- -void FVTerm::createArea ( int x_offset, int y_offset - , int width, int height - , int rsw, int bsh - , term_area*& area ) -{ - // initialize virtual window - area = new term_area; - - area->x_offset = 0; - area->y_offset = 0; - area->width = -1; - area->height = -1; - area->right_shadow = 0; - area->bottom_shadow = 0; - area->cursor_x = 0; - area->cursor_y = 0; - area->input_cursor_x = -1; - area->input_cursor_y = -1; - area->input_cursor_visible = false; - area->changes = 0; - area->text = 0; - area->visible = false; - area->widget = static_cast(this); - - resizeArea (x_offset, y_offset, width, height, rsw, bsh, area); -} - -//---------------------------------------------------------------------- -void FVTerm::resizeArea ( const FRect& r - , const FPoint& p - , FVTerm::term_area* area ) -{ - resizeArea ( r.getX() - , r.getY() - , r.getWidth() - , r.getHeight() - , p.getX() - , p.getY() - , area ); -} - -//---------------------------------------------------------------------- -void FVTerm::resizeArea ( int x_offset, int y_offset - , int width, int height - , int rsw, int bsh - , term_area* area ) -{ - int area_size; - FOptiAttr::char_data default_char; - line_changes unchanged; - - if ( ! area ) - return; - - area_size = (width+rsw) * (height+bsh); - - if ( area->height + area->bottom_shadow != height + bsh ) - { - if ( area->changes != 0 ) - delete[] area->changes; - - if ( area->text != 0 ) - delete[] area->text; - - area->changes = new line_changes[height + bsh]; - area->text = new FOptiAttr::char_data[area_size]; - } - else if ( area->width + area->right_shadow != width + rsw ) - { - if ( area->text != 0 ) - delete[] area->text; - - area->text = new FOptiAttr::char_data[area_size]; - } - else - return; - - area->x_offset = x_offset; - area->y_offset = y_offset; - area->width = width; - area->height = height; - area->right_shadow = rsw; - area->bottom_shadow = bsh; - - default_char.code = ' '; - default_char.fg_color = fc::Default; - default_char.bg_color = fc::Default; - default_char.bold = 0; - default_char.dim = 0; - default_char.italic = 0; - default_char.underline = 0; - default_char.blink = 0; - default_char.reverse = 0; - default_char.standout = 0; - default_char.invisible = 0; - default_char.protect = 0; - default_char.crossed_out = 0; - default_char.dbl_underline = 0; - default_char.alt_charset = 0; - default_char.pc_charset = 0; - default_char.transparent = 0; - default_char.trans_shadow = 0; - default_char.inherit_bg = 0; - - std::fill_n (area->text, area_size, default_char); - - unchanged.xmin = uInt(width+rsw); - unchanged.xmax = 0; - unchanged.trans_count = 0; - - std::fill_n (area->changes, height+bsh, unchanged); -} - -//---------------------------------------------------------------------- -void FVTerm::removeArea (term_area*& area) -{ - // remove the virtual window - if ( area != 0 ) - { - if ( area->changes != 0 ) - { - delete[] area->changes; - area->changes = 0; - } - - if ( area->text != 0 ) - { - delete[] area->text; - area->text = 0; - } - - delete area; - area = 0; - } -} - -//---------------------------------------------------------------------- -void FVTerm::restoreVTerm (const FRect& box) -{ - restoreVTerm ( box.getX() - , box.getY() - , box.getWidth() - , box.getHeight() ); -} - -//---------------------------------------------------------------------- -void FVTerm::restoreVTerm (int x, int y, int w, int h) -{ - FOptiAttr::char_data* tc; // terminal character - FOptiAttr::char_data* sc; // shown character - FOptiAttr::char_data s_ch; // shadow character - FOptiAttr::char_data i_ch; // inherit background character - FWidget* widget; - - x--; - y--; - - if ( x < 0 ) - x = 0; - - if ( y < 0 ) - y = 0; - - if ( w < 0 || h < 0 ) - return; - - if ( x+w > vterm->width ) - w = vterm->width - x; - - if ( w < 0 ) - return; - - if ( y+h > vterm->height ) - h = vterm->height - y; - - if ( h < 0 ) - return; - - widget = static_cast(vterm->widget); - - for (register int ty=0; ty < h; ty++) - { - for (register int tx=0; tx < w; tx++) - { - tc = &vterm->text[(y+ty) * vterm->width + (x+tx)]; - sc = &vdesktop->text[(y+ty) * vdesktop->width + (x+tx)]; - - if ( widget->window_list && ! widget->window_list->empty() ) - { - FWidget::widgetList::const_iterator iter, end; - iter = widget->window_list->begin(); - end = widget->window_list->end(); - - for (; iter != end; ++iter) - { - term_area* win = (*iter)->getVWin(); - - if ( ! win ) - continue; - - if ( ! win->visible ) - continue; - - int win_x = win->x_offset; - int win_y = win->y_offset; - FRect geometry ( win_x - , win_y - , win->width + win->right_shadow - , win->height + win->bottom_shadow ); - - // window visible and contains current character - if ( geometry.contains(tx+x, ty+y) ) - { - FOptiAttr::char_data* tmp; - int line_len = win->width + win->right_shadow; - tmp = &win->text[(ty+y-win_y) * line_len + (tx+x-win_x)]; - - if ( ! tmp->transparent ) // current character not transparent - { - if ( tmp->trans_shadow ) // transparent shadow - { - // keep the current vterm character - std::memcpy (&s_ch, sc, sizeof(FOptiAttr::char_data)); - s_ch.fg_color = tmp->fg_color; - s_ch.bg_color = tmp->bg_color; - s_ch.reverse = false; - s_ch.standout = false; - - if ( s_ch.code == fc::LowerHalfBlock - || s_ch.code == fc::UpperHalfBlock - || s_ch.code == fc::LeftHalfBlock - || s_ch.code == fc::RightHalfBlock - || s_ch.code == fc::FullBlock ) - s_ch.code = ' '; - - sc = &s_ch; - } - else if ( tmp->inherit_bg ) - { - // add the covered background to this character - std::memcpy (&i_ch, tmp, sizeof(FOptiAttr::char_data)); - i_ch.bg_color = sc->bg_color; // last background color; - sc = &i_ch; - } - else // default - sc = tmp; - } - } - } - } - - std::memcpy (tc, sc, sizeof(FOptiAttr::char_data)); - - if ( short(vterm->changes[y+ty].xmin) > x ) - vterm->changes[y+ty].xmin = uInt(x); - - if ( short(vterm->changes[y+ty].xmax) < x+w-1 ) - vterm->changes[y+ty].xmax = uInt(x+w-1); - } - } -} - -//---------------------------------------------------------------------- -FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos - , FVTerm::term_area* area ) -{ - return isCovered (pos.getX(), pos.getY(), area); -} - -//---------------------------------------------------------------------- -FVTerm::covered_state FVTerm::isCovered ( int x, int y - , FVTerm::term_area* area ) -{ - bool found; - FVTerm::covered_state is_covered; - FWidget* w; - - if ( ! area ) - return non_covered; - - is_covered = non_covered; - found = bool(area == vdesktop); - - w = static_cast(area->widget); - - if ( w->window_list && ! w->window_list->empty() ) - { - FWidget::widgetList::const_iterator iter, end; - iter = w->window_list->begin(); - end = w->window_list->end(); - - for (; iter != end; ++iter) - { - term_area* win = (*iter)->getVWin(); - - if ( ! win ) - continue; - - if ( ! win->visible ) - continue; - - int win_x = win->x_offset; - int win_y = win->y_offset; - FRect geometry ( win_x - , win_y - , win->width + win->right_shadow - , win->height + win->bottom_shadow ); - - if ( found && geometry.contains(x,y) ) - { - FOptiAttr::char_data* tmp; - int line_len = win->width + win->right_shadow; - tmp = &win->text[(y-win_y) * line_len + (x-win_x)]; - - if ( tmp->trans_shadow ) - { - is_covered = half_covered; - } - else if ( ! tmp->transparent ) - { - is_covered = fully_covered; - break; - } - } - - if ( area == win ) - found = true; - } - } - - return is_covered; -} - -//---------------------------------------------------------------------- -void FVTerm::updateVTerm (bool on) -{ - vterm_updates = on; - - if ( on ) - updateVTerm (last_area); -} - -//---------------------------------------------------------------------- -void FVTerm::updateVTerm (FVTerm::term_area* area) -{ - int ax, ay, aw, ah, rsh, bsh, y_end, ol; - FOptiAttr::char_data* tc; // terminal character - FOptiAttr::char_data* ac; // area character - bool modified = false; - - if ( ! vterm_updates ) - { - last_area = area; - return; - } - - if ( ! area ) - return; - - if ( ! area->visible ) - return; - - ax = area->x_offset; - ay = area->y_offset; - aw = area->width; - ah = area->height; - rsh = area->right_shadow; - bsh = area->bottom_shadow; - ol = 0; // outside left - - if ( ax < 0 ) - { - ol = std::abs(ax); - ax = 0; - } - - if ( ah + bsh + ay > vterm->height ) - y_end = vterm->height - ay; - else - y_end = ah + bsh; - - for (register int y=0; y < y_end; y++) // line loop - { - int line_xmin = int(area->changes[y].xmin); - int line_xmax = int(area->changes[y].xmax); - - if ( line_xmin <= line_xmax ) - { - int _xmin, _xmax; - - if ( ax == 0 ) - line_xmin = ol; - - if ( aw + rsh + ax - ol >= vterm->width ) - line_xmax = vterm->width + ol - ax - 1; - - if ( ax + line_xmin >= vterm->width ) - continue; - - for (register int x=line_xmin; x <= line_xmax; x++) // column loop - { - int gx, gy, line_len; - FVTerm::covered_state is_covered; - // global terminal positions - gx = ax + x; - gy = ay + y; - - if ( gx < 0 || gy < 0 ) - continue; - - line_len = aw + rsh; - ac = &area->text[y * line_len + x]; - tc = &vterm->text[gy * vterm->width + gx - ol]; - is_covered = isCovered(gx-ol, gy, area); // get covered state - - if ( is_covered != fully_covered ) - { - if ( is_covered == half_covered ) - { - // add the overlapping color to this character - FOptiAttr::char_data ch, oc; - std::memcpy (&ch, ac, sizeof(FOptiAttr::char_data)); - oc = getOverlappedCharacter (gx+1 - ol, gy+1, area->widget); - ch.fg_color = oc.fg_color; - ch.bg_color = oc.bg_color; - ch.reverse = false; - ch.standout = false; - - if ( ch.code == fc::LowerHalfBlock - || ch.code == fc::UpperHalfBlock - || ch.code == fc::LeftHalfBlock - || ch.code == fc::RightHalfBlock - || ch.code == fc::FullBlock ) - ch.code = ' '; - - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else if ( ac->transparent ) // transparent - { - // restore one character on vterm - FOptiAttr::char_data ch; - ch = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else // not transparent - { - if ( ac->trans_shadow ) // transparent shadow - { - // get covered character + add the current color - FOptiAttr::char_data ch; - ch = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); - ch.fg_color = ac->fg_color; - ch.bg_color = ac->bg_color; - ch.reverse = false; - ch.standout = false; - - if ( ch.code == fc::LowerHalfBlock - || ch.code == fc::UpperHalfBlock - || ch.code == fc::LeftHalfBlock - || ch.code == fc::RightHalfBlock - || ch.code == fc::FullBlock ) - ch.code = ' '; - - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else if ( ac->inherit_bg ) - { - // add the covered background to this character - FOptiAttr::char_data ch, cc; - std::memcpy (&ch, ac, sizeof(FOptiAttr::char_data)); - cc = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); - ch.bg_color = cc.bg_color; - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else // default - std::memcpy (tc, ac, sizeof(FOptiAttr::char_data)); - } - - modified = true; - } - else if ( ! modified ) - line_xmin++; // don't update covered character - } - - _xmin = ax + line_xmin - ol; - _xmax = ax + line_xmax; - - if ( _xmin < short(vterm->changes[ay+y].xmin) ) - vterm->changes[ay+y].xmin = uInt(_xmin); - - if ( _xmax >= vterm->width ) - _xmax = vterm->width - 1; - - if ( _xmax > short(vterm->changes[ay+y].xmax) ) - vterm->changes[ay+y].xmax = uInt(_xmax); - - area->changes[y].xmin = uInt(aw + rsh); - area->changes[y].xmax = 0; - } - } - - updateVTermCursor(area); -} - -//---------------------------------------------------------------------- -bool FVTerm::updateVTermCursor (FVTerm::term_area* area) -{ - if ( ! area ) - return false; - - if ( area != active_area ) - return false; - - if ( ! area->visible ) - return false; - - if ( area->input_cursor_visible ) - { - int cx, cy, ax, ay, x, y; - // area offset - ax = area->x_offset; - ay = area->y_offset; - // area cursor position - cx = area->input_cursor_x; - cy = area->input_cursor_y; - // terminal position - x = ax + cx; - y = ay + cy; - - if ( isInsideArea(cx, cy, area) - && isInsideTerminal(x, y) - && isCovered(x, y, area) == non_covered ) - { - vterm->input_cursor_x = x; - vterm->input_cursor_y = y; - vterm->input_cursor_visible = true; - return true; - } - } - - vterm->input_cursor_visible = false; - return false; -} - -//---------------------------------------------------------------------- -bool FVTerm::isInsideArea (int x, int y, FVTerm::term_area* area) -{ - // Check whether the coordinates are within the area - int ax, ay, aw, ah; - ax = 0; - ay = 0; - aw = area->width; - ah = area->height; - FRect area_geometry(ax, ay, aw, ah); - - if ( area_geometry.contains(x,y) ) - return true; - else - return false; -} - -//---------------------------------------------------------------------- -void FVTerm::setAreaCursor ( const FPoint& pos - , bool visible - , FVTerm::term_area* area ) -{ - setAreaCursor (pos.getX(), pos.getY(), visible, area); -} - -//---------------------------------------------------------------------- -void FVTerm::setAreaCursor ( int x, int y - , bool visible - , FVTerm::term_area* area ) -{ - if ( ! area ) - return; - - area->input_cursor_x = x - 1; - area->input_cursor_y = y - 1; - area->input_cursor_visible = visible; - updateVTerm (area); -} - -//---------------------------------------------------------------------- -void FVTerm::getArea (const FPoint& pos, FVTerm::term_area* area) -{ - return getArea (pos.getX(), pos.getY(), area); -} - -//---------------------------------------------------------------------- -void FVTerm::getArea (int ax, int ay, FVTerm::term_area* area) -{ - // Copies a block from the virtual terminal position to the given area - int y_end; - int length; - FOptiAttr::char_data* tc; // terminal character - FOptiAttr::char_data* ac; // area character - - if ( ! area ) - return; - - ax--; - ay--; - - if ( area->height+ay > vterm->height ) - y_end = area->height - ay; - else - y_end = area->height; - - if ( area->width+ax > vterm->width ) - length = vterm->width - ax; - else - length = area->width; - - for (int y=0; y < y_end; y++) // line loop - { - tc = &vterm->text[(ay+y) * vterm->width + ax]; - ac = &area->text[y * area->width]; - std::memcpy (ac, tc, sizeof(FOptiAttr::char_data) * unsigned(length)); - - if ( short(area->changes[y].xmin) > 0 ) - area->changes[y].xmin = 0; - - if ( short(area->changes[y].xmax) < length-1 ) - area->changes[y].xmax = uInt(length-1); - } -} - -//---------------------------------------------------------------------- -void FVTerm::getArea (const FRect& box, FVTerm::term_area* area) -{ - getArea ( box.getX() - , box.getY() - , box.getWidth() - , box.getHeight() - , area ); -} - -//---------------------------------------------------------------------- -void FVTerm::getArea (int x, int y, int w, int h, FVTerm::term_area* area) -{ - // Copies a block from the virtual terminal rectangle to the given area - int y_end, length, dx, dy; - FOptiAttr::char_data* tc; // terminal character - FOptiAttr::char_data* ac; // area character - - if ( ! area ) - return; - - dx = x - area->x_offset + 1; - dy = y - area->y_offset + 1; - - if ( x < 0 || y < 0 ) - return; - - if ( y-1+h > vterm->height ) - y_end = vterm->height - y + 1; - else - y_end = h - 1; - - if ( x-1+w > vterm->width ) - length = vterm->width - x + 1; - else - length = w; - - if ( length < 1 ) - return; - - for (int _y=0; _y < y_end; _y++) // line loop - { - int line_len = area->width + area->right_shadow; - tc = &vterm->text[(y+_y-1) * vterm->width + x-1]; - ac = &area->text[(dy+_y) * line_len + dx]; - std::memcpy (ac, tc, sizeof(FOptiAttr::char_data) * unsigned(length)); - - if ( short(area->changes[dy+_y].xmin) > dx ) - area->changes[dy+_y].xmin = uInt(dx); - - if ( short(area->changes[dy+_y].xmax) < dx+length-1 ) - area->changes[dy+_y].xmax = uInt(dx+length-1); - } -} - -//---------------------------------------------------------------------- -void FVTerm::putArea (const FPoint& pos, FVTerm::term_area* area) -{ - // Copies the given area block to the virtual terminal position - if ( ! area ) - return; - - if ( ! area->visible ) - return; - - putArea (pos.getX(), pos.getY(), area); -} - -//---------------------------------------------------------------------- -void FVTerm::putArea (int ax, int ay, FVTerm::term_area* area) -{ - // Copies the given area block to the virtual terminal position - int aw, ah, rsh, bsh, y_end, length, ol; - FOptiAttr::char_data* tc; // terminal character - FOptiAttr::char_data* ac; // area character - - if ( ! area ) - return; - - if ( ! area->visible ) - return; - - ax--; - ay--; - aw = area->width; - ah = area->height; - rsh = area->right_shadow; - bsh = area->bottom_shadow; - ol = 0; // outside left - - if ( ax < 0 ) - { - ol = std::abs(ax); - ax = 0; - } - - if ( ay + ah + bsh > vterm->height ) - y_end = vterm->height - ay; - else - y_end = ah + bsh; - - if ( aw + rsh - ol + ax > vterm->width ) - length = vterm->width - ax; - else - length = aw + rsh - ol; - - if ( length < 1 ) - return; - - for (register int y=0; y < y_end; y++) // line loop - { - int line_len = aw + rsh; - - if ( area->changes[y].trans_count == 0 ) - { - // Line has only covered characters - tc = &vterm->text[(ay+y) * vterm->width + ax]; - ac = &area->text[y * line_len + ol]; - std::memcpy (tc, ac, sizeof(FOptiAttr::char_data) * unsigned(length)); - } - else - { - // Line has one or more transparent characters - for (register int x=0; x < length; x++) // column loop - { - tc = &vterm->text[(ay+y) * vterm->width + (ax+x)]; - ac = &area->text[y * line_len + ol + x]; - - if ( ac->transparent ) // transparent - { - // restore one character on vterm - FOptiAttr::char_data ch; - ch = getCoveredCharacter (ax+x+1, ay+y+1, area->widget); - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else // not transparent - { - if ( ac->trans_shadow ) // transparent shadow - { - // get covered character + add the current color - FOptiAttr::char_data ch; - ch = getCoveredCharacter (ax+x+1, ay+y+1, area->widget); - ch.fg_color = ac->fg_color; - ch.bg_color = ac->bg_color; - ch.reverse = false; - ch.standout = false; - - if ( ch.code == fc::LowerHalfBlock - || ch.code == fc::UpperHalfBlock - || ch.code == fc::LeftHalfBlock - || ch.code == fc::RightHalfBlock - || ch.code == fc::FullBlock ) - ch.code = ' '; - - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else if ( ac->inherit_bg ) - { - // add the covered background to this character - FOptiAttr::char_data ch, cc; - std::memcpy (&ch, ac, sizeof(FOptiAttr::char_data)); - cc = getCoveredCharacter (ax+x+1, ay+y+1, area->widget); - ch.bg_color = cc.bg_color; - std::memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); - } - else // default - std::memcpy (tc, ac, sizeof(FOptiAttr::char_data)); - } - } - } - - if ( ax < short(vterm->changes[ay+y].xmin) ) - vterm->changes[ay+y].xmin = uInt(ax); - - if ( ax+length-1 > short(vterm->changes[ay+y].xmax) ) - vterm->changes[ay+y].xmax = uInt(ax+length-1); - } -} - -//---------------------------------------------------------------------- -void FVTerm::scrollAreaForward (FVTerm::term_area* area) -{ - // Scrolls the entire area up line down - int total_width; - int length; - int y_max; - FOptiAttr::char_data nc; // next character - FOptiAttr::char_data* lc; // last character - FOptiAttr::char_data* sc; // source character - FOptiAttr::char_data* dc; // destination character - - if ( ! area ) - return; - - if ( area->height <= 1 ) - return; - - length = area->width; - total_width = area->width + area->right_shadow; - y_max = area->height - 1; - - for (int y=0; y < y_max; y++) - { - int pos1 = y * total_width; - int pos2 = (y+1) * total_width; - sc = &area->text[pos2]; - dc = &area->text[pos1]; - std::memcpy (dc, sc, sizeof(FOptiAttr::char_data) * unsigned(length)); - area->changes[y].xmin = 0; - area->changes[y].xmax = uInt(area->width - 1); - } - - // insert a new line below - lc = &area->text[(y_max * total_width) - area->right_shadow - 1]; - std::memcpy (&nc, lc, sizeof(FOptiAttr::char_data)); - nc.code = ' '; - dc = &area->text[y_max * total_width]; - std::fill_n (dc, area->width, nc); - area->changes[y_max].xmin = 0; - area->changes[y_max].xmax = uInt(area->width - 1); -} - -//---------------------------------------------------------------------- -void FVTerm::scrollAreaReverse (FVTerm::term_area* area) -{ - // Scrolls the entire area one line down - int total_width; - int length; - FOptiAttr::char_data nc; // next character - FOptiAttr::char_data* lc; // last character - FOptiAttr::char_data* sc; // source character - FOptiAttr::char_data* dc; // destination character - - if ( ! area ) - return; - - if ( area->height <= 1 ) - return; - - length = area->width; - total_width = area->width + area->right_shadow; - - for (int y=area->height-1; y > 0; y--) - { - int pos1 = (y-1) * total_width; - int pos2 = y * total_width; - sc = &area->text[pos1]; - dc = &area->text[pos2]; - std::memcpy (dc, sc, sizeof(FOptiAttr::char_data) * unsigned(length)); - area->changes[y].xmin = 0; - area->changes[y].xmax = uInt(area->width - 1); - } - - // insert a new line above - lc = &area->text[total_width]; - std::memcpy (&nc, lc, sizeof(FOptiAttr::char_data)); - nc.code = ' '; - dc = &area->text[0]; - std::fill_n (dc, area->width, nc); - area->changes[0].xmin = 0; - area->changes[0].xmax = uInt(area->width - 1); -} - -//---------------------------------------------------------------------- -void FVTerm::clearArea (FVTerm::term_area* area) -{ - // clear the area with the current attributes - FOptiAttr::char_data nc; // next character - int total_width; - uInt w; - - // current attributes with a space character - std::memcpy (&nc, &next_attribute, sizeof(FOptiAttr::char_data)); - nc.code = ' '; - - if ( ! area ) - return; - - total_width = area->width + area->right_shadow; - w = uInt(total_width); - - if ( area->right_shadow == 0 ) - { - int area_size = area->width * area->height; - std::fill_n (area->text, area_size, nc); - } - else - { - FOptiAttr::char_data t_char = nc; - t_char.transparent = true; - - for (int y=0; y < area->height; y++) - { - int pos = y * total_width; - std::fill_n (&area->text[pos], total_width, nc); - std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char); - } - - for (int y=0; y < area->bottom_shadow; y++) - { - int pos = total_width * (y + area->height); - std::fill_n (&area->text[pos], total_width, t_char); - } - } - - for (int i=0; i < area->height; i++) - { - - area->changes[i].xmin = 0; - area->changes[i].xmax = w - 1; - - if ( nc.transparent - || nc.trans_shadow - || nc.inherit_bg ) - area->changes[i].trans_count = w; - else if ( area->right_shadow != 0 ) - area->changes[i].trans_count = uInt(area->right_shadow); - else - area->changes[i].trans_count = 0; - } - - for (int i=0; i < area->bottom_shadow; i++) - { - int y = area->height + i; - area->changes[y].xmin = 0; - area->changes[y].xmax = w - 1; - area->changes[y].trans_count = w; - } - - updateVTerm (area); -} - -//---------------------------------------------------------------------- -FOptiAttr::char_data FVTerm::getCharacter ( character_type type - , const FPoint& pos - , FVTerm* obj ) -{ - // Gets the overlapped or the covered character for a given position - return getCharacter (type, pos.getX(), pos.getY(), obj); -} - -//---------------------------------------------------------------------- -FOptiAttr::char_data FVTerm::getCharacter ( character_type char_type - , int x - , int y - , FVTerm* obj ) -{ - // Gets the overlapped or the covered character for the position (x,y) - int xx, yy; - FOptiAttr::char_data* cc; // covered character - FOptiAttr::char_data s_ch; // shadow character - FOptiAttr::char_data i_ch; // inherit background character - FWidget* w; - - x--; - y--; - xx = x; - yy = y; - - if ( xx < 0 ) - xx = 0; - - if ( yy < 0 ) - yy = 0; - - if ( xx >= vterm->width ) - xx = vterm->width - 1; - - if ( yy >= vterm->height ) - yy = vterm->height - 1; - - cc = &vdesktop->text[yy * vdesktop->width + xx]; - w = static_cast(obj); - - if ( w->window_list && ! w->window_list->empty() ) - { - FWidget::widgetList::const_iterator iter, end; - // get the window layer of this object - int layer = FWindow::getWindowLayer(w); - iter = w->window_list->begin(); - end = w->window_list->end(); - - for (; iter != end; ++iter) - { - bool significant_char; - - // char_type can be "overlapped_character" - // or "covered_character" - if ( char_type == covered_character ) - significant_char = bool(layer >= FWindow::getWindowLayer(*iter)); - else - significant_char = bool(layer < FWindow::getWindowLayer(*iter)); - - if ( obj && *iter != obj && significant_char ) - { - term_area* win = (*iter)->getVWin(); - - if ( ! win ) - continue; - - if ( ! win->visible ) - continue; - - int win_x = win->x_offset; - int win_y = win->y_offset; - FRect geometry ( win_x - , win_y - , win->width + win->right_shadow - , win->height + win->bottom_shadow ); - - // window visible and contains current character - if ( geometry.contains(x,y) ) - { - FOptiAttr::char_data* tmp; - int line_len = win->width + win->right_shadow; - tmp = &win->text[(y-win_y) * line_len + (x-win_x)]; - - // current character not transparent - if ( ! tmp->transparent ) - { - if ( tmp->trans_shadow ) // transparent shadow - { - // keep the current vterm character - std::memcpy (&s_ch, cc, sizeof(FOptiAttr::char_data)); - s_ch.fg_color = tmp->fg_color; - s_ch.bg_color = tmp->bg_color; - s_ch.reverse = false; - s_ch.standout = false; - cc = &s_ch; - } - else if ( tmp->inherit_bg ) - { - // add the covered background to this character - std::memcpy (&i_ch, tmp, sizeof(FOptiAttr::char_data)); - i_ch.bg_color = cc->bg_color; // last background color - cc = &i_ch; - } - else // default - cc = tmp; - } - } - } - else if ( char_type == covered_character ) - break; - } - } - - return *cc; -} - -//---------------------------------------------------------------------- -FOptiAttr::char_data FVTerm::getCoveredCharacter ( const FPoint& pos - , FVTerm* obj ) -{ - // Gets the covered character for a given position - return getCharacter (covered_character, pos.getX(), pos.getY(), obj); -} - -//---------------------------------------------------------------------- -FOptiAttr::char_data FVTerm::getCoveredCharacter ( int x - , int y - , FVTerm* obj) -{ - // Gets the covered character for the position (x,y) - return getCharacter (covered_character, x, y, obj); -} - -//---------------------------------------------------------------------- -FOptiAttr::char_data FVTerm::getOverlappedCharacter ( const FPoint& pos - , FVTerm* obj ) -{ - // Gets the overlapped character for a given position - return getCharacter (overlapped_character, pos.getX(), pos.getY(), obj); -} - -//---------------------------------------------------------------------- -FOptiAttr::char_data FVTerm::getOverlappedCharacter ( int x - , int y - , FVTerm* obj) -{ - // Gets the overlapped character for the position (x,y) - return getCharacter (overlapped_character, x, y, obj); -} - -//---------------------------------------------------------------------- -void FVTerm::startTerminalUpdate() -{ - // Pauses the terminal updates for the printing phase - terminal_update_complete = false; -} - -//---------------------------------------------------------------------- -void FVTerm::finishTerminalUpdate() -{ - // After the printing phase is completed, the terminal will be updated - terminal_update_complete = true; + return FPoint(0,0); } //---------------------------------------------------------------------- @@ -1370,6 +143,18 @@ bool FVTerm::hideCursor (bool on) return hidden_cursor; } +//---------------------------------------------------------------------- +void FVTerm::setPrintCursor (register int x, register int y) +{ + term_area* win = getPrintArea(); + + if ( win ) + { + win->cursor_x = x - win->x_offset; + win->cursor_y = y - win->y_offset; + } +} + //---------------------------------------------------------------------- void FVTerm::createVTerm (const FRect& r) { @@ -1459,7 +244,7 @@ void FVTerm::updateTerminal() x <= change_xmax; x++ ) { - FOptiAttr::char_data* print_char; + char_data* print_char; print_char = &vt->text[y * uInt(vt->width) + x]; if ( term_pos->getX() == term_width @@ -1527,7 +312,7 @@ bool FVTerm::updateTerminalCursor() void FVTerm::processTerminalUpdate() { // Retains terminal updates if there are unprocessed inputs - const int max_skip = 8; + static const int max_skip = 8; if ( terminal_update_pending ) { @@ -1562,30 +347,6 @@ bool FVTerm::isInsideTerminal (int x, int y) return false; } -//---------------------------------------------------------------------- -void FVTerm::setPrintCursor (register int x, register int y) -{ - term_area* win = getPrintArea(); - - if ( win ) - { - win->cursor_x = x - win->x_offset; - win->cursor_y = y - win->y_offset; - } -} - -//---------------------------------------------------------------------- -FPoint FVTerm::getPrintCursor() -{ - term_area* win = getPrintArea(); - - if ( win ) - return FPoint ( win->x_offset + win->cursor_x - , win->y_offset + win->cursor_y ); - - return FPoint(0,0); -} - //---------------------------------------------------------------------- int FVTerm::printf (const wchar_t* format, ...) { @@ -1641,7 +402,7 @@ int FVTerm::print (const std::wstring& s) } //---------------------------------------------------------------------- -int FVTerm::print (FVTerm::term_area* area, const std::wstring& s) +int FVTerm::print (term_area* area, const std::wstring& s) { assert ( area != 0 ); assert ( ! s.empty() ); @@ -1656,7 +417,7 @@ int FVTerm::print (const wchar_t* s) } //---------------------------------------------------------------------- -int FVTerm::print (FVTerm::term_area* area, const wchar_t* s) +int FVTerm::print (term_area* area, const wchar_t* s) { assert ( area != 0 ); assert ( s != 0 ); @@ -1672,7 +433,7 @@ int FVTerm::print (const char* s) } //---------------------------------------------------------------------- -int FVTerm::print (FVTerm::term_area* area, const char* s) +int FVTerm::print (term_area* area, const char* s) { assert ( area != 0 ); assert ( s != 0 ); @@ -1688,7 +449,7 @@ int FVTerm::print (const std::string& s) } //---------------------------------------------------------------------- -int FVTerm::print (FVTerm::term_area* area, const std::string& s) +int FVTerm::print (term_area* area, const std::string& s) { assert ( area != 0 ); assert ( ! s.empty() ); @@ -1713,7 +474,7 @@ int FVTerm::print (FString& s) } //---------------------------------------------------------------------- -int FVTerm::print (FVTerm::term_area* area, FString& s) +int FVTerm::print (term_area* area, FString& s) { assert ( ! s.isNull() ); register int len = 0; @@ -1765,7 +526,7 @@ int FVTerm::print (FVTerm::term_area* area, FString& s) int ax = area->cursor_x - 1; int ay = area->cursor_y - 1; - FOptiAttr::char_data nc; // next character + char_data nc; // next character nc.code = *p; nc.fg_color = next_attribute.fg_color; nc.bg_color = next_attribute.bg_color; @@ -1791,7 +552,7 @@ int FVTerm::print (FVTerm::term_area* area, FString& s) && ax < area->width + area->right_shadow && ay < area->height + area->bottom_shadow ) { - FOptiAttr::char_data* ac; // area character + char_data* ac; // area character int line_len = area->width + area->right_shadow; ac = &area->text[ay * line_len + ax]; @@ -1866,9 +627,9 @@ int FVTerm::print (register int c) } //---------------------------------------------------------------------- -int FVTerm::print (FVTerm::term_area* area, register int c) +int FVTerm::print (term_area* area, register int c) { - FOptiAttr::char_data nc; // next character + char_data nc; // next character int width, height, rsh, bsh, ax, ay; if ( ! area ) @@ -1905,7 +666,7 @@ int FVTerm::print (FVTerm::term_area* area, register int c) && ax < area->width + area->right_shadow && ay < area->height + area->bottom_shadow ) { - FOptiAttr::char_data* ac; // area character + char_data* ac; // area character int line_len = area->width + area->right_shadow; ac = &area->text[ay * line_len + ax]; @@ -1958,7 +719,7 @@ int FVTerm::print (FVTerm::term_area* area, register int c) } //---------------------------------------------------------------------- -inline void FVTerm::newFontChanges (FOptiAttr::char_data*& next_char) +inline void FVTerm::newFontChanges (char_data*& next_char) { // NewFont special cases if ( NewFont ) @@ -1999,7 +760,7 @@ inline void FVTerm::newFontChanges (FOptiAttr::char_data*& next_char) } //---------------------------------------------------------------------- -inline void FVTerm::charsetChanges (FOptiAttr::char_data*& next_char) +inline void FVTerm::charsetChanges (char_data*& next_char) { if ( Encoding == fc::UTF8 ) return; @@ -2030,7 +791,7 @@ inline void FVTerm::charsetChanges (FOptiAttr::char_data*& next_char) } //---------------------------------------------------------------------- -inline void FVTerm::appendCharacter (FOptiAttr::char_data*& next_char) +inline void FVTerm::appendCharacter (char_data*& next_char) { newFontChanges (next_char); charsetChanges (next_char); @@ -2040,10 +801,10 @@ inline void FVTerm::appendCharacter (FOptiAttr::char_data*& next_char) } //---------------------------------------------------------------------- -inline void FVTerm::appendAttributes (FOptiAttr::char_data*& next_attr) +inline void FVTerm::appendAttributes (char_data*& next_attr) { char* attr_str; - FOptiAttr::char_data* term_attr = &term_attribute; + char_data* term_attr = &term_attribute; // generate attribute string for the next character attr_str = changeAttribute (term_attr, next_attr); @@ -2053,7 +814,7 @@ inline void FVTerm::appendAttributes (FOptiAttr::char_data*& next_attr) } //---------------------------------------------------------------------- -int FVTerm::appendLowerRight (FOptiAttr::char_data*& screen_char) +int FVTerm::appendLowerRight (char_data*& screen_char) { char* SA = tcap[fc::t_enter_am_mode].string; char* RA = tcap[fc::t_exit_am_mode].string; @@ -2149,3 +910,1249 @@ void FVTerm::flush_out() std::fflush(stdout); } + + +// protected methods of FVTerm +//---------------------------------------------------------------------- +void FVTerm::createArea ( const FRect& r + , const FPoint& p + , term_area*& area ) +{ + createArea ( r.getX() + , r.getY() + , r.getWidth() + , r.getHeight() + , p.getX() + , p.getY() + , area ); +} + +//---------------------------------------------------------------------- +void FVTerm::createArea ( int x_offset, int y_offset + , int width, int height + , int rsw, int bsh + , term_area*& area ) +{ + // initialize virtual window + area = new term_area; + + area->x_offset = 0; + area->y_offset = 0; + area->width = -1; + area->height = -1; + area->right_shadow = 0; + area->bottom_shadow = 0; + area->cursor_x = 0; + area->cursor_y = 0; + area->input_cursor_x = -1; + area->input_cursor_y = -1; + area->input_cursor_visible = false; + area->changes = 0; + area->text = 0; + area->visible = false; + area->widget = static_cast(this); + + resizeArea (x_offset, y_offset, width, height, rsw, bsh, area); +} + +//---------------------------------------------------------------------- +void FVTerm::resizeArea ( const FRect& r + , const FPoint& p + , term_area* area ) +{ + resizeArea ( r.getX() + , r.getY() + , r.getWidth() + , r.getHeight() + , p.getX() + , p.getY() + , area ); +} + +//---------------------------------------------------------------------- +void FVTerm::resizeArea ( int x_offset, int y_offset + , int width, int height + , int rsw, int bsh + , term_area* area ) +{ + int area_size; + char_data default_char; + line_changes unchanged; + + if ( ! area ) + return; + + area_size = (width+rsw) * (height+bsh); + + if ( area->height + area->bottom_shadow != height + bsh ) + { + if ( area->changes != 0 ) + delete[] area->changes; + + if ( area->text != 0 ) + delete[] area->text; + + area->changes = new line_changes[height + bsh]; + area->text = new char_data[area_size]; + } + else if ( area->width + area->right_shadow != width + rsw ) + { + if ( area->text != 0 ) + delete[] area->text; + + area->text = new char_data[area_size]; + } + else + return; + + area->x_offset = x_offset; + area->y_offset = y_offset; + area->width = width; + area->height = height; + area->right_shadow = rsw; + area->bottom_shadow = bsh; + + default_char.code = ' '; + default_char.fg_color = fc::Default; + default_char.bg_color = fc::Default; + default_char.bold = 0; + default_char.dim = 0; + default_char.italic = 0; + default_char.underline = 0; + default_char.blink = 0; + default_char.reverse = 0; + default_char.standout = 0; + default_char.invisible = 0; + default_char.protect = 0; + default_char.crossed_out = 0; + default_char.dbl_underline = 0; + default_char.alt_charset = 0; + default_char.pc_charset = 0; + default_char.transparent = 0; + default_char.trans_shadow = 0; + default_char.inherit_bg = 0; + + std::fill_n (area->text, area_size, default_char); + + unchanged.xmin = uInt(width+rsw); + unchanged.xmax = 0; + unchanged.trans_count = 0; + + std::fill_n (area->changes, height+bsh, unchanged); +} + +//---------------------------------------------------------------------- +void FVTerm::removeArea (term_area*& area) +{ + // remove the virtual window + if ( area != 0 ) + { + if ( area->changes != 0 ) + { + delete[] area->changes; + area->changes = 0; + } + + if ( area->text != 0 ) + { + delete[] area->text; + area->text = 0; + } + + delete area; + area = 0; + } +} + +//---------------------------------------------------------------------- +void FVTerm::restoreVTerm (const FRect& box) +{ + restoreVTerm ( box.getX() + , box.getY() + , box.getWidth() + , box.getHeight() ); +} + +//---------------------------------------------------------------------- +void FVTerm::restoreVTerm (int x, int y, int w, int h) +{ + char_data* tc; // terminal character + char_data* sc; // shown character + char_data s_ch; // shadow character + char_data i_ch; // inherit background character + FWidget* widget; + + x--; + y--; + + if ( x < 0 ) + x = 0; + + if ( y < 0 ) + y = 0; + + if ( w < 0 || h < 0 ) + return; + + if ( x+w > vterm->width ) + w = vterm->width - x; + + if ( w < 0 ) + return; + + if ( y+h > vterm->height ) + h = vterm->height - y; + + if ( h < 0 ) + return; + + widget = static_cast(vterm->widget); + + for (register int ty=0; ty < h; ty++) + { + for (register int tx=0; tx < w; tx++) + { + tc = &vterm->text[(y+ty) * vterm->width + (x+tx)]; + sc = &vdesktop->text[(y+ty) * vdesktop->width + (x+tx)]; + + if ( widget->window_list && ! widget->window_list->empty() ) + { + FWidget::widgetList::const_iterator iter, end; + iter = widget->window_list->begin(); + end = widget->window_list->end(); + + for (; iter != end; ++iter) + { + term_area* win = (*iter)->getVWin(); + + if ( ! win ) + continue; + + if ( ! win->visible ) + continue; + + int win_x = win->x_offset; + int win_y = win->y_offset; + FRect geometry ( win_x + , win_y + , win->width + win->right_shadow + , win->height + win->bottom_shadow ); + + // window visible and contains current character + if ( geometry.contains(tx+x, ty+y) ) + { + char_data* tmp; + int line_len = win->width + win->right_shadow; + tmp = &win->text[(ty+y-win_y) * line_len + (tx+x-win_x)]; + + if ( ! tmp->transparent ) // current character not transparent + { + if ( tmp->trans_shadow ) // transparent shadow + { + // keep the current vterm character + std::memcpy (&s_ch, sc, sizeof(char_data)); + s_ch.fg_color = tmp->fg_color; + s_ch.bg_color = tmp->bg_color; + s_ch.reverse = false; + s_ch.standout = false; + + if ( s_ch.code == fc::LowerHalfBlock + || s_ch.code == fc::UpperHalfBlock + || s_ch.code == fc::LeftHalfBlock + || s_ch.code == fc::RightHalfBlock + || s_ch.code == fc::FullBlock ) + s_ch.code = ' '; + + sc = &s_ch; + } + else if ( tmp->inherit_bg ) + { + // add the covered background to this character + std::memcpy (&i_ch, tmp, sizeof(char_data)); + i_ch.bg_color = sc->bg_color; // last background color; + sc = &i_ch; + } + else // default + sc = tmp; + } + } + } + } + + std::memcpy (tc, sc, sizeof(char_data)); + + if ( short(vterm->changes[y+ty].xmin) > x ) + vterm->changes[y+ty].xmin = uInt(x); + + if ( short(vterm->changes[y+ty].xmax) < x+w-1 ) + vterm->changes[y+ty].xmax = uInt(x+w-1); + } + } +} + +//---------------------------------------------------------------------- +FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos + , term_area* area ) +{ + return isCovered (pos.getX(), pos.getY(), area); +} + +//---------------------------------------------------------------------- +FVTerm::covered_state FVTerm::isCovered ( int x, int y + , term_area* area ) +{ + bool found; + covered_state is_covered; + FWidget* w; + + if ( ! area ) + return non_covered; + + is_covered = non_covered; + found = bool(area == vdesktop); + + w = static_cast(area->widget); + + if ( w->window_list && ! w->window_list->empty() ) + { + FWidget::widgetList::const_iterator iter, end; + iter = w->window_list->begin(); + end = w->window_list->end(); + + for (; iter != end; ++iter) + { + term_area* win = (*iter)->getVWin(); + + if ( ! win ) + continue; + + if ( ! win->visible ) + continue; + + int win_x = win->x_offset; + int win_y = win->y_offset; + FRect geometry ( win_x + , win_y + , win->width + win->right_shadow + , win->height + win->bottom_shadow ); + + if ( found && geometry.contains(x,y) ) + { + char_data* tmp; + int line_len = win->width + win->right_shadow; + tmp = &win->text[(y-win_y) * line_len + (x-win_x)]; + + if ( tmp->trans_shadow ) + { + is_covered = half_covered; + } + else if ( ! tmp->transparent ) + { + is_covered = fully_covered; + break; + } + } + + if ( area == win ) + found = true; + } + } + + return is_covered; +} + +//---------------------------------------------------------------------- +void FVTerm::updateVTerm (bool on) +{ + vterm_updates = on; + + if ( on ) + updateVTerm (last_area); +} + +//---------------------------------------------------------------------- +void FVTerm::updateVTerm (term_area* area) +{ + int ax, ay, aw, ah, rsh, bsh, y_end, ol; + char_data* tc; // terminal character + char_data* ac; // area character + bool modified = false; + + if ( ! vterm_updates ) + { + last_area = area; + return; + } + + if ( ! area ) + return; + + if ( ! area->visible ) + return; + + ax = area->x_offset; + ay = area->y_offset; + aw = area->width; + ah = area->height; + rsh = area->right_shadow; + bsh = area->bottom_shadow; + ol = 0; // outside left + + if ( ax < 0 ) + { + ol = std::abs(ax); + ax = 0; + } + + if ( ah + bsh + ay > vterm->height ) + y_end = vterm->height - ay; + else + y_end = ah + bsh; + + for (register int y=0; y < y_end; y++) // line loop + { + int line_xmin = int(area->changes[y].xmin); + int line_xmax = int(area->changes[y].xmax); + + if ( line_xmin <= line_xmax ) + { + int _xmin, _xmax; + + if ( ax == 0 ) + line_xmin = ol; + + if ( aw + rsh + ax - ol >= vterm->width ) + line_xmax = vterm->width + ol - ax - 1; + + if ( ax + line_xmin >= vterm->width ) + continue; + + for (register int x=line_xmin; x <= line_xmax; x++) // column loop + { + int gx, gy, line_len; + covered_state is_covered; + // global terminal positions + gx = ax + x; + gy = ay + y; + + if ( gx < 0 || gy < 0 ) + continue; + + line_len = aw + rsh; + ac = &area->text[y * line_len + x]; + tc = &vterm->text[gy * vterm->width + gx - ol]; + is_covered = isCovered(gx-ol, gy, area); // get covered state + + if ( is_covered != fully_covered ) + { + if ( is_covered == half_covered ) + { + // add the overlapping color to this character + char_data ch, oc; + std::memcpy (&ch, ac, sizeof(char_data)); + oc = getOverlappedCharacter (gx+1 - ol, gy+1, area->widget); + ch.fg_color = oc.fg_color; + ch.bg_color = oc.bg_color; + ch.reverse = false; + ch.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::FullBlock ) + ch.code = ' '; + + std::memcpy (tc, &ch, sizeof(char_data)); + } + else if ( ac->transparent ) // transparent + { + // restore one character on vterm + char_data ch; + ch = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); + std::memcpy (tc, &ch, sizeof(char_data)); + } + else // not transparent + { + if ( ac->trans_shadow ) // transparent shadow + { + // get covered character + add the current color + char_data ch; + ch = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); + ch.fg_color = ac->fg_color; + ch.bg_color = ac->bg_color; + ch.reverse = false; + ch.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::FullBlock ) + ch.code = ' '; + + std::memcpy (tc, &ch, sizeof(char_data)); + } + else if ( ac->inherit_bg ) + { + // add the covered background to this character + char_data ch, cc; + std::memcpy (&ch, ac, sizeof(char_data)); + cc = getCoveredCharacter (gx+1 - ol, gy+1, area->widget); + ch.bg_color = cc.bg_color; + std::memcpy (tc, &ch, sizeof(char_data)); + } + else // default + std::memcpy (tc, ac, sizeof(char_data)); + } + + modified = true; + } + else if ( ! modified ) + line_xmin++; // don't update covered character + } + + _xmin = ax + line_xmin - ol; + _xmax = ax + line_xmax; + + if ( _xmin < short(vterm->changes[ay+y].xmin) ) + vterm->changes[ay+y].xmin = uInt(_xmin); + + if ( _xmax >= vterm->width ) + _xmax = vterm->width - 1; + + if ( _xmax > short(vterm->changes[ay+y].xmax) ) + vterm->changes[ay+y].xmax = uInt(_xmax); + + area->changes[y].xmin = uInt(aw + rsh); + area->changes[y].xmax = 0; + } + } + + updateVTermCursor(area); +} + +//---------------------------------------------------------------------- +bool FVTerm::updateVTermCursor (term_area* area) +{ + if ( ! area ) + return false; + + if ( area != active_area ) + return false; + + if ( ! area->visible ) + return false; + + if ( area->input_cursor_visible ) + { + int cx, cy, ax, ay, x, y; + // area offset + ax = area->x_offset; + ay = area->y_offset; + // area cursor position + cx = area->input_cursor_x; + cy = area->input_cursor_y; + // terminal position + x = ax + cx; + y = ay + cy; + + if ( isInsideArea(cx, cy, area) + && isInsideTerminal(x, y) + && isCovered(x, y, area) == non_covered ) + { + vterm->input_cursor_x = x; + vterm->input_cursor_y = y; + vterm->input_cursor_visible = true; + return true; + } + } + + vterm->input_cursor_visible = false; + return false; +} + +//---------------------------------------------------------------------- +bool FVTerm::isInsideArea (int x, int y, term_area* area) +{ + // Check whether the coordinates are within the area + int ax, ay, aw, ah; + ax = 0; + ay = 0; + aw = area->width; + ah = area->height; + FRect area_geometry(ax, ay, aw, ah); + + if ( area_geometry.contains(x,y) ) + return true; + else + return false; +} + +//---------------------------------------------------------------------- +void FVTerm::setAreaCursor ( const FPoint& pos + , bool visible + , term_area* area ) +{ + setAreaCursor (pos.getX(), pos.getY(), visible, area); +} + +//---------------------------------------------------------------------- +void FVTerm::setAreaCursor ( int x, int y + , bool visible + , term_area* area ) +{ + if ( ! area ) + return; + + area->input_cursor_x = x - 1; + area->input_cursor_y = y - 1; + area->input_cursor_visible = visible; + updateVTerm (area); +} + +//---------------------------------------------------------------------- +void FVTerm::getArea (const FPoint& pos, term_area* area) +{ + return getArea (pos.getX(), pos.getY(), area); +} + +//---------------------------------------------------------------------- +void FVTerm::getArea (int ax, int ay, term_area* area) +{ + // Copies a block from the virtual terminal position to the given area + int y_end; + int length; + char_data* tc; // terminal character + char_data* ac; // area character + + if ( ! area ) + return; + + ax--; + ay--; + + if ( area->height+ay > vterm->height ) + y_end = area->height - ay; + else + y_end = area->height; + + if ( area->width+ax > vterm->width ) + length = vterm->width - ax; + else + length = area->width; + + for (int y=0; y < y_end; y++) // line loop + { + tc = &vterm->text[(ay+y) * vterm->width + ax]; + ac = &area->text[y * area->width]; + std::memcpy (ac, tc, sizeof(char_data) * unsigned(length)); + + if ( short(area->changes[y].xmin) > 0 ) + area->changes[y].xmin = 0; + + if ( short(area->changes[y].xmax) < length-1 ) + area->changes[y].xmax = uInt(length-1); + } +} + +//---------------------------------------------------------------------- +void FVTerm::getArea (const FRect& box, term_area* area) +{ + getArea ( box.getX() + , box.getY() + , box.getWidth() + , box.getHeight() + , area ); +} + +//---------------------------------------------------------------------- +void FVTerm::getArea (int x, int y, int w, int h, term_area* area) +{ + // Copies a block from the virtual terminal rectangle to the given area + int y_end, length, dx, dy; + char_data* tc; // terminal character + char_data* ac; // area character + + if ( ! area ) + return; + + dx = x - area->x_offset + 1; + dy = y - area->y_offset + 1; + + if ( x < 0 || y < 0 ) + return; + + if ( y-1+h > vterm->height ) + y_end = vterm->height - y + 1; + else + y_end = h - 1; + + if ( x-1+w > vterm->width ) + length = vterm->width - x + 1; + else + length = w; + + if ( length < 1 ) + return; + + for (int _y=0; _y < y_end; _y++) // line loop + { + int line_len = area->width + area->right_shadow; + tc = &vterm->text[(y+_y-1) * vterm->width + x-1]; + ac = &area->text[(dy+_y) * line_len + dx]; + std::memcpy (ac, tc, sizeof(char_data) * unsigned(length)); + + if ( short(area->changes[dy+_y].xmin) > dx ) + area->changes[dy+_y].xmin = uInt(dx); + + if ( short(area->changes[dy+_y].xmax) < dx+length-1 ) + area->changes[dy+_y].xmax = uInt(dx+length-1); + } +} + +//---------------------------------------------------------------------- +void FVTerm::putArea (const FPoint& pos, term_area* area) +{ + // Copies the given area block to the virtual terminal position + if ( ! area ) + return; + + if ( ! area->visible ) + return; + + putArea (pos.getX(), pos.getY(), area); +} + +//---------------------------------------------------------------------- +void FVTerm::putArea (int ax, int ay, term_area* area) +{ + // Copies the given area block to the virtual terminal position + int aw, ah, rsh, bsh, y_end, length, ol; + char_data* tc; // terminal character + char_data* ac; // area character + + if ( ! area ) + return; + + if ( ! area->visible ) + return; + + ax--; + ay--; + aw = area->width; + ah = area->height; + rsh = area->right_shadow; + bsh = area->bottom_shadow; + ol = 0; // outside left + + if ( ax < 0 ) + { + ol = std::abs(ax); + ax = 0; + } + + if ( ay + ah + bsh > vterm->height ) + y_end = vterm->height - ay; + else + y_end = ah + bsh; + + if ( aw + rsh - ol + ax > vterm->width ) + length = vterm->width - ax; + else + length = aw + rsh - ol; + + if ( length < 1 ) + return; + + for (register int y=0; y < y_end; y++) // line loop + { + int line_len = aw + rsh; + + if ( area->changes[y].trans_count == 0 ) + { + // Line has only covered characters + tc = &vterm->text[(ay+y) * vterm->width + ax]; + ac = &area->text[y * line_len + ol]; + std::memcpy (tc, ac, sizeof(char_data) * unsigned(length)); + } + else + { + // Line has one or more transparent characters + for (register int x=0; x < length; x++) // column loop + { + tc = &vterm->text[(ay+y) * vterm->width + (ax+x)]; + ac = &area->text[y * line_len + ol + x]; + + if ( ac->transparent ) // transparent + { + // restore one character on vterm + char_data ch; + ch = getCoveredCharacter (ax+x+1, ay+y+1, area->widget); + std::memcpy (tc, &ch, sizeof(char_data)); + } + else // not transparent + { + if ( ac->trans_shadow ) // transparent shadow + { + // get covered character + add the current color + char_data ch; + ch = getCoveredCharacter (ax+x+1, ay+y+1, area->widget); + ch.fg_color = ac->fg_color; + ch.bg_color = ac->bg_color; + ch.reverse = false; + ch.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::FullBlock ) + ch.code = ' '; + + std::memcpy (tc, &ch, sizeof(char_data)); + } + else if ( ac->inherit_bg ) + { + // add the covered background to this character + char_data ch, cc; + std::memcpy (&ch, ac, sizeof(char_data)); + cc = getCoveredCharacter (ax+x+1, ay+y+1, area->widget); + ch.bg_color = cc.bg_color; + std::memcpy (tc, &ch, sizeof(char_data)); + } + else // default + std::memcpy (tc, ac, sizeof(char_data)); + } + } + } + + if ( ax < short(vterm->changes[ay+y].xmin) ) + vterm->changes[ay+y].xmin = uInt(ax); + + if ( ax+length-1 > short(vterm->changes[ay+y].xmax) ) + vterm->changes[ay+y].xmax = uInt(ax+length-1); + } +} + +//---------------------------------------------------------------------- +void FVTerm::scrollAreaForward (term_area* area) +{ + // Scrolls the entire area up line down + int total_width; + int length; + int y_max; + char_data nc; // next character + char_data* lc; // last character + char_data* sc; // source character + char_data* dc; // destination character + + if ( ! area ) + return; + + if ( area->height <= 1 ) + return; + + length = area->width; + total_width = area->width + area->right_shadow; + y_max = area->height - 1; + + for (int y=0; y < y_max; y++) + { + int pos1 = y * total_width; + int pos2 = (y+1) * total_width; + sc = &area->text[pos2]; + dc = &area->text[pos1]; + std::memcpy (dc, sc, sizeof(char_data) * unsigned(length)); + area->changes[y].xmin = 0; + area->changes[y].xmax = uInt(area->width - 1); + } + + // insert a new line below + lc = &area->text[(y_max * total_width) - area->right_shadow - 1]; + std::memcpy (&nc, lc, sizeof(char_data)); + nc.code = ' '; + dc = &area->text[y_max * total_width]; + std::fill_n (dc, area->width, nc); + area->changes[y_max].xmin = 0; + area->changes[y_max].xmax = uInt(area->width - 1); +} + +//---------------------------------------------------------------------- +void FVTerm::scrollAreaReverse (term_area* area) +{ + // Scrolls the entire area one line down + int total_width; + int length; + char_data nc; // next character + char_data* lc; // last character + char_data* sc; // source character + char_data* dc; // destination character + + if ( ! area ) + return; + + if ( area->height <= 1 ) + return; + + length = area->width; + total_width = area->width + area->right_shadow; + + for (int y=area->height-1; y > 0; y--) + { + int pos1 = (y-1) * total_width; + int pos2 = y * total_width; + sc = &area->text[pos1]; + dc = &area->text[pos2]; + std::memcpy (dc, sc, sizeof(char_data) * unsigned(length)); + area->changes[y].xmin = 0; + area->changes[y].xmax = uInt(area->width - 1); + } + + // insert a new line above + lc = &area->text[total_width]; + std::memcpy (&nc, lc, sizeof(char_data)); + nc.code = ' '; + dc = &area->text[0]; + std::fill_n (dc, area->width, nc); + area->changes[0].xmin = 0; + area->changes[0].xmax = uInt(area->width - 1); +} + +//---------------------------------------------------------------------- +void FVTerm::clearArea (term_area* area) +{ + // clear the area with the current attributes + char_data nc; // next character + int total_width; + uInt w; + + // current attributes with a space character + std::memcpy (&nc, &next_attribute, sizeof(char_data)); + nc.code = ' '; + + if ( ! area ) + return; + + total_width = area->width + area->right_shadow; + w = uInt(total_width); + + if ( area->right_shadow == 0 ) + { + int area_size = area->width * area->height; + std::fill_n (area->text, area_size, nc); + } + else + { + char_data t_char = nc; + t_char.transparent = true; + + for (int y=0; y < area->height; y++) + { + int pos = y * total_width; + std::fill_n (&area->text[pos], total_width, nc); + std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char); + } + + for (int y=0; y < area->bottom_shadow; y++) + { + int pos = total_width * (y + area->height); + std::fill_n (&area->text[pos], total_width, t_char); + } + } + + for (int i=0; i < area->height; i++) + { + + area->changes[i].xmin = 0; + area->changes[i].xmax = w - 1; + + if ( nc.transparent + || nc.trans_shadow + || nc.inherit_bg ) + area->changes[i].trans_count = w; + else if ( area->right_shadow != 0 ) + area->changes[i].trans_count = uInt(area->right_shadow); + else + area->changes[i].trans_count = 0; + } + + for (int i=0; i < area->bottom_shadow; i++) + { + int y = area->height + i; + area->changes[y].xmin = 0; + area->changes[y].xmax = w - 1; + area->changes[y].trans_count = w; + } + + updateVTerm (area); +} + +//---------------------------------------------------------------------- +FVTerm::char_data FVTerm::getCharacter ( character_type type + , const FPoint& pos + , FVTerm* obj ) +{ + // Gets the overlapped or the covered character for a given position + return getCharacter (type, pos.getX(), pos.getY(), obj); +} + +//---------------------------------------------------------------------- +FVTerm::char_data FVTerm::getCharacter ( character_type char_type + , int x + , int y + , FVTerm* obj ) +{ + // Gets the overlapped or the covered character for the position (x,y) + int xx, yy; + char_data* cc; // covered character + char_data s_ch; // shadow character + char_data i_ch; // inherit background character + FWidget* w; + + x--; + y--; + xx = x; + yy = y; + + if ( xx < 0 ) + xx = 0; + + if ( yy < 0 ) + yy = 0; + + if ( xx >= vterm->width ) + xx = vterm->width - 1; + + if ( yy >= vterm->height ) + yy = vterm->height - 1; + + cc = &vdesktop->text[yy * vdesktop->width + xx]; + w = static_cast(obj); + + if ( w->window_list && ! w->window_list->empty() ) + { + FWidget::widgetList::const_iterator iter, end; + // get the window layer of this object + int layer = FWindow::getWindowLayer(w); + iter = w->window_list->begin(); + end = w->window_list->end(); + + for (; iter != end; ++iter) + { + bool significant_char; + + // char_type can be "overlapped_character" + // or "covered_character" + if ( char_type == covered_character ) + significant_char = bool(layer >= FWindow::getWindowLayer(*iter)); + else + significant_char = bool(layer < FWindow::getWindowLayer(*iter)); + + if ( obj && *iter != obj && significant_char ) + { + term_area* win = (*iter)->getVWin(); + + if ( ! win ) + continue; + + if ( ! win->visible ) + continue; + + int win_x = win->x_offset; + int win_y = win->y_offset; + FRect geometry ( win_x + , win_y + , win->width + win->right_shadow + , win->height + win->bottom_shadow ); + + // window visible and contains current character + if ( geometry.contains(x,y) ) + { + char_data* tmp; + int line_len = win->width + win->right_shadow; + tmp = &win->text[(y-win_y) * line_len + (x-win_x)]; + + // current character not transparent + if ( ! tmp->transparent ) + { + if ( tmp->trans_shadow ) // transparent shadow + { + // keep the current vterm character + std::memcpy (&s_ch, cc, sizeof(char_data)); + s_ch.fg_color = tmp->fg_color; + s_ch.bg_color = tmp->bg_color; + s_ch.reverse = false; + s_ch.standout = false; + cc = &s_ch; + } + else if ( tmp->inherit_bg ) + { + // add the covered background to this character + std::memcpy (&i_ch, tmp, sizeof(char_data)); + i_ch.bg_color = cc->bg_color; // last background color + cc = &i_ch; + } + else // default + cc = tmp; + } + } + } + else if ( char_type == covered_character ) + break; + } + } + + return *cc; +} + +//---------------------------------------------------------------------- +FVTerm::char_data FVTerm::getCoveredCharacter ( const FPoint& pos + , FVTerm* obj ) +{ + // Gets the covered character for a given position + return getCharacter (covered_character, pos.getX(), pos.getY(), obj); +} + +//---------------------------------------------------------------------- +FVTerm::char_data FVTerm::getCoveredCharacter ( int x + , int y + , FVTerm* obj) +{ + // Gets the covered character for the position (x,y) + return getCharacter (covered_character, x, y, obj); +} + +//---------------------------------------------------------------------- +FVTerm::char_data FVTerm::getOverlappedCharacter ( const FPoint& pos + , FVTerm* obj ) +{ + // Gets the overlapped character for a given position + return getCharacter (overlapped_character, pos.getX(), pos.getY(), obj); +} + +//---------------------------------------------------------------------- +FVTerm::char_data FVTerm::getOverlappedCharacter ( int x + , int y + , FVTerm* obj) +{ + // Gets the overlapped character for the position (x,y) + return getCharacter (overlapped_character, x, y, obj); +} + +//---------------------------------------------------------------------- +void FVTerm::startTerminalUpdate() +{ + // Pauses the terminal updates for the printing phase + terminal_update_complete = false; +} + +//---------------------------------------------------------------------- +void FVTerm::finishTerminalUpdate() +{ + // After the printing phase is completed, the terminal will be updated + terminal_update_complete = true; +} + + +// private methods of FVTerm +//---------------------------------------------------------------------- +FVTerm::term_area* FVTerm::getPrintArea() +{ + // returns the print area of this object + if ( print_area ) + return print_area; + else + { + FVTerm* obj = static_cast(this); + FVTerm* p_obj = static_cast(obj->getParent()); + + while ( ! obj->vwin && p_obj ) + { + obj = p_obj; + p_obj = static_cast(p_obj->getParent()); + } + + if ( obj->vwin ) + { + print_area = obj->vwin; + return print_area; + } + } + + return vdesktop; +} + +//---------------------------------------------------------------------- +void FVTerm::init() +{ + init_object = this; + vterm = 0; + vdesktop = 0; + last_area = 0; + term_pos = new FPoint(-1,-1); + output_buffer = new std::queue; + + // Preset to false + hidden_cursor = \ + terminal_update_pending = \ + force_terminal_update = \ + stop_terminal_updates = false; + + // term_attribute stores the current state of the terminal + term_attribute.code = '\0'; + term_attribute.fg_color = fc::Default; + term_attribute.bg_color = fc::Default; + term_attribute.bold = \ + term_attribute.dim = \ + term_attribute.italic = \ + term_attribute.underline = \ + term_attribute.blink = \ + term_attribute.reverse = \ + term_attribute.standout = \ + term_attribute.invisible = \ + term_attribute.protect = \ + term_attribute.crossed_out = \ + term_attribute.dbl_underline = \ + term_attribute.alt_charset = \ + term_attribute.pc_charset = \ + term_attribute.transparent = \ + term_attribute.trans_shadow = \ + term_attribute.inherit_bg = false; + + // next_attribute contains the state of the next printed character + std::memcpy (&next_attribute, &term_attribute, sizeof(char_data)); + + // receive the terminal capabilities + tcap = FTermcap().getTermcapMap(); + + // create virtual terminal + FRect term_geometry (0, 0, getColumnNumber(), getLineNumber()); + createVTerm (term_geometry); + + // create virtual desktop area + FPoint shadow_size(0,0); + createArea (term_geometry, shadow_size, vdesktop); + vdesktop->visible = true; + active_area = vdesktop; + + // Hide the input cursor + hideCursor(); +} + +//---------------------------------------------------------------------- +void FVTerm::finish() +{ + // Show the input cursor + showCursor(); + + if ( output_buffer ) + delete output_buffer; + + // remove virtual terminal + virtual desktop area + removeArea (vdesktop); + removeArea (vterm); + + if ( term_pos ) + delete term_pos; +} diff --git a/src/fvterm.h b/src/fvterm.h index b8fb6f3b..0b915b71 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -28,10 +28,6 @@ #include "fterm.h" - -// Buffer size for character output on the terminal -#define TERMINAL_OUTPUT_BUFFER_SIZE 32768 - // class forward declaration class FWidget; @@ -45,35 +41,8 @@ class FWidget; class FVTerm : public FObject, public FTerm { - private: - static std::queue* output_buffer; - static FOptiAttr::char_data term_attribute; - static FOptiAttr::char_data next_attribute; - static FPoint* term_pos; // terminal cursor position - static FTermcap::tcap_map* tcap; - - static bool hidden_cursor; - static bool terminal_update_complete; - static bool terminal_update_pending; - static bool force_terminal_update; - static bool stop_terminal_updates; - static bool vterm_updates; - static int skipped_terminal_update; - - enum covered_state - { - non_covered, - half_covered, - fully_covered - }; - - enum character_type - { - overlapped_character, - covered_character - }; - - protected: + public: + // Typedefs and Enumeration typedef struct { uInt xmin; @@ -81,6 +50,8 @@ class FVTerm : public FObject, public FTerm uInt trans_count; } line_changes; + typedef FOptiAttr::char_data char_data; + typedef struct { int x_offset; @@ -96,80 +67,123 @@ class FVTerm : public FObject, public FTerm int input_cursor_visible; FWidget* widget; line_changes* changes; - FOptiAttr::char_data* text; + char_data* text; bool visible; } term_area; - static term_area* vterm; // virtual terminal - static term_area* vdesktop; // virtual desktop - static term_area* last_area; // last used area - static term_area* active_area; // active area - term_area* print_area; // print area for this object - term_area* vwin; // virtual window + enum covered_state + { + non_covered, + half_covered, + fully_covered + }; - protected: - void createArea (const FRect&, const FPoint&, FVTerm::term_area*&); - void createArea (int, int, int, int, int, int, FVTerm::term_area*&); - static void resizeArea (const FRect&, const FPoint&, FVTerm::term_area*); - static void resizeArea (int, int, int, int, int, int, FVTerm::term_area*); - static void removeArea (FVTerm::term_area*&); - static void restoreVTerm (const FRect&); - static void restoreVTerm (int, int, int, int); - static FVTerm::covered_state isCovered (const FPoint&, FVTerm::term_area*); - static FVTerm::covered_state isCovered (int, int, FVTerm::term_area*); - static void updateVTerm (bool); - static void updateVTerm (FVTerm::term_area*); - static bool updateVTermCursor (FVTerm::term_area*); - static bool isInsideArea (int, int, FVTerm::term_area*); - static void setAreaCursor (const FPoint&, bool, FVTerm::term_area*); - static void setAreaCursor (int, int, bool, FVTerm::term_area*); - static void getArea (const FPoint&, FVTerm::term_area*); - static void getArea (int, int, FVTerm::term_area*); - static void getArea (const FRect&, FVTerm::term_area*); - static void getArea (int, int, int, int, FVTerm::term_area*); - static void putArea (const FPoint&, FVTerm::term_area*); - static void putArea (int, int, FVTerm::term_area*); - static void scrollAreaForward (FVTerm::term_area*); - static void scrollAreaReverse (FVTerm::term_area*); - static void clearArea (FVTerm::term_area*); - static FOptiAttr::char_data getCharacter (character_type, const FPoint&, FVTerm*); - static FOptiAttr::char_data getCharacter (character_type, int, int, FVTerm*); - static FOptiAttr::char_data getCoveredCharacter (const FPoint&, FVTerm*); - static FOptiAttr::char_data getCoveredCharacter (int, int, FVTerm*); - static FOptiAttr::char_data getOverlappedCharacter (const FPoint&, FVTerm*); - static FOptiAttr::char_data getOverlappedCharacter (int, int, FVTerm*); - static void startTerminalUpdate(); - static void finishTerminalUpdate(); - - private: - // Disable copy constructor - FVTerm (const FVTerm&); - // Disable assignment operator (=) - FVTerm& operator = (const FVTerm&); - - void init(); - void finish(); - term_area* getPrintArea(); - void setPrintArea (term_area*); - - public: // Constructor explicit FVTerm (FVTerm* = 0); + // Destructor ~FVTerm(); + // Accessors virtual const char* getClassName() const; + static short getTermForegroundColor(); + static short getTermBackgroundColor(); + term_area* getVWin() const; + FPoint getPrintCursor(); + // Mutators static void setTermXY (register int, register int); - static bool hideCursor (bool); static bool hideCursor(); static bool showCursor(); - static bool isCursorHidden(); + void setPrintCursor (const FPoint&); + void setPrintCursor (register int, register int); + void setColor (short, short); + static void setNormal(); + + static bool setBold (register bool); + static bool setBold(); + static bool unsetBold(); + + static bool setDim (register bool); + static bool setDim(); + static bool unsetDim(); + + static bool setItalic (register bool); + static bool setItalic(); + static bool unsetItalic(); + + static bool setUnderline (register bool); + static bool setUnderline(); + static bool unsetUnderline(); + + static bool setBlink (register bool); + static bool setBlink(); + static bool unsetBlink(); + + static bool setReverse (register bool); + static bool setReverse(); + static bool unsetReverse(); + + static bool setStandout (register bool); + static bool setStandout(); + static bool unsetStandout(); + + static bool setInvisible (register bool); + static bool setInvisible(); + static bool unsetInvisible(); + + static bool setProtected (register bool); + static bool setProtected(); + static bool unsetProtected(); + + static bool setCrossedOut (register bool); + static bool setCrossedOut(); + static bool unsetCrossedOut(); + + static bool setDoubleUnderline (register bool); + static bool setDoubleUnderline(); + static bool unsetDoubleUnderline(); + + static bool setAltCharset (register bool); + static bool setAltCharset(); + static bool unsetAltCharset(); + + static bool setPCcharset (register bool); + static bool setPCcharset(); + static bool unsetPCcharset(); + + static bool setTransparent (register bool); + static bool setTransparent(); + static bool unsetTransparent(); + + static bool setTransShadow (register bool); + static bool setTransShadow(); + static bool unsetTransShadow(); + + static bool setInheritBackground (register bool); + static bool setInheritBackground(); + static bool unsetInheritBackground(); + + // Inquiries + static bool isCursorHidden(); + static bool isBold(); + static bool isDim(); + static bool isItalic(); + static bool isUnderline(); + static bool isBlink(); + static bool isReverse(); + static bool isStandout(); + static bool isInvisible(); + static bool isProtected(); + static bool isCrossedOut(); + static bool isDoubleUnderline(); + static bool isAltCharset(); + static bool isPCcharset(); + static bool isTransparent(); + static bool isTransShadow(); + static bool isInheritBackground(); - static short getTermForegroundColor(); - static short getTermBackgroundColor(); - FVTerm::term_area* getVWin() const; void createVTerm (const FRect&); void createVTerm (int, int); static void resizeVTerm (const FRect&); @@ -181,10 +195,6 @@ class FVTerm : public FObject, public FTerm static void processTerminalUpdate(); static bool isInsideTerminal (int, int); - void setPrintCursor (const FPoint&); - void setPrintCursor (register int, register int); - FPoint getPrintCursor(); - int printf (const wchar_t*, ...); int printf (const char*, ...) #if defined(__clang__) @@ -194,134 +204,152 @@ class FVTerm : public FObject, public FTerm #endif ; int print (const std::wstring&); - int print (FVTerm::term_area*, const std::wstring&); + int print (term_area*, const std::wstring&); int print (const wchar_t*); - int print (FVTerm::term_area*, const wchar_t*); + int print (term_area*, const wchar_t*); int print (const char*); - int print (FVTerm::term_area*, const char*); + int print (term_area*, const char*); int print (const std::string&); - int print (FVTerm::term_area*, const std::string&); + int print (term_area*, const std::string&); int print (FString&); - int print (FVTerm::term_area*, FString&); + int print (term_area*, FString&); int print (int); - int print (FVTerm::term_area*, int); - static void newFontChanges (FOptiAttr::char_data*&); - static void charsetChanges (FOptiAttr::char_data*&); - static void appendCharacter (FOptiAttr::char_data*&); - static void appendAttributes (FOptiAttr::char_data*&); - static int appendLowerRight (FOptiAttr::char_data*&); + int print (term_area*, int); + static void newFontChanges (char_data*&); + static void charsetChanges (char_data*&); + static void appendCharacter (char_data*&); + static void appendAttributes (char_data*&); + static int appendLowerRight (char_data*&); static void appendOutputBuffer (std::string&); static void appendOutputBuffer (const char*); static int appendOutputBuffer (int); static void flush_out(); - void setColor (short, short); - static void setNormal(); + protected: + // Enumeration + enum character_type + { + overlapped_character, + covered_character + }; - static bool setBold (register bool); - static bool setBold(); - static bool unsetBold(); - static bool isBold(); + // Methods + void createArea ( const FRect& + , const FPoint& + , term_area*& ); - static bool setDim (register bool); - static bool setDim(); - static bool unsetDim(); - static bool isDim(); + void createArea ( int, int, int, int + , int, int + , term_area*& ); - static bool setItalic (register bool); - static bool setItalic(); - static bool unsetItalic(); - static bool isItalic(); + static void resizeArea ( const FRect& + , const FPoint& + , term_area* ); - static bool setUnderline (register bool); - static bool setUnderline(); - static bool unsetUnderline(); - static bool isUnderline(); + static void resizeArea ( int, int, int, int + , int, int + , term_area* ); - static bool setBlink (register bool); - static bool setBlink(); - static bool unsetBlink(); - static bool isBlink(); + static void removeArea (term_area*&); + static void restoreVTerm (const FRect&); + static void restoreVTerm (int, int, int, int); - static bool setReverse (register bool); - static bool setReverse(); - static bool unsetReverse(); - static bool isReverse(); + static covered_state isCovered ( const FPoint& + , term_area* ); - static bool setStandout (register bool); - static bool setStandout(); - static bool unsetStandout(); - static bool isStandout(); + static covered_state isCovered ( int, int + , term_area* ); - static bool setInvisible (register bool); - static bool setInvisible(); - static bool unsetInvisible(); - static bool isInvisible(); + static void updateVTerm (bool); + static void updateVTerm (term_area*); + static bool updateVTermCursor (term_area*); + static bool isInsideArea (int, int, term_area*); - static bool setProtected (register bool); - static bool setProtected(); - static bool unsetProtected(); - static bool isProtected(); + static void setAreaCursor ( const FPoint& + , bool, term_area* ); - static bool setCrossedOut (register bool); - static bool setCrossedOut(); - static bool unsetCrossedOut(); - static bool isCrossedOut(); + static void setAreaCursor ( int, int + , bool, term_area*); - static bool setDoubleUnderline (register bool); - static bool setDoubleUnderline(); - static bool unsetDoubleUnderline(); - static bool isDoubleUnderline(); + static void getArea (const FPoint&, term_area*); + static void getArea (int, int, term_area*); + static void getArea (const FRect&, term_area*); + static void getArea (int, int, int, int, term_area*); + static void putArea (const FPoint&, term_area*); + static void putArea (int, int, term_area*); + static void scrollAreaForward (term_area*); + static void scrollAreaReverse (term_area*); + static void clearArea (term_area*); - static bool setAltCharset (register bool); - static bool setAltCharset(); - static bool unsetAltCharset(); - static bool isAltCharset(); + static char_data getCharacter ( character_type + , const FPoint& + , FVTerm* ); - static bool setPCcharset (register bool); - static bool setPCcharset(); - static bool unsetPCcharset(); - static bool isPCcharset(); + static char_data getCharacter ( character_type + , int + , int, FVTerm* ); - static bool setTransparent (register bool); - static bool setTransparent(); - static bool unsetTransparent(); - static bool isTransparent(); + static char_data getCoveredCharacter (const FPoint&, FVTerm*); + static char_data getCoveredCharacter (int, int, FVTerm*); + static char_data getOverlappedCharacter (const FPoint&, FVTerm*); + static char_data getOverlappedCharacter (int, int, FVTerm*); + static void startTerminalUpdate(); + static void finishTerminalUpdate(); - static bool setTransShadow (register bool); - static bool setTransShadow(); - static bool unsetTransShadow(); - static bool isTransShadow(); + // Data Members + static term_area* vterm; // virtual terminal + static term_area* vdesktop; // virtual desktop + static term_area* last_area; // last used area + static term_area* active_area; // active area + term_area* print_area; // print area for this object + term_area* vwin; // virtual window - static bool setInheritBackground (register bool); - static bool setInheritBackground(); - static bool unsetInheritBackground(); - static bool isInheritBackground(); + private: + // Typedef + typedef FTermcap::tcap_map termcap_map; + + // Constants + static const uInt TERMINAL_OUTPUT_BUFFER_SIZE = 32768; + // Buffer size for character output on the terminal + + // Disable copy constructor + FVTerm (const FVTerm&); + + // Disable assignment operator (=) + FVTerm& operator = (const FVTerm&); + + // Accessor + term_area* getPrintArea(); + + // Mutators + void setPrintArea (term_area*); + + // Methods + void init(); + void finish(); + + // Data Members + static std::queue* output_buffer; + static char_data term_attribute; + static char_data next_attribute; + static FPoint* term_pos; // terminal cursor position + static termcap_map* tcap; + static bool hidden_cursor; + static bool terminal_update_complete; + static bool terminal_update_pending; + static bool force_terminal_update; + static bool stop_terminal_updates; + static bool vterm_updates; + static int skipped_terminal_update; }; #pragma pack(pop) // FVTerm inline functions -//---------------------------------------------------------------------- -inline void FVTerm::setPrintArea (term_area* area) -{ print_area = area; } - //---------------------------------------------------------------------- inline const char* FVTerm::getClassName() const { return "FVTerm"; } -//---------------------------------------------------------------------- -inline bool FVTerm::hideCursor() -{ return hideCursor(true); } - -//---------------------------------------------------------------------- -inline bool FVTerm::showCursor() -{ return hideCursor(false); } - -//---------------------------------------------------------------------- -inline bool FVTerm::isCursorHidden() -{ return hidden_cursor; } - //---------------------------------------------------------------------- inline short FVTerm::getTermForegroundColor() { return next_attribute.fg_color; } @@ -334,6 +362,14 @@ inline short FVTerm::getTermBackgroundColor() inline FVTerm::term_area* FVTerm::getVWin() const { return vwin; } +//---------------------------------------------------------------------- +inline bool FVTerm::hideCursor() +{ return hideCursor(true); } + +//---------------------------------------------------------------------- +inline bool FVTerm::showCursor() +{ return hideCursor(false); } + //---------------------------------------------------------------------- inline void FVTerm::setPrintCursor (const FPoint& pos) { setPrintCursor (pos.getX(), pos.getY()); } @@ -383,10 +419,6 @@ inline bool FVTerm::setBold() inline bool FVTerm::unsetBold() { return setBold(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isBold() -{ return next_attribute.bold; } - //---------------------------------------------------------------------- inline bool FVTerm::setDim (register bool on) { return (next_attribute.dim = on); } @@ -399,10 +431,6 @@ inline bool FVTerm::setDim() inline bool FVTerm::unsetDim() { return setDim(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isDim() -{ return next_attribute.dim; } - //---------------------------------------------------------------------- inline bool FVTerm::setItalic (register bool on) { return (next_attribute.italic = on); } @@ -415,10 +443,6 @@ inline bool FVTerm::setItalic() inline bool FVTerm::unsetItalic() { return setItalic(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isItalic() -{ return next_attribute.italic; } - //---------------------------------------------------------------------- inline bool FVTerm::setUnderline (register bool on) { return (next_attribute.underline = on); } @@ -431,10 +455,6 @@ inline bool FVTerm::setUnderline() inline bool FVTerm::unsetUnderline() { return setUnderline(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isUnderline() -{ return next_attribute.underline; } - //---------------------------------------------------------------------- inline bool FVTerm::setBlink (register bool on) { return (next_attribute.blink = on); } @@ -447,10 +467,6 @@ inline bool FVTerm::setBlink() inline bool FVTerm::unsetBlink() { return setBlink(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isBlink() -{ return next_attribute.blink; } - //---------------------------------------------------------------------- inline bool FVTerm::setReverse (register bool on) { return (next_attribute.reverse = on); } @@ -463,10 +479,6 @@ inline bool FVTerm::setReverse() inline bool FVTerm::unsetReverse() { return setReverse(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isReverse() -{ return next_attribute.reverse; } - //---------------------------------------------------------------------- inline bool FVTerm::setStandout (register bool on) { return (next_attribute.standout = on); } @@ -479,10 +491,6 @@ inline bool FVTerm::setStandout() inline bool FVTerm::unsetStandout() { return setStandout(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isStandout() -{ return next_attribute.standout; } - //---------------------------------------------------------------------- inline bool FVTerm::setInvisible (register bool on) { return (next_attribute.invisible = on); } @@ -495,10 +503,6 @@ inline bool FVTerm::setInvisible() inline bool FVTerm::unsetInvisible() { return setInvisible(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isInvisible() -{ return next_attribute.invisible; } - //---------------------------------------------------------------------- inline bool FVTerm::setProtected (register bool on) { return (next_attribute.protect = on); } @@ -511,10 +515,6 @@ inline bool FVTerm::setProtected() inline bool FVTerm::unsetProtected() { return setProtected(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isProtected() -{ return next_attribute.protect; } - //---------------------------------------------------------------------- inline bool FVTerm::setCrossedOut (register bool on) { return (next_attribute.crossed_out = on); } @@ -527,10 +527,6 @@ inline bool FVTerm::setCrossedOut() inline bool FVTerm::unsetCrossedOut() { return setCrossedOut(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isCrossedOut() -{ return next_attribute.crossed_out; } - //---------------------------------------------------------------------- inline bool FVTerm::setDoubleUnderline (register bool on) { return (next_attribute.dbl_underline = on); } @@ -543,10 +539,6 @@ inline bool FVTerm::setDoubleUnderline() inline bool FVTerm::unsetDoubleUnderline() { return setDoubleUnderline(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isDoubleUnderline() -{ return next_attribute.dbl_underline; } - //---------------------------------------------------------------------- inline bool FVTerm::setAltCharset (register bool on) { return (next_attribute.alt_charset = on); } @@ -559,10 +551,6 @@ inline bool FVTerm::setAltCharset() inline bool FVTerm::unsetAltCharset() { return setAltCharset(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isAltCharset() -{ return next_attribute.alt_charset; } - //---------------------------------------------------------------------- inline bool FVTerm::setPCcharset (register bool on) { return (next_attribute.pc_charset = on); } @@ -575,10 +563,6 @@ inline bool FVTerm::setPCcharset() inline bool FVTerm::unsetPCcharset() { return setPCcharset(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isPCcharset() -{ return next_attribute.pc_charset; } - //---------------------------------------------------------------------- inline bool FVTerm::setTransparent (register bool on) { return (next_attribute.transparent = on); } @@ -591,10 +575,6 @@ inline bool FVTerm::setTransparent() inline bool FVTerm::unsetTransparent() { return setTransparent(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isTransparent() -{ return next_attribute.transparent; } - //---------------------------------------------------------------------- inline bool FVTerm::setTransShadow (register bool on) { return (next_attribute.trans_shadow = on); } @@ -607,10 +587,6 @@ inline bool FVTerm::setTransShadow() inline bool FVTerm::unsetTransShadow() { return setTransShadow(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::isTransShadow() -{ return next_attribute.trans_shadow; } - //---------------------------------------------------------------------- inline bool FVTerm::setInheritBackground (register bool on) { return (next_attribute.inherit_bg = on); } @@ -623,8 +599,76 @@ inline bool FVTerm::setInheritBackground() inline bool FVTerm::unsetInheritBackground() { return setInheritBackground(false); } +//---------------------------------------------------------------------- +inline bool FVTerm::isCursorHidden() +{ return hidden_cursor; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isBold() +{ return next_attribute.bold; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isDim() +{ return next_attribute.dim; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isItalic() +{ return next_attribute.italic; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isUnderline() +{ return next_attribute.underline; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isBlink() +{ return next_attribute.blink; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isReverse() +{ return next_attribute.reverse; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isStandout() +{ return next_attribute.standout; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isInvisible() +{ return next_attribute.invisible; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isProtected() +{ return next_attribute.protect; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isCrossedOut() +{ return next_attribute.crossed_out; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isDoubleUnderline() +{ return next_attribute.dbl_underline; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isAltCharset() +{ return next_attribute.alt_charset; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isPCcharset() +{ return next_attribute.pc_charset; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isTransparent() +{ return next_attribute.transparent; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isTransShadow() +{ return next_attribute.trans_shadow; } + //---------------------------------------------------------------------- inline bool FVTerm::isInheritBackground() { return next_attribute.inherit_bg; } +//---------------------------------------------------------------------- +inline void FVTerm::setPrintArea (term_area* area) +{ print_area = area; } + #endif // _FVTERM_H diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 3e8deafd..e6834fad 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -31,10 +31,10 @@ FWidget::widget_colors FWidget::wc; //---------------------------------------------------------------------- FWidget::FWidget (FWidget* parent) : FVTerm(parent) - , callback_objects() - , member_callback_objects() , accelerator_list(0) , flags(0) + , callback_objects() + , member_callback_objects() , enable(true) , visible(true) , shown(false) @@ -113,742 +113,6 @@ FWidget::~FWidget() // destructor this->finish(); } -// private methods of FWidget -//---------------------------------------------------------------------- -void FWidget::init() -{ - 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 - detectTermSize(); - wsize.setRect(1, 1, getColumnNumber(), getLineNumber()); - adjust_wsize = wsize; - offset.setRect(0, 0, getColumnNumber(), getLineNumber()); - client_offset = offset; - - double_flatline_mask.top.resize (uLong(getWidth()), false); - double_flatline_mask.right.resize (uLong(getHeight()), false); - double_flatline_mask.bottom.resize (uLong(getWidth()), false); - double_flatline_mask.left.resize (uLong(getHeight()), false); - - // Initialize default widget colors - setColorTheme(); - - foreground_color = wc.term_fg; - background_color = wc.term_bg; - setColor(); - clearArea (vdesktop); - - accelerator_list = new Accelerators(); -} - -//---------------------------------------------------------------------- -void FWidget::finish() -{ - delete accelerator_list; - accelerator_list = 0; - - if ( close_widget ) - { - delete close_widget; - close_widget = 0; - } - - if ( dialog_list ) - { - delete dialog_list; - dialog_list = 0; - } - - if ( always_on_top_list ) - { - delete always_on_top_list; - always_on_top_list = 0; - } - - if ( window_list ) - { - delete window_list; - window_list = 0; - } -} - -//---------------------------------------------------------------------- -void FWidget::draw() -{ } - -//---------------------------------------------------------------------- -void FWidget::setColorTheme() -{ - wc.term_fg = fc::Black; - wc.term_bg = fc::LightBlue; - wc.list_fg = fc::Black; - wc.list_bg = fc::White; - wc.selected_list_fg = fc::Cyan; - wc.selected_list_bg = fc::White; - wc.dialog_fg = fc::Black; - wc.dialog_resize_fg = fc::Cyan; - wc.dialog_emphasis_fg = fc::Blue; - wc.dialog_bg = fc::White; - 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; - wc.current_element_focus_bg = fc::Blue; - wc.current_element_fg = fc::LightGray; - wc.current_element_bg = fc::Blue; - wc.current_inc_search_element_fg = fc::LightRed; - wc.selected_current_element_focus_fg = fc::LightCyan; - wc.selected_current_element_focus_bg = fc::Blue; - wc.selected_current_element_fg = fc::LightBlue; - wc.selected_current_element_bg = fc::Blue; - wc.label_fg = fc::Black; - wc.label_bg = fc::White; - wc.label_inactive_fg = fc::LightGray; - wc.label_inactive_bg = fc::White; - wc.label_hotkey_fg = fc::Red; - wc.label_hotkey_bg = fc::White; - wc.label_emphasis_fg = fc::Blue; - wc.label_ellipsis_fg = fc::DarkGray; - wc.inputfield_active_focus_fg = fc::White; - wc.inputfield_active_focus_bg = fc::Cyan; - wc.inputfield_active_fg = fc::Black; - wc.inputfield_active_bg = fc::LightGray; - wc.inputfield_inactive_fg = fc::DarkGray; - wc.inputfield_inactive_bg = fc::LightGray; - wc.toggle_button_active_focus_fg = fc::White; - wc.toggle_button_active_focus_bg = fc::Cyan; - wc.toggle_button_active_fg = fc::Black; - wc.toggle_button_active_bg = fc::White; - wc.toggle_button_inactive_fg = fc::LightGray; - wc.toggle_button_inactive_bg = fc::White; - wc.button_active_focus_fg = fc::LightGray; - wc.button_active_focus_bg = fc::Blue; - wc.button_active_fg = fc::LightGray; - wc.button_active_bg = fc::DarkGray; - wc.button_inactive_fg = fc::DarkGray; - wc.button_inactive_bg = fc::LightGray; - wc.button_hotkey_fg = fc::White; - wc.titlebar_active_fg = fc::White; - wc.titlebar_active_bg = fc::Blue; - wc.titlebar_inactive_fg = fc::LightGray; - wc.titlebar_inactive_bg = fc::DarkGray; - wc.titlebar_button_fg = fc::DarkGray; - wc.titlebar_button_bg = fc::LightGray; - wc.titlebar_button_focus_fg = fc::LightGray; - wc.titlebar_button_focus_bg = fc::Black; - wc.menu_active_focus_fg = fc::White; - wc.menu_active_focus_bg = fc::Blue; - wc.menu_active_fg = fc::Black; - wc.menu_active_bg = fc::White; - wc.menu_inactive_fg = fc::LightGray; - wc.menu_inactive_bg = fc::White; - wc.menu_hotkey_fg = fc::Red; - wc.menu_hotkey_bg = fc::White; - wc.statusbar_fg = fc::White; - wc.statusbar_bg = fc::Blue; - wc.statusbar_hotkey_fg = fc::LightRed; - wc.statusbar_hotkey_bg = fc::Blue; - wc.statusbar_separator_fg = fc::Black; - wc.statusbar_active_fg = fc::Blue; - wc.statusbar_active_bg = fc::White; - wc.statusbar_active_hotkey_fg = fc::DarkGray; - wc.statusbar_active_hotkey_bg = fc::White; - wc.scrollbar_fg = fc::DarkGray; - wc.scrollbar_bg = fc::LightBlue; - wc.scrollbar_button_fg = fc::Black; - wc.scrollbar_button_bg = fc::LightGray; - wc.progressbar_fg = fc::DarkGray; - wc.progressbar_bg = fc::LightBlue; - - if ( isKdeTerminal() ) - wc.term_bg = fc::SteelBlue3; - - if ( isTeraTerm() ) - wc.term_bg = fc::LightBlue; - - if ( getMaxColor() < 16 ) // for 8 color mode - { - wc.term_fg = fc::Black; - wc.term_bg = fc::Blue; - wc.list_fg = fc::Black; - wc.list_bg = fc::LightGray; - wc.selected_list_fg = fc::Blue; - wc.selected_list_bg = fc::LightGray; - wc.dialog_fg = fc::Black; - wc.dialog_resize_fg = fc::Red; - wc.dialog_emphasis_fg = fc::Blue; - wc.dialog_bg = fc::LightGray; - 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; - wc.current_element_focus_bg = fc::Red; - wc.current_element_fg = fc::LightGray; - wc.current_element_bg = fc::Blue; - wc.current_inc_search_element_fg = fc::Brown; - wc.selected_current_element_focus_fg = fc::Blue; - wc.selected_current_element_focus_bg = fc::Red; - wc.selected_current_element_fg = fc::Cyan; - wc.selected_current_element_bg = fc::Blue; - wc.label_fg = fc::Black; - wc.label_bg = fc::LightGray; - wc.label_inactive_fg = fc::Cyan; - wc.label_inactive_bg = fc::LightGray; - wc.label_hotkey_fg = fc::Red; - wc.label_hotkey_bg = fc::LightGray; - wc.label_emphasis_fg = fc::Blue; - wc.label_ellipsis_fg = fc::Black; - wc.inputfield_active_focus_fg = fc::LightGray; - wc.inputfield_active_focus_bg = fc::Blue; - wc.inputfield_active_fg = fc::Black; - wc.inputfield_active_bg = fc::Cyan; - wc.inputfield_inactive_fg = fc::Black; - wc.inputfield_inactive_bg = fc::LightGray; - wc.toggle_button_active_focus_fg = fc::LightGray; - wc.toggle_button_active_focus_bg = fc::Red; - wc.toggle_button_active_fg = fc::Black; - wc.toggle_button_active_bg = fc::LightGray; - wc.toggle_button_inactive_fg = fc::Cyan; - wc.toggle_button_inactive_bg = fc::LightGray; - wc.button_active_focus_fg = fc::LightGray; - wc.button_active_focus_bg = fc::Red; - wc.button_active_fg = fc::LightGray; - wc.button_active_bg = fc::Blue; - wc.button_inactive_fg = fc::Black; - wc.button_inactive_bg = fc::Blue; - wc.button_hotkey_fg = fc::LightGray; - wc.titlebar_active_fg = fc::LightGray; - wc.titlebar_active_bg = fc::Red; - wc.titlebar_inactive_fg = fc::Black; - wc.titlebar_inactive_bg = fc::LightGray; - wc.titlebar_button_fg = fc::Black; - wc.titlebar_button_bg = fc::LightGray; - wc.titlebar_button_focus_fg = fc::LightGray; - wc.titlebar_button_focus_bg = fc::Black; - wc.menu_active_focus_fg = fc::LightGray; - wc.menu_active_focus_bg = fc::Blue; - wc.menu_active_fg = fc::Black; - wc.menu_active_bg = fc::LightGray; - wc.menu_inactive_fg = fc::Cyan; - wc.menu_inactive_bg = fc::LightGray; - wc.menu_hotkey_fg = fc::Red; - wc.menu_hotkey_bg = fc::LightGray; - wc.statusbar_fg = fc::Black; - wc.statusbar_bg = fc::LightGray; - wc.statusbar_hotkey_fg = fc::Red; - wc.statusbar_hotkey_bg = fc::LightGray; - wc.statusbar_separator_fg = fc::Black; - wc.statusbar_active_fg = fc::LightGray; - wc.statusbar_active_bg = fc::Black; - wc.statusbar_active_hotkey_fg = fc::Red; - wc.statusbar_active_hotkey_bg = fc::Black; - wc.scrollbar_fg = fc::Black; - wc.scrollbar_bg = fc::LightGray; - wc.scrollbar_button_fg = fc::Black; - wc.scrollbar_button_bg = fc::LightGray; - wc.progressbar_fg = fc::Blue; - wc.progressbar_bg = fc::LightGray; - } -} - - -// protected methods of FWidget -//---------------------------------------------------------------------- -void FWidget::adjustSize() -{ - if ( ! isRootWidget() ) - { - FWidget* p = getParentWidget(); - - if ( isWindowWidget() ) - { - if ( ignore_padding && ! isDialogWidget() ) - setTermOffset(); - else - offset = rootObject->client_offset; - } - else if ( ignore_padding && p ) - { - offset.setCoordinates ( p->getTermX() - 1 - , p->getTermY() - 1 - , p->getTermX() + p->getWidth() - 2 - , p->getTermY() + p->getHeight() - 2 ); - } - else if ( p ) - offset = p->client_offset; - - adjust_wsize = wsize; - } - - if ( ! isWindowWidget() ) - { - // move left if not enough space - while ( getTermX()+getWidth()-padding.right > offset.getX2()+2 ) - { - adjust_wsize.x1_ref()--; - adjust_wsize.x2_ref()--; - - if ( adjust_wsize.x1_ref() < 1 ) - adjust_wsize.x1_ref() = 1; - } - - // move up if not enough space - while ( getTermY()+getHeight()-padding.bottom > offset.getY2()+2 ) - { - adjust_wsize.y1_ref()--; - adjust_wsize.y2_ref()--; - - if ( adjust_wsize.y1_ref() < 1 ) - adjust_wsize.y1_ref() = 1; - } - - // reduce the width if not enough space - while ( offset.getX1()+getWidth()-1 > offset.getX2() ) - adjust_wsize.x2_ref()--; - - if ( getWidth() < size_hints.min_width ) - adjust_wsize.setWidth(size_hints.min_width); - - if ( getWidth() <= 0 ) - adjust_wsize.setWidth(1); - - // reduce the height if not enough space - while ( offset.getY1()+getHeight()-1 > offset.getY2() ) - adjust_wsize.y2_ref()--; - - if ( getHeight() < size_hints.min_height ) - adjust_wsize.setWidth(size_hints.min_height); - - if ( getHeight() <= 0 ) - adjust_wsize.setHeight(1); - } - - client_offset.setCoordinates - ( - getTermX() - 1 + padding.left, - getTermY() - 1 + padding.top, - getTermX() - 2 + getWidth() - padding.right, - getTermY() - 2 + getHeight() - padding.bottom - ); - - if ( this->hasChildren() ) - { - FObject::object_list children; - FObject::object_list::const_iterator iter, end; - - children = this->getChildren(); - iter = children.begin(); - end = children.end(); - - while ( iter != end ) - { - FWidget* widget = static_cast(*iter); - - if ( ! widget->isWindowWidget() ) - widget->adjustSize(); - - ++iter; - } - } -} - -//---------------------------------------------------------------------- -void FWidget::adjustSizeGlobal() -{ - if ( ! isRootWidget() ) - { - getRootWidget()->adjustSizeGlobal(); - return; - } - - if ( window_list && ! window_list->empty() ) - { - widgetList::const_iterator iter, end; - iter = window_list->begin(); - end = window_list->end(); - - while ( iter != end ) - { - (*iter)->adjustSize(); - ++iter; - } - } -} - -//---------------------------------------------------------------------- -void FWidget::setStatusBar (FStatusBar* sbar) -{ - if ( ! sbar || statusbar == sbar ) - return; - - if ( statusbar && sbar != 0 ) - delete statusbar; - - statusbar = sbar; -} - -//---------------------------------------------------------------------- -void FWidget::setMenuBar (FMenuBar* mbar) -{ - if ( ! mbar || menubar == mbar ) - return; - - if ( menubar ) - delete menubar; - - menubar = mbar; -} - -//---------------------------------------------------------------------- -bool FWidget::event (FEvent* ev) -{ - switch ( ev->type() ) - { - case fc::KeyPress_Event: - { - FKeyEvent* kev = static_cast(ev); - bool accpt_focus = false; - - if ( kev->key() == fc::Fkey_tab ) - accpt_focus = focusNextChild(); - else if ( kev->key() == fc::Fkey_btab ) - accpt_focus = focusPrevChild(); - - if ( accpt_focus ) - break; - - FWidget* widget = this; - - while ( widget ) - { - widget->onKeyPress(kev); - - if ( ! kev->isAccepted() ) - { - if ( kev->key() == fc::Fkey_right - || kev->key() == fc::Fkey_down ) - accpt_focus = focusNextChild(); - else if ( kev->key() == fc::Fkey_left - || kev->key() == fc::Fkey_up ) - accpt_focus = focusPrevChild(); - - if ( accpt_focus ) - break; - } - - if ( kev->isAccepted() || widget->isRootWidget() ) - break; - - widget = widget->getParentWidget(); - } - } - break; - - case fc::KeyUp_Event: - onKeyUp ( static_cast(ev) ); - break; - - case fc::KeyDown_Event: - { - FKeyEvent* kev = static_cast(ev); - FWidget* widget = this; - - while ( widget ) - { - widget->onKeyDown(kev); - - if ( kev->isAccepted() || widget->isRootWidget() ) - break; - - widget = widget->getParentWidget(); - } - } - break; - - case fc::MouseDown_Event: - onMouseDown ( static_cast(ev) ); - break; - - case fc::MouseUp_Event: - onMouseUp ( static_cast(ev) ); - break; - - case fc::MouseDoubleClick_Event: - onMouseDoubleClick ( static_cast(ev) ); - break; - - case fc::MouseWheel_Event: - onWheel ( static_cast(ev) ); - break; - - case fc::MouseMove_Event: - onMouseMove ( static_cast(ev) ); - break; - - case fc::FocusIn_Event: - onFocusIn ( static_cast(ev) ); - break; - - case fc::FocusOut_Event: - onFocusOut ( static_cast(ev) ); - break; - - case fc::Accelerator_Event: - onAccel ( static_cast(ev) ); - break; - - case fc::Resize_Event: - onResize ( static_cast(ev) ); - break; - - case fc::Show_Event: - onShow ( static_cast(ev) ); - break; - - case fc::Hide_Event: - onHide ( static_cast(ev) ); - break; - - case fc::Close_Event: - onClose ( static_cast(ev) ); - break; - - case fc::Timer_Event: - onTimer ( static_cast(ev) ); - break; - - default: - return false; - } - return true; -} - -//---------------------------------------------------------------------- -void FWidget::onKeyPress (FKeyEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onKeyUp (FKeyEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onKeyDown (FKeyEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onMouseDown (FMouseEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onMouseUp (FMouseEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onMouseDoubleClick (FMouseEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onWheel (FWheelEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onMouseMove (FMouseEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onFocusIn (FFocusEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onFocusOut (FFocusEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onAccel (FAccelEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onResize (FResizeEvent* ev) -{ - rootObject->resize(); - rootObject->redraw(); - ev->accept(); -} - -//---------------------------------------------------------------------- -void FWidget::onShow (FShowEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onHide (FHideEvent*) -{ } - -//---------------------------------------------------------------------- -void FWidget::onClose (FCloseEvent* ev) -{ - ev->accept(); -} - -//---------------------------------------------------------------------- -bool FWidget::focusNextChild() -{ - if ( isDialogWidget() ) - return false; - - if ( hasParent() ) - { - FWidget* parent = static_cast(getParent()); - - if ( parent->hasChildren() && parent->numOfFocusableChildren() > 1 ) - { - FObject::object_list children; - FObject::object_list::iterator iter, end; - - children = parent->getChildren(); - iter = children.begin(); - end = children.end(); - - while ( iter != end ) - { - FWidget* w = static_cast(*iter); - - if ( w == this ) - { - FWidget* next; - FObject::object_list::const_iterator next_element; - next_element = iter; - - do - { - ++next_element; - - if ( next_element == children.end() ) - next_element = children.begin(); - - next = static_cast(*next_element); - } while ( ! next->isEnabled() - || ! next->acceptFocus() - || ! next->isVisible() - || next->isWindowWidget() ); - - FFocusEvent out (fc::FocusOut_Event); - out.setFocusType(fc::FocusNextWidget); - FApplication::sendEvent(this, &out); - - if ( out.isAccepted() ) - { - if ( next == this ) - return false; - - next->setFocus(); - FFocusEvent in (fc::FocusIn_Event); - in.setFocusType(fc::FocusNextWidget); - FApplication::sendEvent(next, &in); - - if ( in.isAccepted() ) - { - this->draw(); - next->draw(); - updateTerminal(); - flush_out(); - } - } - break; - } - ++iter; - } - } - } - return true; -} - -//---------------------------------------------------------------------- -bool FWidget::focusPrevChild() -{ - if ( isDialogWidget() ) - return false; - - if ( hasParent() ) - { - FWidget* parent = static_cast(getParent()); - - if ( parent->hasChildren() && parent->numOfFocusableChildren() > 1 ) - { - FObject::object_list children; - FObject::object_list::iterator iter, begin; - - children = parent->getChildren(); - iter = children.end(); - begin = children.begin(); - - do - { - --iter; - FWidget* w = static_cast(*iter); - - if ( w == this ) - { - FWidget* prev; - FObject::object_list::const_iterator prev_element; - prev_element = iter; - - do - { - if ( prev_element == children.begin() ) - prev_element = children.end(); - - --prev_element; - prev = static_cast(*prev_element); - } while ( ! prev->isEnabled() - || ! prev->acceptFocus() - || ! prev->isVisible() - || prev->isWindowWidget() ); - - FFocusEvent out (fc::FocusOut_Event); - out.setFocusType(fc::FocusPreviousWidget); - FApplication::sendEvent(this, &out); - - if ( out.isAccepted() ) - { - if ( prev == this ) - return false; - - prev->setFocus(); - FFocusEvent in (fc::FocusIn_Event); - in.setFocusType(fc::FocusPreviousWidget); - FApplication::sendEvent(prev, &in); - - if ( in.isAccepted() ) - { - this->draw(); - prev->draw(); - updateTerminal(); - flush_out(); - } - } - - break; - } - } - while ( iter != begin ); - } - } - - return true; -} - // public methods of FWidget //---------------------------------------------------------------------- @@ -873,6 +137,88 @@ FWidget* FWidget::getMainWidget() return main_widget; } +//---------------------------------------------------------------------- +FWidget* FWidget::getFocusWidget() const +{ + FWidget* focus_widget = static_cast(FApplication::focus_widget); + return focus_widget; +} + +//---------------------------------------------------------------------- +FWidget* FWidget::getClickedWidget() +{ + FWidget* clicked_widget = static_cast(FApplication::clicked_widget); + return clicked_widget; +} + +//---------------------------------------------------------------------- +FWidget* FWidget::getMoveSizeWidget() +{ + return FApplication::move_size_widget; +} + +//---------------------------------------------------------------------- +FWidget* FWidget::getOpenMenu() +{ + FWidget* open_menu = static_cast(FApplication::open_menu); + return open_menu; +} + +//---------------------------------------------------------------------- +FMenuBar* FWidget::getMenuBar() +{ + if ( menubar ) + return menubar; + else + return 0; +} + +//---------------------------------------------------------------------- +FStatusBar* FWidget::getStatusBar() +{ + if ( statusbar ) + return statusbar; + else + return 0; +} + +//---------------------------------------------------------------------- +FPoint FWidget::getPrintPos() +{ + const FPoint cur = getPrintCursor(); + int cx = cur.getX(); + int cy = cur.getY(); + return FPoint ( cx - offset.getX1() - getX() + 1 + , cy - offset.getY1() - getY() + 1 ); + +} + +//---------------------------------------------------------------------- +std::vector& FWidget::doubleFlatLine_ref (fc::sides side) +{ + assert ( side == fc::top + || side == fc::right + || side == fc::bottom + || side == fc::left ); + + switch ( side ) + { + case fc::top: + return double_flatline_mask.top; + + case fc::right: + return double_flatline_mask.right; + + case fc::bottom: + return double_flatline_mask.bottom; + + case fc::left: + return double_flatline_mask.left; + } + + return double_flatline_mask.left; +} + //---------------------------------------------------------------------- void FWidget::setMainWidget (FWidget* obj) { @@ -880,6 +226,508 @@ void FWidget::setMainWidget (FWidget* obj) fapp->setMainWidget(obj); } +//---------------------------------------------------------------------- +void FWidget::setFocusWidget (FWidget* obj) +{ + FApplication::focus_widget = obj; +} + +//---------------------------------------------------------------------- +void FWidget::setClickedWidget (FWidget* obj) +{ + FApplication::clicked_widget = obj; +} + +//---------------------------------------------------------------------- +void FWidget::setMoveSizeWidget (FWidget* obj) +{ + FApplication::move_size_widget = obj; +} + +//---------------------------------------------------------------------- +void FWidget::setOpenMenu (FWidget* obj) +{ + FApplication::open_menu = obj; +} + +//---------------------------------------------------------------------- +void FWidget::setStatusbarMessage (FString msg) +{ + statusbar_message = msg; +} + +//---------------------------------------------------------------------- +bool FWidget::setFocus (bool on) +{ + FWindow* window; + + if ( ! enable ) + return false; + + if ( on == focus ) + return true; + + // set widget focus + if ( on && ! focus ) + { + int focusable_children = numOfFocusableChildren(); + + if ( FWidget::getFocusWidget() ) + FWidget::getFocusWidget()->unsetFocus(); + + if ( (!isDialogWidget() && focusable_children == 0) + || (isDialogWidget() && focusable_children == 1) ) + { + FWidget::setFocusWidget(this); + } + } + + window = FWindow::getWindowWidget(this); + + // set window focus + if ( on && window ) + { + if ( ! window->isWindowActive() ) + { + bool has_raised = window->raiseWindow(); + FWindow::setActiveWindow(window); + + if ( has_raised && window->isVisible() && window->isShown() ) + window->redraw(); + } + window->setWindowFocusWidget(this); + } + + return focus = (on) ? true : false; +} + +//---------------------------------------------------------------------- +void FWidget::setColor () +{ + // Changes colors to the widget default colors + setColor (foreground_color, background_color); +} + +//---------------------------------------------------------------------- +void FWidget::setX (int x, bool adjust) +{ + if ( getX() == x && wsize.getX() == x ) + return; + + if ( ! isWindowWidget() && x < 1 ) + x = 1; + + wsize.setX(x); + adjust_wsize.setX(x); + + if ( adjust ) + adjustSize(); +} + +//---------------------------------------------------------------------- +void FWidget::setY (int y, bool adjust) +{ + if ( getY() == y && wsize.getY() == y ) + return; + + if ( ! isWindowWidget() && y < 1 ) + y = 1; + + wsize.setY(y); + adjust_wsize.setY(y); + + if ( adjust ) + adjustSize(); +} + +//---------------------------------------------------------------------- +void FWidget::setPos (int x, int y, bool adjust) +{ + if ( getX() == x && wsize.getX() == x + && getY() == y && wsize.getY() == y ) + { + return; + } + + if ( ! isWindowWidget() ) + { + if ( x < 1 ) + x = 1; + + if ( y < 1 ) + y = 1; + } + + wsize.setPos(x,y); + adjust_wsize.setPos(x,y); + + if ( adjust ) + adjustSize(); +} + +//---------------------------------------------------------------------- +void FWidget::setWidth (int width, bool adjust) +{ + width = std::min (width, size_hints.max_width); + width = std::max (width, size_hints.min_width); + + if ( getWidth() == width && wsize.getWidth() == width ) + return; + + if ( width < 1 ) + width = 1; + + wsize.setWidth(width); + adjust_wsize.setWidth(width); + + if ( adjust ) + adjustSize(); + + double_flatline_mask.top.resize (uLong(getWidth()), false); + double_flatline_mask.bottom.resize (uLong(getWidth()), false); +} + +//---------------------------------------------------------------------- +void FWidget::setHeight (int height, bool adjust) +{ + height = std::min (height, size_hints.max_height); + height = std::max (height, size_hints.min_height); + + if ( getHeight() == height && wsize.getHeight() == height ) + return; + + if ( height < 1 ) + height = 1; + + wsize.setHeight(height); + adjust_wsize.setHeight(height); + + if ( adjust ) + adjustSize(); + + double_flatline_mask.right.resize (uLong(getHeight()), false); + double_flatline_mask.left.resize (uLong(getHeight()), false); +} + +//---------------------------------------------------------------------- +void FWidget::setSize (int width, int height, bool adjust) +{ + width = std::min (width, size_hints.max_width); + width = std::max (width, size_hints.min_width); + height = std::min (height, size_hints.max_height); + height = std::max (height, size_hints.min_height); + + if ( getWidth() == width && wsize.getWidth() == width + && getHeight() == height && wsize.getHeight() == height ) + return; + + if ( width < 1 ) + width = 1; + + if ( height < 1 ) + height = 1; + + wsize.setWidth(width); + wsize.setHeight(height); + adjust_wsize.setWidth(width); + adjust_wsize.setHeight(height); + + if ( adjust ) + adjustSize(); + + double_flatline_mask.top.resize (uLong(getWidth()), false); + double_flatline_mask.right.resize (uLong(getHeight()), false); + double_flatline_mask.bottom.resize (uLong(getWidth()), false); + double_flatline_mask.left.resize (uLong(getHeight()), false); +} + +//---------------------------------------------------------------------- +void FWidget::setTopPadding (int top, bool adjust) +{ + if ( padding.top == top ) + return; + + (top < 0) ? padding.top = 0 : padding.top = top; + + if ( adjust ) + { + if ( isRootWidget() ) + { + FWidget* r = rootObject; + r->client_offset.setY1 (r->padding.top); + adjustSizeGlobal(); + } + else + adjustSize(); + } +} + +//---------------------------------------------------------------------- +void FWidget::setLeftPadding (int left, bool adjust) +{ + if ( padding.left == left ) + return; + + (left < 0) ? padding.left = 0 : padding.left = left; + + if ( adjust ) + { + if ( isRootWidget() ) + { + FWidget* r = rootObject; + r->client_offset.setX1 (r->padding.left); + adjustSizeGlobal(); + } + else + adjustSize(); + } +} + +//---------------------------------------------------------------------- +void FWidget::setBottomPadding (int bottom, bool adjust) +{ + if ( padding.bottom == bottom ) + return; + + (bottom < 0) ? padding.bottom = 0 : padding.bottom = bottom; + + if ( adjust ) + { + if ( isRootWidget() ) + { + FWidget* r = rootObject; + r->client_offset.setY2 (r->getHeight() - 1 - r->padding.bottom); + adjustSizeGlobal(); + } + else + adjustSize(); + } +} + +//---------------------------------------------------------------------- +void FWidget::setRightPadding (int right, bool adjust) +{ + if ( padding.right == right ) + return; + + (right < 0) ? padding.right = 0 : padding.right = right; + + if ( adjust ) + { + if ( isRootWidget() ) + { + FWidget* r = rootObject; + r->client_offset.setX2 (r->getWidth() - 1 - r->padding.right); + adjustSizeGlobal(); + } + else + adjustSize(); + } +} + +//---------------------------------------------------------------------- +void FWidget::setParentOffset() +{ + FWidget* p = getParentWidget(); + + if ( p ) + offset = p->client_offset; +} + +//---------------------------------------------------------------------- +void FWidget::setTermOffset() +{ + FWidget* r = getRootWidget(); + int w = r->getWidth(); + int h = r->getHeight(); + offset.setCoordinates (0, 0, w - 1, h - 1); +} + +//---------------------------------------------------------------------- +void FWidget::setTermOffsetWithPadding() +{ + FWidget* r = getRootWidget(); + offset.setCoordinates ( r->getLeftPadding() + , r->getTopPadding() + , r->getWidth() - 1 - r->getRightPadding() + , r->getHeight() - 1 - r->getBottomPadding() ); +} + +//---------------------------------------------------------------------- +void FWidget::setTermSize (int w, int h) +{ + // Set xterm size to w x h + if ( isXTerminal() ) + { + rootObject->wsize.setRect(1, 1, w, h); + rootObject->adjust_wsize = rootObject->wsize; + FTerm::setTermSize (w, h); // w = columns / h = lines + detectTermSize(); + } +} + +//---------------------------------------------------------------------- +void FWidget::setGeometry (int x, int y, int w, int h, bool adjust) +{ + int term_x, term_y; + + w = std::min (w, size_hints.max_width); + w = std::max (w, size_hints.min_width); + h = std::min (h, size_hints.max_height); + h = std::max (h, size_hints.min_height); + + if ( getX() == x && getY() == y && getWidth() == w && getHeight() == h ) + return; + + if ( ! isWindowWidget() ) + { + (x < 1) ? wsize.setX(1) : wsize.setX(x); + (y < 1) ? wsize.setY(1) : wsize.setY(y); + } + else + { + wsize.setX(x); + wsize.setY(y); + } + + (w < 1) ? wsize.setWidth(1) : wsize.setWidth(w); + (h < 1) ? wsize.setHeight(1) : wsize.setHeight(h); + + adjust_wsize = wsize; + term_x = getTermX(); + term_y = getTermY(); + + client_offset.setCoordinates ( term_x - 1 + padding.left + , term_y - 1 + padding.top + , term_x - 2 + getWidth() - padding.right + , term_y - 2 + getHeight() - padding.bottom ); + + double_flatline_mask.top.resize (uLong(getWidth()), false); + double_flatline_mask.right.resize (uLong(getHeight()), false); + double_flatline_mask.bottom.resize (uLong(getWidth()), false); + double_flatline_mask.left.resize (uLong(getHeight()), false); + + if ( adjust ) + adjustSize(); +} + +//---------------------------------------------------------------------- +bool FWidget::setCursorPos (register int x, register int y) +{ + // sets the input cursor position + widget_cursor_position.setPoint(x,y); + + if ( (flags & fc::focus) != 0 && ! isWindowWidget() ) + { + FWidget* window = FWindow::getWindowWidget(this); + + if ( window ) + { + if ( term_area* area = window->getVWin() ) + { + setAreaCursor ( getTermX() - window->getTermX() + x + , getTermY() - window->getTermY() + y + , visible_cursor + , area ); + return true; + } + } + } + + return false; +} + +//---------------------------------------------------------------------- +void FWidget::setPrintPos (register int x, register int y) +{ + setPrintCursor ( offset.getX1() + getX() + x - 1, + offset.getY1() + getY() + y - 1 ); +} + +//---------------------------------------------------------------------- +void FWidget::setDoubleFlatLine (fc::sides side, bool bit) +{ + uLong length; + + assert ( side == fc::top + || side == fc::right + || side == fc::bottom + || side == fc::left ); + + switch ( side ) + { + case fc::top: + length = double_flatline_mask.top.size(); + double_flatline_mask.top.assign(length, bit); + break; + + case fc::right: + length = double_flatline_mask.right.size(); + double_flatline_mask.right.assign(length, bit); + break; + + case fc::bottom: + length = double_flatline_mask.bottom.size(); + double_flatline_mask.bottom.assign(length, bit); + break; + + case fc::left: + length = double_flatline_mask.left.size(); + double_flatline_mask.left.assign(length, bit); + break; + } +} + +//---------------------------------------------------------------------- +void FWidget::setDoubleFlatLine (fc::sides side, int pos, bool bit) +{ + uLong length, index; + + assert ( side == fc::top + || side == fc::right + || side == fc::bottom + || side == fc::left ); + + assert ( pos >= 1 ); + + index = uLong(pos - 1); + + switch ( side ) + { + case fc::top: + length = double_flatline_mask.top.size(); + + if ( index < length ) + double_flatline_mask.top[index] = bit; + + break; + + case fc::right: + length = double_flatline_mask.right.size(); + + if ( index < length ) + double_flatline_mask.right[index] = bit; + + break; + + case fc::bottom: + length = double_flatline_mask.bottom.size(); + + if ( index < length ) + double_flatline_mask.bottom[index] = bit; + + break; + + case fc::left: + length = double_flatline_mask.left.size(); + + if ( index < length ) + double_flatline_mask.left[index] = bit; + + break; + } +} + //---------------------------------------------------------------------- FWidget* FWidget::childWidgetAt (FWidget* p, int x, int y) { @@ -912,57 +760,6 @@ FWidget* FWidget::childWidgetAt (FWidget* p, int x, int y) return 0; } -//---------------------------------------------------------------------- -FWidget* FWidget::getFocusWidget() const -{ - FWidget* focus_widget = static_cast(FApplication::focus_widget); - return focus_widget; -} - -//---------------------------------------------------------------------- -void FWidget::setFocusWidget (FWidget* obj) -{ - FApplication::focus_widget = obj; -} - -//---------------------------------------------------------------------- -FWidget* FWidget::getClickedWidget() -{ - FWidget* clicked_widget = static_cast(FApplication::clicked_widget); - return clicked_widget; -} - -//---------------------------------------------------------------------- -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() -{ - FWidget* open_menu = static_cast(FApplication::open_menu); - return open_menu; -} - -//---------------------------------------------------------------------- -void FWidget::setOpenMenu (FWidget* obj) -{ - FApplication::open_menu = obj; -} - //---------------------------------------------------------------------- int FWidget::numOfFocusableChildren() { @@ -1013,30 +810,6 @@ bool FWidget::close() return false; } -//---------------------------------------------------------------------- -FStatusBar* FWidget::statusBar() -{ - if ( statusbar ) - return statusbar; - else - return 0; -} - -//---------------------------------------------------------------------- -FMenuBar* FWidget::menuBar() -{ - if ( menubar ) - return menubar; - else - return 0; -} - -//---------------------------------------------------------------------- -void FWidget::setStatusbarMessage (FString msg) -{ - statusbar_message = msg; -} - //---------------------------------------------------------------------- void FWidget::addCallback ( FString cb_signal , FWidget::FCallback cb_handler @@ -1382,30 +1155,6 @@ void FWidget::hide() } } -//---------------------------------------------------------------------- -bool FWidget::setEnable (bool on) -{ - return enable = (on) ? true : false; -} - -//---------------------------------------------------------------------- -bool FWidget::setEnable() -{ - return setEnable(true); -} - -//---------------------------------------------------------------------- -bool FWidget::unsetEnable() -{ - return setEnable(false); -} - -//---------------------------------------------------------------------- -bool FWidget::setDisable() -{ - return setEnable(false); -} - //---------------------------------------------------------------------- bool FWidget::focusFirstChild() { @@ -1486,303 +1235,6 @@ bool FWidget::focusLastChild() return false; } -//---------------------------------------------------------------------- -bool FWidget::setFocus (bool on) -{ - FWindow* window; - - if ( ! enable ) - return false; - - if ( on == focus ) - return true; - - // set widget focus - if ( on && ! focus ) - { - int focusable_children = numOfFocusableChildren(); - - if ( FWidget::getFocusWidget() ) - FWidget::getFocusWidget()->unsetFocus(); - - if ( (!isDialogWidget() && focusable_children == 0) - || (isDialogWidget() && focusable_children == 1) ) - { - FWidget::setFocusWidget(this); - } - } - - window = FWindow::getWindowWidget(this); - - // set window focus - if ( on && window ) - { - if ( ! window->isWindowActive() ) - { - bool has_raised = window->raiseWindow(); - FWindow::setActiveWindow(window); - - if ( has_raised && window->isVisible() && window->isShown() ) - window->redraw(); - } - window->setWindowFocusWidget(this); - } - - return focus = (on) ? true : false; -} - -//---------------------------------------------------------------------- -void FWidget::setColor () -{ - // Changes colors to the widget default colors - setColor (foreground_color, background_color); -} - -//---------------------------------------------------------------------- -void FWidget::setX (int x, bool adjust) -{ - if ( getX() == x && wsize.getX() == x ) - return; - - if ( ! isWindowWidget() && x < 1 ) - x = 1; - - wsize.setX(x); - adjust_wsize.setX(x); - - if ( adjust ) - adjustSize(); -} - -//---------------------------------------------------------------------- -void FWidget::setY (int y, bool adjust) -{ - if ( getY() == y && wsize.getY() == y ) - return; - - if ( ! isWindowWidget() && y < 1 ) - y = 1; - - wsize.setY(y); - adjust_wsize.setY(y); - - if ( adjust ) - adjustSize(); -} - -//---------------------------------------------------------------------- -void FWidget::setPos (int x, int y, bool adjust) -{ - if ( getX() == x && wsize.getX() == x - && getY() == y && wsize.getY() == y ) - { - return; - } - - if ( ! isWindowWidget() ) - { - if ( x < 1 ) - x = 1; - - if ( y < 1 ) - y = 1; - } - - wsize.setPos(x,y); - adjust_wsize.setPos(x,y); - - if ( adjust ) - adjustSize(); -} - -//---------------------------------------------------------------------- -void FWidget::setWidth (int width, bool adjust) -{ - width = std::min (width, size_hints.max_width); - width = std::max (width, size_hints.min_width); - - if ( getWidth() == width && wsize.getWidth() == width ) - return; - - if ( width < 1 ) - width = 1; - - wsize.setWidth(width); - adjust_wsize.setWidth(width); - - if ( adjust ) - adjustSize(); - - double_flatline_mask.top.resize (uLong(getWidth()), false); - double_flatline_mask.bottom.resize (uLong(getWidth()), false); -} - -//---------------------------------------------------------------------- -void FWidget::setHeight (int height, bool adjust) -{ - height = std::min (height, size_hints.max_height); - height = std::max (height, size_hints.min_height); - - if ( getHeight() == height && wsize.getHeight() == height ) - return; - - if ( height < 1 ) - height = 1; - - wsize.setHeight(height); - adjust_wsize.setHeight(height); - - if ( adjust ) - adjustSize(); - - double_flatline_mask.right.resize (uLong(getHeight()), false); - double_flatline_mask.left.resize (uLong(getHeight()), false); -} - -//---------------------------------------------------------------------- -void FWidget::setSize (int width, int height, bool adjust) -{ - width = std::min (width, size_hints.max_width); - width = std::max (width, size_hints.min_width); - height = std::min (height, size_hints.max_height); - height = std::max (height, size_hints.min_height); - - if ( getWidth() == width && wsize.getWidth() == width - && getHeight() == height && wsize.getHeight() == height ) - return; - - if ( width < 1 ) - width = 1; - - if ( height < 1 ) - height = 1; - - wsize.setWidth(width); - wsize.setHeight(height); - adjust_wsize.setWidth(width); - adjust_wsize.setHeight(height); - - if ( adjust ) - adjustSize(); - - double_flatline_mask.top.resize (uLong(getWidth()), false); - double_flatline_mask.right.resize (uLong(getHeight()), false); - double_flatline_mask.bottom.resize (uLong(getWidth()), false); - double_flatline_mask.left.resize (uLong(getHeight()), false); -} - -//---------------------------------------------------------------------- -void FWidget::setTopPadding (int top, bool adjust) -{ - if ( padding.top == top ) - return; - - (top < 0) ? padding.top = 0 : padding.top = top; - - if ( adjust ) - { - if ( isRootWidget() ) - { - FWidget* r = rootObject; - r->client_offset.setY1 (r->padding.top); - adjustSizeGlobal(); - } - else - adjustSize(); - } -} - -//---------------------------------------------------------------------- -void FWidget::setLeftPadding (int left, bool adjust) -{ - if ( padding.left == left ) - return; - - (left < 0) ? padding.left = 0 : padding.left = left; - - if ( adjust ) - { - if ( isRootWidget() ) - { - FWidget* r = rootObject; - r->client_offset.setX1 (r->padding.left); - adjustSizeGlobal(); - } - else - adjustSize(); - } -} - -//---------------------------------------------------------------------- -void FWidget::setBottomPadding (int bottom, bool adjust) -{ - if ( padding.bottom == bottom ) - return; - - (bottom < 0) ? padding.bottom = 0 : padding.bottom = bottom; - - if ( adjust ) - { - if ( isRootWidget() ) - { - FWidget* r = rootObject; - r->client_offset.setY2 (r->getHeight() - 1 - r->padding.bottom); - adjustSizeGlobal(); - } - else - adjustSize(); - } -} - -//---------------------------------------------------------------------- -void FWidget::setRightPadding (int right, bool adjust) -{ - if ( padding.right == right ) - return; - - (right < 0) ? padding.right = 0 : padding.right = right; - - if ( adjust ) - { - if ( isRootWidget() ) - { - FWidget* r = rootObject; - r->client_offset.setX2 (r->getWidth() - 1 - r->padding.right); - adjustSizeGlobal(); - } - else - adjustSize(); - } -} - -//---------------------------------------------------------------------- -void FWidget::setParentOffset() -{ - FWidget* p = getParentWidget(); - - if ( p ) - offset = p->client_offset; -} - -//---------------------------------------------------------------------- -void FWidget::setTermOffset() -{ - FWidget* r = getRootWidget(); - int w = r->getWidth(); - int h = r->getHeight(); - offset.setCoordinates (0, 0, w - 1, h - 1); -} - -//---------------------------------------------------------------------- -void FWidget::setTermOffsetWithPadding() -{ - FWidget* r = getRootWidget(); - offset.setCoordinates ( r->getLeftPadding() - , r->getTopPadding() - , r->getWidth() - 1 - r->getRightPadding() - , r->getHeight() - 1 - r->getBottomPadding() ); -} - //---------------------------------------------------------------------- void FWidget::detectTermSize() { @@ -1799,64 +1251,6 @@ void FWidget::detectTermSize() ); } -//---------------------------------------------------------------------- -void FWidget::setTermSize (int w, int h) -{ - // Set xterm size to w x h - if ( isXTerminal() ) - { - rootObject->wsize.setRect(1, 1, w, h); - rootObject->adjust_wsize = rootObject->wsize; - FTerm::setTermSize (w, h); // w = columns / h = lines - detectTermSize(); - } -} - -//---------------------------------------------------------------------- -void FWidget::setGeometry (int x, int y, int w, int h, bool adjust) -{ - int term_x, term_y; - - w = std::min (w, size_hints.max_width); - w = std::max (w, size_hints.min_width); - h = std::min (h, size_hints.max_height); - h = std::max (h, size_hints.min_height); - - if ( getX() == x && getY() == y && getWidth() == w && getHeight() == h ) - return; - - if ( ! isWindowWidget() ) - { - (x < 1) ? wsize.setX(1) : wsize.setX(x); - (y < 1) ? wsize.setY(1) : wsize.setY(y); - } - else - { - wsize.setX(x); - wsize.setY(y); - } - - (w < 1) ? wsize.setWidth(1) : wsize.setWidth(w); - (h < 1) ? wsize.setHeight(1) : wsize.setHeight(h); - - adjust_wsize = wsize; - term_x = getTermX(); - term_y = getTermY(); - - client_offset.setCoordinates ( term_x - 1 + padding.left - , term_y - 1 + padding.top - , term_x - 2 + getWidth() - padding.right - , term_y - 2 + getHeight() - padding.bottom ); - - double_flatline_mask.top.resize (uLong(getWidth()), false); - double_flatline_mask.right.resize (uLong(getHeight()), false); - double_flatline_mask.bottom.resize (uLong(getWidth()), false); - double_flatline_mask.left.resize (uLong(getHeight()), false); - - if ( adjust ) - adjustSize(); -} - //---------------------------------------------------------------------- void FWidget::move (int dx, int dy) { @@ -1864,50 +1258,6 @@ void FWidget::move (int dx, int dy) adjust_wsize.move(dx,dy); } -//---------------------------------------------------------------------- -bool FWidget::setCursorPos (register int x, register int y) -{ - // sets the input cursor position - widget_cursor_position.setPoint(x,y); - - if ( (flags & fc::focus) != 0 && ! isWindowWidget() ) - { - FWidget* window = FWindow::getWindowWidget(this); - - if ( window ) - { - if ( term_area* area = window->getVWin() ) - { - setAreaCursor ( getTermX() - window->getTermX() + x - , getTermY() - window->getTermY() + y - , visible_cursor - , area ); - return true; - } - } - } - - return false; -} - -//---------------------------------------------------------------------- -void FWidget::setPrintPos (register int x, register int y) -{ - setPrintCursor ( offset.getX1() + getX() + x - 1, - offset.getY1() + getY() + y - 1 ); -} - -//---------------------------------------------------------------------- -FPoint FWidget::getPrintPos() -{ - const FPoint cur = getPrintCursor(); - int cx = cur.getX(); - int cy = cur.getY(); - return FPoint ( cx - offset.getX1() - getX() + 1 - , cy - offset.getY1() - getY() + 1 ); - -} - //---------------------------------------------------------------------- void FWidget::drawShadow() { @@ -2182,121 +1532,6 @@ void FWidget::clearFlatBorder() } } -//---------------------------------------------------------------------- -void FWidget::setDoubleFlatLine (int side, bool bit) -{ - uLong length; - - assert ( side == fc::top - || side == fc::right - || side == fc::bottom - || side == fc::left ); - - switch ( side ) - { - case fc::top: - length = double_flatline_mask.top.size(); - double_flatline_mask.top.assign(length, bit); - break; - - case fc::right: - length = double_flatline_mask.right.size(); - double_flatline_mask.right.assign(length, bit); - break; - - case fc::bottom: - length = double_flatline_mask.bottom.size(); - double_flatline_mask.bottom.assign(length, bit); - break; - - case fc::left: - length = double_flatline_mask.left.size(); - double_flatline_mask.left.assign(length, bit); - break; - - default: - break; - } -} - -//---------------------------------------------------------------------- -void FWidget::setDoubleFlatLine (int side, int pos, bool bit) -{ - uLong length, index; - - assert ( side == fc::top - || side == fc::right - || side == fc::bottom - || side == fc::left ); - - assert ( pos >= 1 ); - - index = uLong(pos - 1); - - switch ( side ) - { - case fc::top: - length = double_flatline_mask.top.size(); - - if ( index < length ) - double_flatline_mask.top[index] = bit; - - break; - - case fc::right: - length = double_flatline_mask.right.size(); - - if ( index < length ) - double_flatline_mask.right[index] = bit; - - break; - - case fc::bottom: - length = double_flatline_mask.bottom.size(); - - if ( index < length ) - double_flatline_mask.bottom[index] = bit; - - break; - - case fc::left: - length = double_flatline_mask.left.size(); - - if ( index < length ) - double_flatline_mask.left[index] = bit; - - break; - - default: - break; - } -} - -//---------------------------------------------------------------------- -std::vector& FWidget::doubleFlatLine_ref (int side) -{ - assert ( side == fc::top - || side == fc::right - || side == fc::bottom - || side == fc::left ); - - switch ( side ) - { - case fc::top: - return double_flatline_mask.top; - - case fc::right: - return double_flatline_mask.right; - - case fc::bottom: - return double_flatline_mask.bottom; - - case fc::left: - default: - return double_flatline_mask.left; - } -} - //---------------------------------------------------------------------- void FWidget::drawBorder (int x1, int y1, int x2, int y2) { @@ -2386,3 +1621,740 @@ void FWidget::quit() FApplication* fapp = static_cast(rootObject); fapp->exit(0); } + + +// protected methods of FWidget +//---------------------------------------------------------------------- +void FWidget::setStatusBar (FStatusBar* sbar) +{ + if ( ! sbar || statusbar == sbar ) + return; + + if ( statusbar && sbar != 0 ) + delete statusbar; + + statusbar = sbar; +} + +//---------------------------------------------------------------------- +void FWidget::setMenuBar (FMenuBar* mbar) +{ + if ( ! mbar || menubar == mbar ) + return; + + if ( menubar ) + delete menubar; + + menubar = mbar; +} + +//---------------------------------------------------------------------- +void FWidget::adjustSize() +{ + if ( ! isRootWidget() ) + { + FWidget* p = getParentWidget(); + + if ( isWindowWidget() ) + { + if ( ignore_padding && ! isDialogWidget() ) + setTermOffset(); + else + offset = rootObject->client_offset; + } + else if ( ignore_padding && p ) + { + offset.setCoordinates ( p->getTermX() - 1 + , p->getTermY() - 1 + , p->getTermX() + p->getWidth() - 2 + , p->getTermY() + p->getHeight() - 2 ); + } + else if ( p ) + offset = p->client_offset; + + adjust_wsize = wsize; + } + + if ( ! isWindowWidget() ) + { + // move left if not enough space + while ( getTermX()+getWidth()-padding.right > offset.getX2()+2 ) + { + adjust_wsize.x1_ref()--; + adjust_wsize.x2_ref()--; + + if ( adjust_wsize.x1_ref() < 1 ) + adjust_wsize.x1_ref() = 1; + } + + // move up if not enough space + while ( getTermY()+getHeight()-padding.bottom > offset.getY2()+2 ) + { + adjust_wsize.y1_ref()--; + adjust_wsize.y2_ref()--; + + if ( adjust_wsize.y1_ref() < 1 ) + adjust_wsize.y1_ref() = 1; + } + + // reduce the width if not enough space + while ( offset.getX1()+getWidth()-1 > offset.getX2() ) + adjust_wsize.x2_ref()--; + + if ( getWidth() < size_hints.min_width ) + adjust_wsize.setWidth(size_hints.min_width); + + if ( getWidth() <= 0 ) + adjust_wsize.setWidth(1); + + // reduce the height if not enough space + while ( offset.getY1()+getHeight()-1 > offset.getY2() ) + adjust_wsize.y2_ref()--; + + if ( getHeight() < size_hints.min_height ) + adjust_wsize.setWidth(size_hints.min_height); + + if ( getHeight() <= 0 ) + adjust_wsize.setHeight(1); + } + + client_offset.setCoordinates + ( + getTermX() - 1 + padding.left, + getTermY() - 1 + padding.top, + getTermX() - 2 + getWidth() - padding.right, + getTermY() - 2 + getHeight() - padding.bottom + ); + + if ( this->hasChildren() ) + { + FObject::object_list children; + FObject::object_list::const_iterator iter, end; + + children = this->getChildren(); + iter = children.begin(); + end = children.end(); + + while ( iter != end ) + { + FWidget* widget = static_cast(*iter); + + if ( ! widget->isWindowWidget() ) + widget->adjustSize(); + + ++iter; + } + } +} + +//---------------------------------------------------------------------- +void FWidget::adjustSizeGlobal() +{ + if ( ! isRootWidget() ) + { + getRootWidget()->adjustSizeGlobal(); + return; + } + + if ( window_list && ! window_list->empty() ) + { + widgetList::const_iterator iter, end; + iter = window_list->begin(); + end = window_list->end(); + + while ( iter != end ) + { + (*iter)->adjustSize(); + ++iter; + } + } +} + +//---------------------------------------------------------------------- +bool FWidget::focusNextChild() +{ + if ( isDialogWidget() ) + return false; + + if ( hasParent() ) + { + FWidget* parent = static_cast(getParent()); + + if ( parent->hasChildren() && parent->numOfFocusableChildren() > 1 ) + { + FObject::object_list children; + FObject::object_list::iterator iter, end; + + children = parent->getChildren(); + iter = children.begin(); + end = children.end(); + + while ( iter != end ) + { + FWidget* w = static_cast(*iter); + + if ( w == this ) + { + FWidget* next; + FObject::object_list::const_iterator next_element; + next_element = iter; + + do + { + ++next_element; + + if ( next_element == children.end() ) + next_element = children.begin(); + + next = static_cast(*next_element); + } while ( ! next->isEnabled() + || ! next->acceptFocus() + || ! next->isVisible() + || next->isWindowWidget() ); + + FFocusEvent out (fc::FocusOut_Event); + out.setFocusType(fc::FocusNextWidget); + FApplication::sendEvent(this, &out); + + if ( out.isAccepted() ) + { + if ( next == this ) + return false; + + next->setFocus(); + FFocusEvent in (fc::FocusIn_Event); + in.setFocusType(fc::FocusNextWidget); + FApplication::sendEvent(next, &in); + + if ( in.isAccepted() ) + { + this->draw(); + next->draw(); + updateTerminal(); + flush_out(); + } + } + break; + } + ++iter; + } + } + } + return true; +} + +//---------------------------------------------------------------------- +bool FWidget::focusPrevChild() +{ + if ( isDialogWidget() ) + return false; + + if ( hasParent() ) + { + FWidget* parent = static_cast(getParent()); + + if ( parent->hasChildren() && parent->numOfFocusableChildren() > 1 ) + { + FObject::object_list children; + FObject::object_list::iterator iter, begin; + + children = parent->getChildren(); + iter = children.end(); + begin = children.begin(); + + do + { + --iter; + FWidget* w = static_cast(*iter); + + if ( w == this ) + { + FWidget* prev; + FObject::object_list::const_iterator prev_element; + prev_element = iter; + + do + { + if ( prev_element == children.begin() ) + prev_element = children.end(); + + --prev_element; + prev = static_cast(*prev_element); + } while ( ! prev->isEnabled() + || ! prev->acceptFocus() + || ! prev->isVisible() + || prev->isWindowWidget() ); + + FFocusEvent out (fc::FocusOut_Event); + out.setFocusType(fc::FocusPreviousWidget); + FApplication::sendEvent(this, &out); + + if ( out.isAccepted() ) + { + if ( prev == this ) + return false; + + prev->setFocus(); + FFocusEvent in (fc::FocusIn_Event); + in.setFocusType(fc::FocusPreviousWidget); + FApplication::sendEvent(prev, &in); + + if ( in.isAccepted() ) + { + this->draw(); + prev->draw(); + updateTerminal(); + flush_out(); + } + } + + break; + } + } + while ( iter != begin ); + } + } + + return true; +} + +//---------------------------------------------------------------------- +bool FWidget::event (FEvent* ev) +{ + switch ( ev->type() ) + { + case fc::KeyPress_Event: + { + FKeyEvent* kev = static_cast(ev); + bool accpt_focus = false; + + if ( kev->key() == fc::Fkey_tab ) + accpt_focus = focusNextChild(); + else if ( kev->key() == fc::Fkey_btab ) + accpt_focus = focusPrevChild(); + + if ( accpt_focus ) + break; + + FWidget* widget = this; + + while ( widget ) + { + widget->onKeyPress(kev); + + if ( ! kev->isAccepted() ) + { + if ( kev->key() == fc::Fkey_right + || kev->key() == fc::Fkey_down ) + accpt_focus = focusNextChild(); + else if ( kev->key() == fc::Fkey_left + || kev->key() == fc::Fkey_up ) + accpt_focus = focusPrevChild(); + + if ( accpt_focus ) + break; + } + + if ( kev->isAccepted() || widget->isRootWidget() ) + break; + + widget = widget->getParentWidget(); + } + } + break; + + case fc::KeyUp_Event: + onKeyUp ( static_cast(ev) ); + break; + + case fc::KeyDown_Event: + { + FKeyEvent* kev = static_cast(ev); + FWidget* widget = this; + + while ( widget ) + { + widget->onKeyDown(kev); + + if ( kev->isAccepted() || widget->isRootWidget() ) + break; + + widget = widget->getParentWidget(); + } + } + break; + + case fc::MouseDown_Event: + onMouseDown ( static_cast(ev) ); + break; + + case fc::MouseUp_Event: + onMouseUp ( static_cast(ev) ); + break; + + case fc::MouseDoubleClick_Event: + onMouseDoubleClick ( static_cast(ev) ); + break; + + case fc::MouseWheel_Event: + onWheel ( static_cast(ev) ); + break; + + case fc::MouseMove_Event: + onMouseMove ( static_cast(ev) ); + break; + + case fc::FocusIn_Event: + onFocusIn ( static_cast(ev) ); + break; + + case fc::FocusOut_Event: + onFocusOut ( static_cast(ev) ); + break; + + case fc::Accelerator_Event: + onAccel ( static_cast(ev) ); + break; + + case fc::Resize_Event: + onResize ( static_cast(ev) ); + break; + + case fc::Show_Event: + onShow ( static_cast(ev) ); + break; + + case fc::Hide_Event: + onHide ( static_cast(ev) ); + break; + + case fc::Close_Event: + onClose ( static_cast(ev) ); + break; + + case fc::Timer_Event: + onTimer ( static_cast(ev) ); + break; + + default: + return false; + } + return true; +} + +//---------------------------------------------------------------------- +void FWidget::onKeyPress (FKeyEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onKeyUp (FKeyEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onKeyDown (FKeyEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onMouseDown (FMouseEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onMouseUp (FMouseEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onMouseDoubleClick (FMouseEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onWheel (FWheelEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onMouseMove (FMouseEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onFocusIn (FFocusEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onFocusOut (FFocusEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onAccel (FAccelEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onResize (FResizeEvent* ev) +{ + rootObject->resize(); + rootObject->redraw(); + ev->accept(); +} + +//---------------------------------------------------------------------- +void FWidget::onShow (FShowEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onHide (FHideEvent*) +{ } + +//---------------------------------------------------------------------- +void FWidget::onClose (FCloseEvent* ev) +{ + ev->accept(); +} + + +// private methods of FWidget +//---------------------------------------------------------------------- +void FWidget::init() +{ + 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 + detectTermSize(); + wsize.setRect(1, 1, getColumnNumber(), getLineNumber()); + adjust_wsize = wsize; + offset.setRect(0, 0, getColumnNumber(), getLineNumber()); + client_offset = offset; + + double_flatline_mask.top.resize (uLong(getWidth()), false); + double_flatline_mask.right.resize (uLong(getHeight()), false); + double_flatline_mask.bottom.resize (uLong(getWidth()), false); + double_flatline_mask.left.resize (uLong(getHeight()), false); + + // Initialize default widget colors + setColorTheme(); + + foreground_color = wc.term_fg; + background_color = wc.term_bg; + setColor(); + clearArea (vdesktop); + + accelerator_list = new Accelerators(); +} + +//---------------------------------------------------------------------- +void FWidget::finish() +{ + delete accelerator_list; + accelerator_list = 0; + + if ( close_widget ) + { + delete close_widget; + close_widget = 0; + } + + if ( dialog_list ) + { + delete dialog_list; + dialog_list = 0; + } + + if ( always_on_top_list ) + { + delete always_on_top_list; + always_on_top_list = 0; + } + + if ( window_list ) + { + delete window_list; + window_list = 0; + } +} + +//---------------------------------------------------------------------- +void FWidget::draw() +{ } + +//---------------------------------------------------------------------- +void FWidget::setColorTheme() +{ + wc.term_fg = fc::Black; + wc.term_bg = fc::LightBlue; + wc.list_fg = fc::Black; + wc.list_bg = fc::White; + wc.selected_list_fg = fc::Cyan; + wc.selected_list_bg = fc::White; + wc.dialog_fg = fc::Black; + wc.dialog_resize_fg = fc::Cyan; + wc.dialog_emphasis_fg = fc::Blue; + wc.dialog_bg = fc::White; + 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; + wc.current_element_focus_bg = fc::Blue; + wc.current_element_fg = fc::LightGray; + wc.current_element_bg = fc::Blue; + wc.current_inc_search_element_fg = fc::LightRed; + wc.selected_current_element_focus_fg = fc::LightCyan; + wc.selected_current_element_focus_bg = fc::Blue; + wc.selected_current_element_fg = fc::LightBlue; + wc.selected_current_element_bg = fc::Blue; + wc.label_fg = fc::Black; + wc.label_bg = fc::White; + wc.label_inactive_fg = fc::LightGray; + wc.label_inactive_bg = fc::White; + wc.label_hotkey_fg = fc::Red; + wc.label_hotkey_bg = fc::White; + wc.label_emphasis_fg = fc::Blue; + wc.label_ellipsis_fg = fc::DarkGray; + wc.inputfield_active_focus_fg = fc::White; + wc.inputfield_active_focus_bg = fc::Cyan; + wc.inputfield_active_fg = fc::Black; + wc.inputfield_active_bg = fc::LightGray; + wc.inputfield_inactive_fg = fc::DarkGray; + wc.inputfield_inactive_bg = fc::LightGray; + wc.toggle_button_active_focus_fg = fc::White; + wc.toggle_button_active_focus_bg = fc::Cyan; + wc.toggle_button_active_fg = fc::Black; + wc.toggle_button_active_bg = fc::White; + wc.toggle_button_inactive_fg = fc::LightGray; + wc.toggle_button_inactive_bg = fc::White; + wc.button_active_focus_fg = fc::LightGray; + wc.button_active_focus_bg = fc::Blue; + wc.button_active_fg = fc::LightGray; + wc.button_active_bg = fc::DarkGray; + wc.button_inactive_fg = fc::DarkGray; + wc.button_inactive_bg = fc::LightGray; + wc.button_hotkey_fg = fc::White; + wc.titlebar_active_fg = fc::White; + wc.titlebar_active_bg = fc::Blue; + wc.titlebar_inactive_fg = fc::LightGray; + wc.titlebar_inactive_bg = fc::DarkGray; + wc.titlebar_button_fg = fc::DarkGray; + wc.titlebar_button_bg = fc::LightGray; + wc.titlebar_button_focus_fg = fc::LightGray; + wc.titlebar_button_focus_bg = fc::Black; + wc.menu_active_focus_fg = fc::White; + wc.menu_active_focus_bg = fc::Blue; + wc.menu_active_fg = fc::Black; + wc.menu_active_bg = fc::White; + wc.menu_inactive_fg = fc::LightGray; + wc.menu_inactive_bg = fc::White; + wc.menu_hotkey_fg = fc::Red; + wc.menu_hotkey_bg = fc::White; + wc.statusbar_fg = fc::White; + wc.statusbar_bg = fc::Blue; + wc.statusbar_hotkey_fg = fc::LightRed; + wc.statusbar_hotkey_bg = fc::Blue; + wc.statusbar_separator_fg = fc::Black; + wc.statusbar_active_fg = fc::Blue; + wc.statusbar_active_bg = fc::White; + wc.statusbar_active_hotkey_fg = fc::DarkGray; + wc.statusbar_active_hotkey_bg = fc::White; + wc.scrollbar_fg = fc::DarkGray; + wc.scrollbar_bg = fc::LightBlue; + wc.scrollbar_button_fg = fc::Black; + wc.scrollbar_button_bg = fc::LightGray; + wc.progressbar_fg = fc::DarkGray; + wc.progressbar_bg = fc::LightBlue; + + if ( isKdeTerminal() ) + wc.term_bg = fc::SteelBlue3; + + if ( isTeraTerm() ) + wc.term_bg = fc::LightBlue; + + if ( getMaxColor() < 16 ) // for 8 color mode + { + wc.term_fg = fc::Black; + wc.term_bg = fc::Blue; + wc.list_fg = fc::Black; + wc.list_bg = fc::LightGray; + wc.selected_list_fg = fc::Blue; + wc.selected_list_bg = fc::LightGray; + wc.dialog_fg = fc::Black; + wc.dialog_resize_fg = fc::Red; + wc.dialog_emphasis_fg = fc::Blue; + wc.dialog_bg = fc::LightGray; + 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; + wc.current_element_focus_bg = fc::Red; + wc.current_element_fg = fc::LightGray; + wc.current_element_bg = fc::Blue; + wc.current_inc_search_element_fg = fc::Brown; + wc.selected_current_element_focus_fg = fc::Blue; + wc.selected_current_element_focus_bg = fc::Red; + wc.selected_current_element_fg = fc::Cyan; + wc.selected_current_element_bg = fc::Blue; + wc.label_fg = fc::Black; + wc.label_bg = fc::LightGray; + wc.label_inactive_fg = fc::Cyan; + wc.label_inactive_bg = fc::LightGray; + wc.label_hotkey_fg = fc::Red; + wc.label_hotkey_bg = fc::LightGray; + wc.label_emphasis_fg = fc::Blue; + wc.label_ellipsis_fg = fc::Black; + wc.inputfield_active_focus_fg = fc::LightGray; + wc.inputfield_active_focus_bg = fc::Blue; + wc.inputfield_active_fg = fc::Black; + wc.inputfield_active_bg = fc::Cyan; + wc.inputfield_inactive_fg = fc::Black; + wc.inputfield_inactive_bg = fc::LightGray; + wc.toggle_button_active_focus_fg = fc::LightGray; + wc.toggle_button_active_focus_bg = fc::Red; + wc.toggle_button_active_fg = fc::Black; + wc.toggle_button_active_bg = fc::LightGray; + wc.toggle_button_inactive_fg = fc::Cyan; + wc.toggle_button_inactive_bg = fc::LightGray; + wc.button_active_focus_fg = fc::LightGray; + wc.button_active_focus_bg = fc::Red; + wc.button_active_fg = fc::LightGray; + wc.button_active_bg = fc::Blue; + wc.button_inactive_fg = fc::Black; + wc.button_inactive_bg = fc::Blue; + wc.button_hotkey_fg = fc::LightGray; + wc.titlebar_active_fg = fc::LightGray; + wc.titlebar_active_bg = fc::Red; + wc.titlebar_inactive_fg = fc::Black; + wc.titlebar_inactive_bg = fc::LightGray; + wc.titlebar_button_fg = fc::Black; + wc.titlebar_button_bg = fc::LightGray; + wc.titlebar_button_focus_fg = fc::LightGray; + wc.titlebar_button_focus_bg = fc::Black; + wc.menu_active_focus_fg = fc::LightGray; + wc.menu_active_focus_bg = fc::Blue; + wc.menu_active_fg = fc::Black; + wc.menu_active_bg = fc::LightGray; + wc.menu_inactive_fg = fc::Cyan; + wc.menu_inactive_bg = fc::LightGray; + wc.menu_hotkey_fg = fc::Red; + wc.menu_hotkey_bg = fc::LightGray; + wc.statusbar_fg = fc::Black; + wc.statusbar_bg = fc::LightGray; + wc.statusbar_hotkey_fg = fc::Red; + wc.statusbar_hotkey_bg = fc::LightGray; + wc.statusbar_separator_fg = fc::Black; + wc.statusbar_active_fg = fc::LightGray; + wc.statusbar_active_bg = fc::Black; + wc.statusbar_active_hotkey_fg = fc::Red; + wc.statusbar_active_hotkey_bg = fc::Black; + wc.scrollbar_fg = fc::Black; + wc.scrollbar_bg = fc::LightGray; + wc.scrollbar_button_fg = fc::Black; + wc.scrollbar_button_bg = fc::LightGray; + wc.progressbar_fg = fc::Blue; + wc.progressbar_bg = fc::LightGray; + } +} diff --git a/src/fwidget.h b/src/fwidget.h index 7b5c65b8..32bddc6d 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -96,16 +96,182 @@ class FMenuBar; class FWidget : public FVTerm { public: - typedef std::vector widgetList; - static widgetList* window_list; - static widgetList* dialog_list; - static widgetList* always_on_top_list; - static widgetList* close_widget; + // Using-declaration + using FVTerm::setColor; + struct accelerator + { + int key; + FWidget* object; + }; + + // Typedefs + typedef std::vector widgetList; typedef void (*FCallback)(FWidget*, void*); typedef void (FWidget::*FMemberCallback)(FWidget*, void*); typedef void* data_ptr; + typedef std::vector Accelerators; + // Constructor + explicit FWidget (FWidget* = 0); + + // Destructor + ~FWidget(); + + // Accessors + const char* getClassName() const; + FWidget* getRootWidget() const; + FWidget* getParentWidget() const; + static FWidget* getMainWidget(); + virtual FWidget* getFocusWidget() const; + static FWidget* getClickedWidget(); + static FWidget* getMoveSizeWidget(); + static FWidget* getOpenMenu(); + static FMenuBar* getMenuBar(); + static FStatusBar* getStatusBar(); + FString getStatusbarMessage() const; + short getForegroundColor() const; // get the primary + short getBackgroundColor() const; // widget colors + int getX() const; // positioning + int getY() const; + const FPoint getPos() const; + int getTermX() const; + int getTermY() const; + const FPoint getTermPos() const; + int getWidth() const; + int getHeight() const; + int getTopPadding() const; + int getLeftPadding() const; + int getBottomPadding() const; + int getRightPadding() const; + int getClientWidth() const; + int getClientHeight() const; + int getMaxWidth() const; + int getMaxHeight() const; + const FPoint& getShadow() const; + const FRect& getGeometry() const; + const FRect& getGeometryWithShadow(); + const FRect& getTermGeometry(); + const FRect& getTermGeometryWithShadow(); + int getFlags() const; + FPoint getCursorPos(); + FPoint getPrintPos(); + std::vector& doubleFlatLine_ref (fc::sides); + + // Mutators + static void setMainWidget (FWidget*); + virtual void setFocusWidget (FWidget*); + static void setClickedWidget (FWidget*); + static void setMoveSizeWidget (FWidget*); + static void setOpenMenu (FWidget*); + virtual void setStatusbarMessage (FString); + bool setVisible(); + virtual bool setEnable (bool); + virtual bool setEnable(); + virtual bool unsetEnable(); + virtual bool setDisable(); + virtual bool setVisibleCursor (bool); // input cursor visibility + virtual bool setVisibleCursor(); // for the widget + virtual bool unsetVisibleCursor(); + virtual bool setFocus (bool); + virtual bool setFocus(); + virtual bool unsetFocus(); + void setFocusable(); + void unsetFocusable(); + bool ignorePadding (bool); // ignore padding from + bool ignorePadding(); // the parent widget + bool acceptPadding(); + void setForegroundColor (short); + void setBackgroundColor (short); + void setColor(); + virtual void setX (int, bool = true); // positioning + virtual void setY (int, bool = true); + virtual void setPos (const FPoint&, bool = true); + virtual void setPos (int, int, bool = true); + virtual void setWidth (int, bool = true); + virtual void setHeight (int, bool = true); + virtual void setSize (int, int, bool = true); + void setTopPadding (int, bool = true); + void setLeftPadding (int, bool = true); + void setBottomPadding (int, bool = true); + void setRightPadding (int, bool = true); + void setParentOffset(); + void setTermOffset(); + void setTermOffsetWithPadding(); + void setTermSize (int, int); + virtual void setGeometry (const FRect&, bool = true); + virtual void setGeometry (int, int, int, int, bool = true); + virtual void setShadowSize (int, int); + void setMinimumSize (int, int); + void setMaximumSize (int, int); + void setFixedSize (int, int); + bool setCursorPos (const FPoint&); + bool setCursorPos (register int, register int); + void unsetCursorPos(); + void setPrintPos (const FPoint&); + void setPrintPos (register int, register int); + void setDoubleFlatLine (fc::sides, bool = true); + void unsetDoubleFlatLine (fc::sides); + void setDoubleFlatLine (fc::sides, int, bool = true); + void unsetDoubleFlatLine (fc::sides, int); + + // Inquiries + bool isRootWidget() const; + bool isWindowWidget() const; + bool isDialogWidget() const; + bool isMenuWidget() const; + bool isVisible() const; + bool isShown() const; + bool isEnabled() const; + bool hasVisibleCursor() const; + bool hasFocus() const; + bool acceptFocus() const; // is focusable + bool isPaddingIgnored(); + + // Methods + static FWidget* childWidgetAt (FWidget*, const FPoint&); + static FWidget* childWidgetAt (FWidget*, int, int); + int numOfFocusableChildren(); + virtual bool close(); + void clearStatusbarMessage(); + void addCallback ( FString + , FCallback + , void* = null ); + void addCallback ( FString + , FWidget* + , FMemberCallback + , void* = null ); + void delCallback (FCallback); + void delCallback (FWidget*); + void delCallbacks(); + void emitCallback (FString); + void addAccelerator (int); + virtual void addAccelerator (int, FWidget*); + void delAccelerator (); + virtual void delAccelerator (FWidget*); + virtual void redraw(); + virtual void resize(); + virtual void show(); + virtual void hide(); + virtual bool focusFirstChild(); // widget focusing + virtual bool focusLastChild(); + FPoint termToWidgetPos (const FPoint&); + void detectTermSize(); + virtual void move (const FPoint&); + virtual void move (int, int); + void drawShadow(); + void clearShadow(); + void drawFlatBorder(); + void clearFlatBorder(); + virtual void drawBorder (int, int, int, int); + virtual void drawBorder(); + static void quit(); + + // Data Members + static widgetList* window_list; + Accelerators* accelerator_list; + + protected: struct callback_data { FString cb_signal; @@ -113,9 +279,6 @@ class FWidget : public FVTerm data_ptr data; }; - typedef std::vector CallbackObjects; - CallbackObjects callback_objects; - struct member_callback_data { FString cb_signal; @@ -124,19 +287,39 @@ class FWidget : public FVTerm data_ptr data; }; + // Typedefs + typedef std::vector CallbackObjects; typedef std::vector MemberCallbackObjects; - MemberCallbackObjects member_callback_objects; - struct accelerator - { - int key; - FWidget* object; - }; + // Mutators + virtual void setStatusBar (FStatusBar*); + virtual void setMenuBar (FMenuBar*); - typedef std::vector Accelerators; - Accelerators* accelerator_list; + // Methods + virtual void adjustSize(); + void adjustSizeGlobal(); + virtual bool focusNextChild(); // Change child + virtual bool focusPrevChild(); // focus - protected: + // Event handlers + bool event (FEvent*); + virtual void onKeyPress (FKeyEvent*); + virtual void onKeyUp (FKeyEvent*); + virtual void onKeyDown (FKeyEvent*); + virtual void onMouseDown (FMouseEvent*); + virtual void onMouseUp (FMouseEvent*); + virtual void onMouseDoubleClick (FMouseEvent*); + virtual void onWheel (FWheelEvent*); + virtual void onMouseMove (FMouseEvent*); + virtual void onFocusIn (FFocusEvent*); + virtual void onFocusOut (FFocusEvent*); + virtual void onAccel (FAccelEvent*); + virtual void onResize (FResizeEvent*); + virtual void onShow (FShowEvent*); + virtual void onHide (FHideEvent*); + virtual void onClose (FCloseEvent*); + + // Data Members static struct widget_colors { short term_fg; @@ -226,17 +409,36 @@ class FWidget : public FVTerm } wc; // widget_colors wc; - int flags; - static uInt modal_dialogs; + int flags; + static uInt modal_dialogs; + static widgetList* dialog_list; + static widgetList* always_on_top_list; + static widgetList* close_widget; + CallbackObjects callback_objects; + MemberCallbackObjects member_callback_objects; private: - bool enable; - bool visible; - bool shown; - bool focus; - bool focusable; - bool visible_cursor; - FPoint widget_cursor_position; + // Disable copy constructor + FWidget (const FWidget&); + + // Disable assignment operator (=) + FWidget& operator = (const FWidget&); + + // Methods + void init(); + void finish(); + void processDestroy(); + virtual void draw(); + static void setColorTheme(); + + // Data Members + bool enable; + bool visible; + bool shown; + bool focus; + bool focusable; + bool visible_cursor; + FPoint widget_cursor_position; struct widget_size_hints { @@ -288,366 +490,50 @@ class FWidget : public FVTerm int right; } padding; - bool ignore_padding; + bool ignore_padding; // widget size - FRect wsize; - FRect adjust_wsize; - FRect adjust_wsize_term; - FRect adjust_wsize_shadow; - FRect adjust_wsize_term_shadow; + FRect wsize; + FRect adjust_wsize; + FRect adjust_wsize_term; + FRect adjust_wsize_shadow; + FRect adjust_wsize_term_shadow; // widget offset - FRect offset; + FRect offset; // offset of the widget client area - FRect client_offset; + FRect client_offset; // widget shadow size (on the right and bottom side) - FPoint wshadow; + FPoint wshadow; // default widget foreground and background color - short foreground_color; - short background_color; - - FString statusbar_message; + short foreground_color; + short background_color; + FString statusbar_message; static FStatusBar* statusbar; static FMenuBar* menubar; static FWidget* show_root_widget; static FWidget* redraw_root_widget; - // Friend classes + // Friend class friend class FToggleButton; - - private: - // Disable copy constructor - FWidget (const FWidget&); - // Disable assignment operator (=) - FWidget& operator = (const FWidget&); - - void init(); - void finish(); - void processDestroy(); - virtual void draw(); - static void setColorTheme(); - - protected: - virtual void adjustSize(); - void adjustSizeGlobal(); - virtual void setStatusBar (FStatusBar*); - virtual void setMenuBar (FMenuBar*); - // Event handlers - bool event (FEvent*); - virtual void onKeyPress (FKeyEvent*); - virtual void onKeyUp (FKeyEvent*); - virtual void onKeyDown (FKeyEvent*); - virtual void onMouseDown (FMouseEvent*); - virtual void onMouseUp (FMouseEvent*); - virtual void onMouseDoubleClick (FMouseEvent*); - virtual void onWheel (FWheelEvent*); - virtual void onMouseMove (FMouseEvent*); - virtual void onFocusIn (FFocusEvent*); - virtual void onFocusOut (FFocusEvent*); - virtual void onAccel (FAccelEvent*); - virtual void onResize (FResizeEvent*); - virtual void onShow (FShowEvent*); - virtual void onHide (FHideEvent*); - virtual void onClose (FCloseEvent*); - // Change child focus - virtual bool focusNextChild(); - virtual bool focusPrevChild(); - - public: - // Constructor - explicit FWidget (FWidget* = 0); - // Destructor - ~FWidget(); - - const char* getClassName() const; - FWidget* getRootWidget() const; - static FWidget* getMainWidget(); - static void setMainWidget (FWidget*); - static FWidget* childWidgetAt (FWidget*, const FPoint&); - static FWidget* childWidgetAt (FWidget*, int, int); - virtual FWidget* getFocusWidget() const; - virtual void setFocusWidget (FWidget*); - static FWidget* getClickedWidget(); - static void setClickedWidget (FWidget*); - static FWidget* getMoveSizeWidget(); - static void setMoveSizeWidget (FWidget*); - static FWidget* getOpenMenu(); - static void setOpenMenu (FWidget*); - int numOfFocusableChildren(); - FWidget* getParentWidget() const; - bool isRootWidget() const; - bool isWindowWidget() const; - bool isDialogWidget() const; - bool isMenuWidget() const; - virtual bool close(); - - static FStatusBar* statusBar(); - static FMenuBar* menuBar(); - virtual void setStatusbarMessage (FString); - void clearStatusbarMessage(); - FString getStatusbarMessage(); - - void addCallback ( FString - , FCallback - , void* = null ); - void addCallback ( FString - , FWidget* - , FMemberCallback - , void* = null ); - void delCallback (FCallback); - void delCallback (FWidget*); - void delCallbacks(); - void emitCallback (FString); - - void addAccelerator (int); - virtual void addAccelerator (int, FWidget*); - void delAccelerator (); - virtual void delAccelerator (FWidget*); - - virtual void redraw(); - virtual void resize(); - virtual void show(); - virtual void hide(); - bool setVisible(); - bool isVisible() const; - bool isShown() const; - - virtual bool setEnable(bool); - virtual bool setEnable(); - virtual bool unsetEnable(); - virtual bool setDisable(); - bool isEnabled() const; - - // input cursor visibility for the widget - virtual bool setVisibleCursor(bool); - virtual bool setVisibleCursor(); - virtual bool unsetVisibleCursor(); - bool hasVisibleCursor() const; - - // widget focusing - virtual bool focusFirstChild(); - virtual bool focusLastChild(); - virtual bool setFocus (bool); - virtual bool setFocus(); - virtual bool unsetFocus(); - bool hasFocus() const; - bool acceptFocus() const; - void setFocusable(); - void unsetFocusable(); - - // ignore padding from the parent widget - bool ignorePadding (bool); - bool ignorePadding(); - bool acceptPadding(); - bool isPaddingIgnored(); - - // get the primary widget colors - short getForegroundColor() const; - short getBackgroundColor() const; - - // positioning - int getX() const; - int getY() const; - const FPoint getPos() const; - int getTermX() const; - int getTermY() const; - const FPoint getTermPos() const; - int getWidth() const; - int getHeight() const; - int getTopPadding() const; - int getLeftPadding() const; - int getBottomPadding() const; - int getRightPadding() const; - int getClientWidth() const; - int getClientHeight() const; - int getMaxWidth() const; - int getMaxHeight() const; - const FPoint& getShadow() const; - const FRect& getGeometry() const; - const FRect& getGeometryWithShadow(); - const FRect& getTermGeometry(); - const FRect& getTermGeometryWithShadow(); - FPoint termToWidgetPos (const FPoint&); - void setForegroundColor (short); - void setBackgroundColor (short); - void setColor(); - // make every setColor from FVTerm available - using FVTerm::setColor; - virtual void setX (int, bool = true); - virtual void setY (int, bool = true); - virtual void setPos (const FPoint&, bool = true); - virtual void setPos (int, int, bool = true); - virtual void setWidth (int, bool = true); - virtual void setHeight (int, bool = true); - virtual void setSize (int, int, bool = true); - void setTopPadding (int, bool = true); - void setLeftPadding (int, bool = true); - void setBottomPadding (int, bool = true); - void setRightPadding (int, bool = true); - void setParentOffset(); - void setTermOffset(); - void setTermOffsetWithPadding(); - void detectTermSize(); - void setTermSize (int, int); - virtual void setGeometry (const FRect&, bool = true); - virtual void setGeometry (int, int, int, int, bool = true); - virtual void setShadowSize (int, int); - void setMinimumSize (int, int); - void setMaximumSize (int, int); - void setFixedSize (int, int); - virtual void move (const FPoint&); - virtual void move (int, int); - int getFlags() const; - - FPoint getCursorPos(); - bool setCursorPos (const FPoint&); - bool setCursorPos (register int, register int); - void unsetCursorPos(); - - void setPrintPos (const FPoint&); - void setPrintPos (register int, register int); - FPoint getPrintPos(); - - void drawShadow(); - void clearShadow(); - void drawFlatBorder(); - void clearFlatBorder(); - void setDoubleFlatLine (int, bool = true); - void unsetDoubleFlatLine (int); - void setDoubleFlatLine (int, int, bool = true); - void unsetDoubleFlatLine (int, int); - std::vector& doubleFlatLine_ref (int); - virtual void drawBorder (int, int, int, int); - virtual void drawBorder(); - - static void quit(); }; #pragma pack(pop) // FWidget inline functions -//---------------------------------------------------------------------- -inline void FWidget::processDestroy() -{ emitCallback("destroy"); } - //---------------------------------------------------------------------- inline const char* FWidget::getClassName() const { return "FWidget"; } -//---------------------------------------------------------------------- -inline FWidget* FWidget::childWidgetAt (FWidget* p, const FPoint& pos) -{ return childWidgetAt (p, pos.getX(), pos.getY()); } - //---------------------------------------------------------------------- inline FWidget* FWidget::getParentWidget() const { return static_cast(getParent()); } //---------------------------------------------------------------------- -inline bool FWidget::isRootWidget() const -{ return (! hasParent()); } - -//---------------------------------------------------------------------- -inline void FWidget::clearStatusbarMessage() -{ statusbar_message.clear(); } - -//---------------------------------------------------------------------- -inline FString FWidget::getStatusbarMessage() +inline FString FWidget::getStatusbarMessage() const { return statusbar_message; } -//---------------------------------------------------------------------- -inline void FWidget::addAccelerator (int key) -{ addAccelerator (key, this); } - -//---------------------------------------------------------------------- -inline void FWidget::delAccelerator() -{ delAccelerator(this); } - -//---------------------------------------------------------------------- -inline bool FWidget::setVisible() -{ return visible = true; } - -//---------------------------------------------------------------------- -inline bool FWidget::isVisible() const -{ return visible; } - -//---------------------------------------------------------------------- -inline bool FWidget::isShown() const -{ return shown; } - -//---------------------------------------------------------------------- -inline bool FWidget::isWindowWidget() const -{ return ((flags & fc::window_widget) != 0); } - -//---------------------------------------------------------------------- -inline bool FWidget::isDialogWidget() const -{ return ((flags & fc::dialog_widget) != 0); } - -//---------------------------------------------------------------------- -inline bool FWidget::isMenuWidget() const -{ return ((flags & fc::menu_widget) != 0); } - -//---------------------------------------------------------------------- -inline bool FWidget::isEnabled() const -{ return enable; } - -//---------------------------------------------------------------------- -inline bool FWidget::setVisibleCursor (bool on) -{ return visible_cursor = (on) ? true : false; } - -//---------------------------------------------------------------------- -inline bool FWidget::setVisibleCursor() -{ return setVisibleCursor(true); } - -//---------------------------------------------------------------------- -inline bool FWidget::unsetVisibleCursor() -{ return setVisibleCursor(false); } - -//---------------------------------------------------------------------- -inline bool FWidget::hasVisibleCursor() const -{ return visible_cursor; } - -//---------------------------------------------------------------------- -inline bool FWidget::setFocus() -{ return setFocus(true); } - -//---------------------------------------------------------------------- -inline bool FWidget::unsetFocus() -{ return setFocus(false); } - -//---------------------------------------------------------------------- -inline bool FWidget::hasFocus() const -{ return focus; } - -//---------------------------------------------------------------------- -inline bool FWidget::acceptFocus() const -{ return focusable; } - -//---------------------------------------------------------------------- -inline bool FWidget::ignorePadding (bool on) -{ return ignore_padding = on; } - -//---------------------------------------------------------------------- -inline bool FWidget::ignorePadding() -{ return ignore_padding = true; } - -//---------------------------------------------------------------------- -inline bool FWidget::acceptPadding() -{ return ignore_padding = false; } - -//---------------------------------------------------------------------- -inline bool FWidget::isPaddingIgnored() -{ return ignore_padding; } - -//---------------------------------------------------------------------- -inline void FWidget::setFocusable() -{ focusable = true; } - -//---------------------------------------------------------------------- -inline void FWidget::unsetFocusable() -{ focusable = false; } - //---------------------------------------------------------------------- inline short FWidget::getForegroundColor() const { return foreground_color; } @@ -680,33 +566,6 @@ inline int FWidget::getTermY() const // y-position on terminal inline const FPoint FWidget::getTermPos() const // position on terminal { return FPoint(getTermX(), getTermY()); } -//---------------------------------------------------------------------- -inline FPoint FWidget::termToWidgetPos (const FPoint& tPos) -{ - return FPoint ( tPos.getX() + 1 - offset.getX1() - adjust_wsize.getX() - , tPos.getY() + 1 - offset.getY1() - adjust_wsize.getY() ); -} - -//---------------------------------------------------------------------- -inline void FWidget::setForegroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - foreground_color = color; -} - -//---------------------------------------------------------------------- -inline void FWidget::setBackgroundColor (short color) -{ - // valid colors -1..254 - if ( color == fc::Default || color >> 8 == 0 ) - background_color = color; -} - -//---------------------------------------------------------------------- -inline void FWidget::setPos (const FPoint& p, bool adjust) -{ setPos (p.getX(), p.getY(), adjust); } - //---------------------------------------------------------------------- inline int FWidget::getWidth() const { return adjust_wsize.getWidth(); } @@ -794,6 +653,94 @@ inline const FRect& FWidget::getTermGeometryWithShadow() return adjust_wsize_term_shadow; } +//---------------------------------------------------------------------- +inline int FWidget::getFlags() const +{ return flags; } + +//---------------------------------------------------------------------- +inline FPoint FWidget::getCursorPos() +{ return widget_cursor_position; } + +//---------------------------------------------------------------------- +inline bool FWidget::setVisible() +{ return visible = true; } + +//---------------------------------------------------------------------- +inline bool FWidget::setEnable (bool on) +{ return enable = (on) ? true : false; } + +//---------------------------------------------------------------------- +inline bool FWidget::setEnable() +{ return setEnable(true); } + +//---------------------------------------------------------------------- +inline bool FWidget::unsetEnable() +{ return setEnable(false); } + +//---------------------------------------------------------------------- +inline bool FWidget::setDisable() +{ return setEnable(false); } + +//---------------------------------------------------------------------- +inline bool FWidget::setVisibleCursor (bool on) +{ return visible_cursor = (on) ? true : false; } + +//---------------------------------------------------------------------- +inline bool FWidget::setVisibleCursor() +{ return setVisibleCursor(true); } + +//---------------------------------------------------------------------- +inline bool FWidget::unsetVisibleCursor() +{ return setVisibleCursor(false); } + +//---------------------------------------------------------------------- +inline bool FWidget::setFocus() +{ return setFocus(true); } + +//---------------------------------------------------------------------- +inline bool FWidget::unsetFocus() +{ return setFocus(false); } + +//---------------------------------------------------------------------- +inline void FWidget::setFocusable() +{ focusable = true; } + +//---------------------------------------------------------------------- +inline void FWidget::unsetFocusable() +{ focusable = false; } + +//---------------------------------------------------------------------- +inline bool FWidget::ignorePadding (bool on) +{ return ignore_padding = on; } + +//---------------------------------------------------------------------- +inline bool FWidget::ignorePadding() +{ return ignore_padding = true; } + +//---------------------------------------------------------------------- +inline bool FWidget::acceptPadding() +{ return ignore_padding = false; } + +//---------------------------------------------------------------------- +inline void FWidget::setForegroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + foreground_color = color; +} + +//---------------------------------------------------------------------- +inline void FWidget::setBackgroundColor (short color) +{ + // valid colors -1..254 + if ( color == fc::Default || color >> 8 == 0 ) + background_color = color; +} + +//---------------------------------------------------------------------- +inline void FWidget::setPos (const FPoint& p, bool adjust) +{ setPos (p.getX(), p.getY(), adjust); } + //---------------------------------------------------------------------- inline void FWidget::setGeometry (const FRect& box, bool adjust) { @@ -823,18 +770,6 @@ inline void FWidget::setFixedSize (int width, int height) size_hints.setMaximum (width, height); } -//---------------------------------------------------------------------- -inline void FWidget::move (const FPoint& pos) -{ move( pos.getX(), pos.getY() ); } - -//---------------------------------------------------------------------- -inline int FWidget::getFlags() const -{ return flags; } - -//---------------------------------------------------------------------- -inline FPoint FWidget::getCursorPos() -{ return widget_cursor_position; } - //---------------------------------------------------------------------- inline bool FWidget::setCursorPos (const FPoint& pos) { return setCursorPos (pos.getX(), pos.getY()); } @@ -848,19 +783,94 @@ inline void FWidget::setPrintPos (const FPoint& pos) { setPrintPos (pos.getX(), pos.getY()); } //---------------------------------------------------------------------- -inline void FWidget::unsetDoubleFlatLine (int side) +inline void FWidget::unsetDoubleFlatLine (fc::sides side) { setDoubleFlatLine(side, false); } //---------------------------------------------------------------------- -inline void FWidget::unsetDoubleFlatLine (int side, int pos) +inline void FWidget::unsetDoubleFlatLine (fc::sides side, int pos) { setDoubleFlatLine(side, pos, false); } +//---------------------------------------------------------------------- +inline bool FWidget::isRootWidget() const +{ return (! hasParent()); } + +//---------------------------------------------------------------------- +inline bool FWidget::isVisible() const +{ return visible; } + +//---------------------------------------------------------------------- +inline bool FWidget::isShown() const +{ return shown; } + +//---------------------------------------------------------------------- +inline bool FWidget::isWindowWidget() const +{ return ((flags & fc::window_widget) != 0); } + +//---------------------------------------------------------------------- +inline bool FWidget::isDialogWidget() const +{ return ((flags & fc::dialog_widget) != 0); } + +//---------------------------------------------------------------------- +inline bool FWidget::isMenuWidget() const +{ return ((flags & fc::menu_widget) != 0); } + +//---------------------------------------------------------------------- +inline bool FWidget::isEnabled() const +{ return enable; } + +//---------------------------------------------------------------------- +inline bool FWidget::hasVisibleCursor() const +{ return visible_cursor; } + +//---------------------------------------------------------------------- +inline bool FWidget::hasFocus() const +{ return focus; } + +//---------------------------------------------------------------------- +inline bool FWidget::acceptFocus() const // is focusable +{ return focusable; } + +//---------------------------------------------------------------------- +inline bool FWidget::isPaddingIgnored() +{ return ignore_padding; } + +//---------------------------------------------------------------------- +inline FWidget* FWidget::childWidgetAt (FWidget* p, const FPoint& pos) +{ return childWidgetAt (p, pos.getX(), pos.getY()); } + +//---------------------------------------------------------------------- +inline void FWidget::clearStatusbarMessage() +{ statusbar_message.clear(); } + +//---------------------------------------------------------------------- +inline void FWidget::addAccelerator (int key) +{ addAccelerator (key, this); } + +//---------------------------------------------------------------------- +inline void FWidget::delAccelerator() +{ delAccelerator(this); } + +//---------------------------------------------------------------------- +inline FPoint FWidget::termToWidgetPos (const FPoint& tPos) +{ + return FPoint ( tPos.getX() + 1 - offset.getX1() - adjust_wsize.getX() + , tPos.getY() + 1 - offset.getY1() - adjust_wsize.getY() ); +} + +//---------------------------------------------------------------------- +inline void FWidget::move (const FPoint& pos) +{ move( pos.getX(), pos.getY() ); } + //---------------------------------------------------------------------- inline void FWidget::drawBorder() { drawBorder (1, 1, getWidth(), getHeight()); } +//---------------------------------------------------------------------- +inline void FWidget::processDestroy() +{ emitCallback("destroy"); } -// NewFont elements + +// Non-member elements for NewFont //---------------------------------------------------------------------- const wchar_t NF_Drive[5] = { diff --git a/src/fwindow.cpp b/src/fwindow.cpp index ff94b5b7..830ed82d 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -53,23 +53,78 @@ FWindow::~FWindow() // destructor } -// private methods of FWindow +// public methods of FWindow //---------------------------------------------------------------------- -void FWindow::deleteFromAlwaysOnTopList (FWidget* obj) +FWindow* FWindow::getActiveWindow() { - // delete the window object obj from the always-on-top list - if ( ! always_on_top_list || always_on_top_list->empty() ) + // returns the active FWindow object + FWindow* active_window = static_cast(FApplication::active_window); + return active_window; +} + +//---------------------------------------------------------------------- +FWidget* FWindow::getWindowFocusWidget() const +{ + // returns the focused widget of this window + return win_focus_widget; +} + +//---------------------------------------------------------------------- +bool FWindow::setWindowWidget (bool on) +{ + if ( isWindowWidget() == on ) + return true; + + if ( on ) + { + flags |= fc::window_widget; + setTermOffset(); + } + else + { + flags &= ~fc::window_widget; + setParentOffset(); + } + + return on; +} + +//---------------------------------------------------------------------- +void FWindow::setActiveWindow (FWindow* window) +{ + // activate FWindow object window + widgetList::const_iterator iter, end; + + if ( ! window_list ) return; - widgetList::iterator iter; - iter = always_on_top_list->begin(); + if ( window_list->empty() ) + return; - while ( iter != always_on_top_list->end() ) + iter = window_list->begin(); + end = window_list->end(); + + while ( iter != end ) { - if ( *iter == obj ) + if ( *iter == window ) { - always_on_top_list->erase (iter); - return; + if ( ! window->isWindowActive() ) + { + window->activateWindow(); + FEvent ev(fc::WindowActive_Event); + FApplication::sendEvent(window, &ev); + } + } + else + { + FWindow* w = static_cast(*iter); + + if ( w->isWindowActive() ) + { + w->deactivateWindow(); + FEvent ev(fc::WindowInactive_Event); + FApplication::sendEvent(*iter, &ev); + } } ++iter; @@ -77,93 +132,112 @@ void FWindow::deleteFromAlwaysOnTopList (FWidget* obj) } //---------------------------------------------------------------------- -void FWindow::processAlwaysOnTop() +void FWindow::setWindowFocusWidget (FWidget* obj) { - // Raise all always-on-top windows - if ( ! always_on_top_list || always_on_top_list->empty() ) - return; - - widgetList::iterator iter; - iter = always_on_top_list->begin(); - - while ( iter != always_on_top_list->end() ) - { - delWindow (*iter); - - if ( window_list ) - window_list->push_back(*iter); - - ++iter; - } -} - - -// protected methods of FWindow -//---------------------------------------------------------------------- -bool FWindow::event (FEvent* ev) -{ - switch ( ev->type() ) - { - case fc::WindowActive_Event: - onWindowActive (ev); - break; - - case fc::WindowInactive_Event: - onWindowInactive (ev); - break; - - case fc::WindowRaised_Event: - onWindowRaised (ev); - break; - - case fc::WindowLowered_Event: - onWindowLowered (ev); - break; - - default: - return FWidget::event(ev); - } - - return true; + // set focus widget of this window + win_focus_widget = obj; } //---------------------------------------------------------------------- -void FWindow::onWindowActive (FEvent*) -{ } - -//---------------------------------------------------------------------- -void FWindow::onWindowInactive (FEvent*) -{ } - -//---------------------------------------------------------------------- -void FWindow::onWindowRaised (FEvent*) -{ } - -//---------------------------------------------------------------------- -void FWindow::onWindowLowered (FEvent*) -{ } - -//---------------------------------------------------------------------- -void FWindow::adjustSize() +bool FWindow::activateWindow (bool on) { - int old_x = getX(); - int old_y = getY(); - FWidget::adjustSize(); - - if ( zoomed ) - setGeometry (1, 1, getMaxWidth(), getMaxHeight(), false); - else if ( vwin ) + // activate/deactivate this window + if ( on ) { - if ( getX() != old_x ) - vwin->x_offset = getTermX() - 1; - - if ( getY() != old_y ) - vwin->y_offset = getTermY() - 1; + FApplication::active_window = this; + active_area = getVWin(); } + + return window_active = (on) ? true : false; } +//---------------------------------------------------------------------- +bool FWindow::setResizeable (bool on) +{ + if ( on ) + flags |= fc::resizeable; + else + flags &= ~fc::resizeable; + + return on; +} + +//---------------------------------------------------------------------- +bool FWindow::setTransparentShadow (bool on) +{ + if ( on ) + { + flags |= fc::shadow; + flags |= fc::trans_shadow; + setShadowSize (2,1); + } + else + { + flags &= ~fc::shadow; + flags &= ~fc::trans_shadow; + setShadowSize (0,0); + } + + return on; +} + +//---------------------------------------------------------------------- +bool FWindow::setShadow (bool on) +{ + if ( isMonochron() ) + return false; + + if ( on ) + { + flags |= fc::shadow; + flags &= ~fc::trans_shadow; + setShadowSize (1,1); + } + else + { + flags &= ~fc::shadow; + flags &= ~fc::trans_shadow; + setShadowSize (0,0); + } + + return on; +} + +//---------------------------------------------------------------------- +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; +} + +//---------------------------------------------------------------------- +bool FWindow::isWindowHidden() const +{ + // returns the window hidden state + if ( vwin ) + return ! vwin->visible; + else + return false; +} -// public methods of FWindow //---------------------------------------------------------------------- void FWindow::drawBorder() { @@ -608,90 +682,6 @@ bool FWindow::zoomWindow() return zoomed; } -//---------------------------------------------------------------------- -bool FWindow::setWindowWidget (bool on) -{ - if ( isWindowWidget() == on ) - return true; - - if ( on ) - { - flags |= fc::window_widget; - setTermOffset(); - } - else - { - flags &= ~fc::window_widget; - setParentOffset(); - } - - return on; -} - -//---------------------------------------------------------------------- -FWindow* FWindow::getActiveWindow() -{ - // returns the active FWindow object - FWindow* active_window = static_cast(FApplication::active_window); - return active_window; -} - -//---------------------------------------------------------------------- -void FWindow::setActiveWindow (FWindow* window) -{ - // activate FWindow object window - widgetList::const_iterator iter, end; - - if ( ! window_list ) - return; - - if ( window_list->empty() ) - return; - - iter = window_list->begin(); - end = window_list->end(); - - while ( iter != end ) - { - if ( *iter == window ) - { - if ( ! window->isWindowActive() ) - { - window->activateWindow(); - FEvent ev(fc::WindowActive_Event); - FApplication::sendEvent(window, &ev); - } - } - else - { - FWindow* w = static_cast(*iter); - - if ( w->isWindowActive() ) - { - w->deactivateWindow(); - FEvent ev(fc::WindowInactive_Event); - FApplication::sendEvent(*iter, &ev); - } - } - - ++iter; - } -} - -//---------------------------------------------------------------------- -FWidget* FWindow::getWindowFocusWidget() const -{ - // returns the focused widget of this window - return win_focus_widget; -} - -//---------------------------------------------------------------------- -void FWindow::setWindowFocusWidget (FWidget* obj) -{ - // set focus widget of this window - win_focus_widget = obj; -} - //---------------------------------------------------------------------- void FWindow::switchToPrevWindow() { @@ -716,8 +706,8 @@ void FWindow::switchToPrevWindow() if ( w && w != active_window && ! (w->isWindowHidden() || w->isWindowActive()) - && w != static_cast(statusBar()) - && w != static_cast(menuBar()) ) + && w != static_cast(getStatusBar()) + && w != static_cast(getMenuBar()) ) { setActiveWindow(w); break; @@ -765,81 +755,6 @@ bool FWindow::activatePrevWindow() return false; } -//---------------------------------------------------------------------- -bool FWindow::activateWindow (bool on) -{ - // activate/deactivate this window - if ( on ) - { - FApplication::active_window = this; - active_area = getVWin(); - } - - return window_active = (on) ? true : false; -} - -//---------------------------------------------------------------------- -bool FWindow::isWindowHidden() const -{ - // returns the window hidden state - if ( vwin ) - return ! vwin->visible; - else - return false; -} - -//---------------------------------------------------------------------- -bool FWindow::setResizeable (bool on) -{ - if ( on ) - flags |= fc::resizeable; - else - flags &= ~fc::resizeable; - - return on; -} - -//---------------------------------------------------------------------- -bool FWindow::setTransparentShadow (bool on) -{ - if ( on ) - { - flags |= fc::shadow; - flags |= fc::trans_shadow; - setShadowSize (2,1); - } - else - { - flags &= ~fc::shadow; - flags &= ~fc::trans_shadow; - setShadowSize (0,0); - } - - return on; -} - -//---------------------------------------------------------------------- -bool FWindow::setShadow (bool on) -{ - if ( isMonochron() ) - return false; - - if ( on ) - { - flags |= fc::shadow; - flags &= ~fc::trans_shadow; - setShadowSize (1,1); - } - else - { - flags &= ~fc::shadow; - flags &= ~fc::trans_shadow; - setShadowSize (0,0); - } - - return on; -} - //---------------------------------------------------------------------- void FWindow::setShadowSize (int right, int bottom) { @@ -858,27 +773,112 @@ void FWindow::setShadowSize (int right, int bottom) } } + +// protected methods of FWindow //---------------------------------------------------------------------- -bool FWindow::setAlwaysOnTop (bool on) +void FWindow::adjustSize() { - if ( isAlwaysOnTop() == on ) - return true; + int old_x = getX(); + int old_y = getY(); + FWidget::adjustSize(); - if ( on ) + if ( zoomed ) + setGeometry (1, 1, getMaxWidth(), getMaxHeight(), false); + else if ( vwin ) { - flags |= fc::always_on_top; + if ( getX() != old_x ) + vwin->x_offset = getTermX() - 1; - if ( always_on_top_list ) - { - deleteFromAlwaysOnTopList (this); - always_on_top_list->push_back (this); - } + if ( getY() != old_y ) + vwin->y_offset = getTermY() - 1; + } +} + +//---------------------------------------------------------------------- +bool FWindow::event (FEvent* ev) +{ + switch ( ev->type() ) + { + case fc::WindowActive_Event: + onWindowActive (ev); + break; + + case fc::WindowInactive_Event: + onWindowInactive (ev); + break; + + case fc::WindowRaised_Event: + onWindowRaised (ev); + break; + + case fc::WindowLowered_Event: + onWindowLowered (ev); + break; + + default: + return FWidget::event(ev); + } + + return true; +} + +//---------------------------------------------------------------------- +void FWindow::onWindowActive (FEvent*) +{ } + +//---------------------------------------------------------------------- +void FWindow::onWindowInactive (FEvent*) +{ } + +//---------------------------------------------------------------------- +void FWindow::onWindowRaised (FEvent*) +{ } + +//---------------------------------------------------------------------- +void FWindow::onWindowLowered (FEvent*) +{ } + + +// 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() ) + return; + + 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; + } +} + +//---------------------------------------------------------------------- +void FWindow::processAlwaysOnTop() +{ + // Raise all always-on-top windows + if ( ! always_on_top_list || always_on_top_list->empty() ) + return; + + widgetList::iterator iter; + iter = always_on_top_list->begin(); + + while ( iter != always_on_top_list->end() ) + { + delWindow (*iter); + + if ( window_list ) + window_list->push_back(*iter); + + ++iter; } - else - { - flags &= ~fc::always_on_top; - deleteFromAlwaysOnTopList (this); - } - - return on; } diff --git a/src/fwindow.h b/src/fwindow.h index cd4863c0..e68c56bf 100644 --- a/src/fwindow.h +++ b/src/fwindow.h @@ -48,25 +48,87 @@ class FWindow : public FWidget { - private: - bool window_active; - bool zoomed; - FWidget* win_focus_widget; - FRect normalGeometry; + public: + // Using-declaration + using FWidget::drawBorder; + using FWidget::setPos; + using FWidget::setGeometry; + using FWidget::move; + + // Constructor + explicit FWindow (FWidget* = 0); + + // Destructor + ~FWindow (); + + // Accessors + const char* getClassName() const; + static FWindow* getWindowWidget (FWidget*); + static int getWindowLayer (FWidget*); + static FWindow* getActiveWindow(); + FWidget* getWindowFocusWidget() const; + + // Mutators + bool setWindowWidget (bool); + bool setWindowWidget(); + bool unsetWindowWidget(); + static void setActiveWindow (FWindow*); + void setWindowFocusWidget (FWidget*); + bool activateWindow (bool); + bool activateWindow(); + bool deactivateWindow(); + virtual bool setResizeable (bool); + virtual bool setResizeable(); + bool unsetResizeable(); + bool setTransparentShadow (bool); + bool setTransparentShadow(); + bool unsetTransparentShadow(); + bool setShadow (bool); + bool setShadow(); + bool unsetShadow(); + bool setAlwaysOnTop (bool); + bool setAlwaysOnTop(); + bool unsetAlwaysOnTop(); + + // Inquiries + bool isZoomed() const; + bool isWindowActive() const; + bool isWindowHidden() const; + bool isResizeable() const; + bool isAlwaysOnTop() const; + bool hasTransparentShadow() const; + bool hasShadow() const; + + // Methods + virtual void drawBorder(); + virtual void show(); + virtual void hide(); + virtual void setX (int, bool = true); + virtual void setY (int, bool = true); + virtual void setPos (int, int, bool = true); + virtual void setWidth (int, bool = true); + virtual void setHeight (int, bool = true); + virtual void setSize (int, int, bool = true); + void setGeometry (int, int, int, int, bool = true); + virtual void move (int, int); + static FWindow* getWindowWidgetAt (const FPoint&); + static FWindow* getWindowWidgetAt (int, int); + static void addWindow (FWidget*); + static void delWindow (FWidget*); + static void swapWindow (FWidget*, FWidget*); + static bool raiseWindow (FWidget*); + bool raiseWindow (); + static bool lowerWindow (FWidget*); + bool lowerWindow (); + bool zoomWindow (); + static void switchToPrevWindow(); + static bool activatePrevWindow(); + virtual void setShadowSize (int, int); protected: - static FWindow* previous_window; + // Method + virtual void adjustSize(); - private: - // Disable copy constructor - FWindow (const FWindow&); - // Disable assignment operator (=) - FWindow& operator = (const FWindow&); - - static void deleteFromAlwaysOnTopList (FWidget*); - static void processAlwaysOnTop(); - - protected: // Event handlers bool event (FEvent*); virtual void onWindowActive (FEvent*); @@ -74,78 +136,25 @@ class FWindow : public FWidget virtual void onWindowRaised (FEvent*); virtual void onWindowLowered (FEvent*); - virtual void adjustSize(); + // Data Members + static FWindow* previous_window; - public: - // Constructor - explicit FWindow (FWidget* = 0); - // Destructor - ~FWindow (); + private: + // Disable copy constructor + FWindow (const FWindow&); - const char* getClassName() const; - // make every drawBorder from FWidget available - using FWidget::drawBorder; - virtual void drawBorder(); - virtual void show(); - virtual void hide(); - virtual void setX (int, bool = true); - virtual void setY (int, bool = true); - virtual void setPos (int, int, bool = true); - // make every setPos from FWidget available - using FWidget::setPos; - virtual void setWidth (int, bool = true); - virtual void setHeight (int, bool = true); - virtual void setSize (int, int, bool = true); - // make every setGeometry from FWidget available - using FWidget::setGeometry; - void setGeometry (int, int, int, int, bool = true); - virtual void move (int, int); - // make every move from FWidget available - using FWidget::move; - static FWindow* getWindowWidgetAt (const FPoint&); - static FWindow* getWindowWidgetAt (int, int); - static void addWindow (FWidget*); - static void delWindow (FWidget*); - static FWindow* getWindowWidget (FWidget*); - static int getWindowLayer (FWidget*); - static void swapWindow (FWidget*, FWidget*); - static bool raiseWindow (FWidget*); - bool raiseWindow (); - static bool lowerWindow (FWidget*); - bool lowerWindow (); - bool zoomWindow (); - bool isZoomed() const; - bool setWindowWidget (bool); - bool setWindowWidget(); - bool unsetWindowWidget(); - static FWindow* getActiveWindow(); - static void setActiveWindow (FWindow*); - FWidget* getWindowFocusWidget() const; - void setWindowFocusWidget (FWidget*); - static void switchToPrevWindow(); - static bool activatePrevWindow(); - bool activateWindow (bool); - bool activateWindow(); - bool deactivateWindow(); - bool isWindowActive() const; - bool isWindowHidden() const; - virtual bool setResizeable (bool); - virtual bool setResizeable(); - bool unsetResizeable(); - bool isResizeable(); - bool setTransparentShadow (bool); - bool setTransparentShadow(); - bool unsetTransparentShadow(); - bool hasTransparentShadow(); - bool setShadow (bool); - bool setShadow(); - bool unsetShadow(); - bool hasShadow(); - virtual void setShadowSize (int, int); - bool setAlwaysOnTop (bool); - bool setAlwaysOnTop(); - bool unsetAlwaysOnTop(); - bool isAlwaysOnTop(); + // Disable assignment operator (=) + FWindow& operator = (const FWindow&); + + // Methods + static void deleteFromAlwaysOnTopList (FWidget*); + static void processAlwaysOnTop(); + + // Data Members + bool window_active; + bool zoomed; + FWidget* win_focus_widget; + FRect normalGeometry; }; #pragma pack(pop) @@ -155,22 +164,6 @@ class FWindow : public FWidget inline const char* FWindow::getClassName() const { return "FWindow"; } -//---------------------------------------------------------------------- -inline FWindow* FWindow::getWindowWidgetAt (const FPoint& pos) -{ return getWindowWidgetAt (pos.getX(), pos.getY()); } - -//---------------------------------------------------------------------- -inline bool FWindow::raiseWindow() -{ return raiseWindow(this); } - -//---------------------------------------------------------------------- -inline bool FWindow::lowerWindow() -{ return lowerWindow(this); } - -//---------------------------------------------------------------------- -inline bool FWindow::isZoomed() const -{ return zoomed; } - //---------------------------------------------------------------------- inline bool FWindow::setWindowWidget() { return setWindowWidget(true); } @@ -187,10 +180,6 @@ inline bool FWindow::activateWindow() inline bool FWindow::deactivateWindow() { return activateWindow(false); } -//---------------------------------------------------------------------- -inline bool FWindow::isWindowActive() const -{ return window_active; } - //---------------------------------------------------------------------- inline bool FWindow::setResizeable() { return setResizeable(true); } @@ -199,10 +188,6 @@ inline bool FWindow::setResizeable() inline bool FWindow::unsetResizeable() { return setResizeable(false); } -//---------------------------------------------------------------------- -inline bool FWindow::isResizeable() -{ return ((flags & fc::resizeable) != 0); } - //---------------------------------------------------------------------- inline bool FWindow::setTransparentShadow() { return setTransparentShadow(true); } @@ -211,10 +196,6 @@ inline bool FWindow::setTransparentShadow() inline bool FWindow::unsetTransparentShadow() { return setTransparentShadow(false); } -//---------------------------------------------------------------------- -inline bool FWindow::hasTransparentShadow() -{ return ((flags & fc::trans_shadow) != 0); } - //---------------------------------------------------------------------- inline bool FWindow::setShadow() { return setShadow(true); } @@ -223,10 +204,6 @@ inline bool FWindow::setShadow() inline bool FWindow::unsetShadow() { return setShadow(false); } -//---------------------------------------------------------------------- -inline bool FWindow::hasShadow() -{ return ((flags & fc::shadow) != 0); } - //---------------------------------------------------------------------- inline bool FWindow::setAlwaysOnTop() { return setAlwaysOnTop(true); } @@ -236,8 +213,39 @@ inline bool FWindow::unsetAlwaysOnTop() { return setAlwaysOnTop(false); } //---------------------------------------------------------------------- -inline bool FWindow::isAlwaysOnTop() +inline bool FWindow::isZoomed() const +{ return zoomed; } + +//---------------------------------------------------------------------- +inline bool FWindow::isWindowActive() const +{ return window_active; } + +//---------------------------------------------------------------------- +inline bool FWindow::isResizeable() const +{ return ((flags & fc::resizeable) != 0); } + +//---------------------------------------------------------------------- +inline bool FWindow::isAlwaysOnTop() const { return ((flags & fc::always_on_top) != 0); } +//---------------------------------------------------------------------- +inline bool FWindow::hasTransparentShadow() const +{ return ((flags & fc::trans_shadow) != 0); } + +//---------------------------------------------------------------------- +inline bool FWindow::hasShadow() const +{ return ((flags & fc::shadow) != 0); } + +//---------------------------------------------------------------------- +inline FWindow* FWindow::getWindowWidgetAt (const FPoint& pos) +{ return getWindowWidgetAt (pos.getX(), pos.getY()); } + +//---------------------------------------------------------------------- +inline bool FWindow::raiseWindow() +{ return raiseWindow(this); } + +//---------------------------------------------------------------------- +inline bool FWindow::lowerWindow() +{ return lowerWindow(this); } #endif // _FWINDOW_H diff --git a/test/calculator.cpp b/test/calculator.cpp index 840b6647..aa979904 100644 --- a/test/calculator.cpp +++ b/test/calculator.cpp @@ -25,17 +25,19 @@ const lDouble PI = 3.141592653589793238L; class Button : public FButton { - private: - bool checked; - public: // Constructor explicit Button (FWidget* = 0); + // Method void setChecked(bool); // Event handler void onKeyPress (FKeyEvent*); + + private: + // Data Member + bool checked; }; #pragma pack(pop) @@ -91,7 +93,34 @@ void Button::onKeyPress (FKeyEvent* ev) class Calc : public FDialog { + public: + // Constructor + explicit Calc (FWidget* parent=0); + + // Destructor + ~Calc(); + + // Event handlers + void onKeyPress (FKeyEvent*); + void onAccel (FAccelEvent*); + void onClose (FCloseEvent*); + + // Callback method + void cb_buttonClicked (FWidget*, void*); + private: + // Methods + void drawDispay(); + virtual void draw(); + bool isDataEntryKey(int); + bool isOperatorKey(int); + void setDisplay (lDouble); + void setInfixOperator(char); + void clearInfixOperator(); + void calcInfixOperator(); + void adjustSize(); + + // Data Members bool error; bool arcus_mode; bool hyperbolic_mode; @@ -151,31 +180,6 @@ class Calc : public FDialog std::stack bracket_stack; std::map calculator_buttons; - - private: - void drawDispay(); - virtual void draw(); - bool isDataEntryKey(int); - bool isOperatorKey(int); - void setDisplay (lDouble); - void setInfixOperator(char); - void clearInfixOperator(); - void calcInfixOperator(); - void adjustSize(); - - public: - // Constructor - explicit Calc (FWidget* parent=0); - // Destructor - ~Calc(); - - // Event handlers - void onKeyPress (FKeyEvent*); - void onAccel (FAccelEvent*); - void onClose (FCloseEvent*); - - // Callback method - void cb_buttonClicked (FWidget*, void*); }; #pragma pack(pop) diff --git a/test/mandelbrot.cpp b/test/mandelbrot.cpp index eb339d4a..be87e247 100644 --- a/test/mandelbrot.cpp +++ b/test/mandelbrot.cpp @@ -13,19 +13,21 @@ class Mandelbrot : public FDialog { - private: - virtual void draw(); - void adjustSize(); - public: // Constructor explicit Mandelbrot (FWidget* = 0); + // Destructor ~Mandelbrot(); // Callback methods void onAccel (FAccelEvent*); void onClose (FCloseEvent*); + + private: + // Methods + virtual void draw(); + void adjustSize(); }; #pragma pack(pop) diff --git a/test/menu.cpp b/test/menu.cpp index ea0f4738..cbba9a6a 100644 --- a/test/menu.cpp +++ b/test/menu.cpp @@ -20,13 +20,23 @@ class Menu : public FDialog { + public: + // Constructor + explicit Menu (FWidget* = 0); + + // Destructor + ~Menu(); + private: // Disable copy constructor Menu (const Menu&); + // Disable assignment operator (=) Menu& operator = (const Menu&); + // Methods void defaultCallback (FMenuList*); + void adjustSize(); // Event handler void onClose (FCloseEvent*); @@ -34,14 +44,6 @@ class Menu : public FDialog // Callback methods void cb_message (FWidget*, void*); void cb_exitApp (FWidget*, void*); - - void adjustSize(); - - public: - // Constructor - explicit Menu (FWidget* = 0); - // Destructor - ~Menu(); }; #pragma pack(pop) @@ -204,9 +206,9 @@ Menu::~Menu() //---------------------------------------------------------------------- void Menu::defaultCallback (FMenuList* mb) { - for (uInt i=1; i <= mb->count(); i++) + for (uInt i=1; i <= mb->getCount(); i++) { - FMenuItem* item = mb->item(int(i)); + FMenuItem* item = mb->getItem(int(i)); if ( item && item->isEnabled() @@ -229,6 +231,16 @@ void Menu::defaultCallback (FMenuList* mb) } } +//---------------------------------------------------------------------- +void Menu::adjustSize() +{ + int pw = getParentWidget()->getWidth(); + int ph = getParentWidget()->getHeight(); + setX (1 + (pw - getWidth()) / 2, false); + setY (1 + (ph - getHeight()) / 4, false); + FDialog::adjustSize(); +} + //---------------------------------------------------------------------- void Menu::onClose (FCloseEvent* ev) { @@ -259,16 +271,6 @@ void Menu::cb_exitApp (FWidget*, void*) close(); } -//---------------------------------------------------------------------- -void Menu::adjustSize() -{ - int pw = getParentWidget()->getWidth(); - int ph = getParentWidget()->getHeight(); - setX (1 + (pw - getWidth()) / 2, false); - setY (1 + (ph - getHeight()) / 4, false); - FDialog::adjustSize(); -} - //---------------------------------------------------------------------- // main part diff --git a/test/term-attributes.cpp b/test/term-attributes.cpp index 2ddd8560..7a91293f 100644 --- a/test/term-attributes.cpp +++ b/test/term-attributes.cpp @@ -14,24 +14,10 @@ class AttribDlg : public FDialog { - private: - FButton* next_button; - FButton* back_button; - - public: - short bgcolor; - - private: - // Disable copy constructor - AttribDlg (const AttribDlg&); - // Disable assignment operator (=) - AttribDlg& operator = (const AttribDlg&); - - void adjustSize(); - public: // Constructor explicit AttribDlg (FWidget* = 0); + // Destructor ~AttribDlg(); @@ -43,15 +29,32 @@ class AttribDlg : public FDialog // Callback methods void cb_next (FWidget* = 0, void* = 0); void cb_back (FWidget* = 0, void* = 0); + + // Data Members + short bgcolor; + + private: + // Disable copy constructor + AttribDlg (const AttribDlg&); + // Disable assignment operator (=) + AttribDlg& operator = (const AttribDlg&); + + // Method + void adjustSize(); + + // Data Members + FButton* next_button; + FButton* back_button; + }; #pragma pack(pop) //---------------------------------------------------------------------- AttribDlg::AttribDlg (FWidget* parent) : FDialog(parent) + , bgcolor(wc.label_bg) , next_button() , back_button() - , bgcolor(wc.label_bg) { resetXTermForeground(); resetXTermBackground(); @@ -173,17 +176,10 @@ void AttribDlg::adjustSize() class AttribDemo : public FWidget { - private: - int colors; - - private: - void printColorLine(); - void printAltCharset(); - void draw(); - public: // Constructor explicit AttribDemo (FWidget* = 0); + // Destructor ~AttribDemo() { } @@ -192,9 +188,19 @@ class AttribDemo : public FWidget void onWheel (FWheelEvent* ev) { AttribDlg* p = dynamic_cast(getParentWidget()); + if ( p ) p->onWheel(ev); } + + private: + // Methods + void printColorLine(); + void printAltCharset(); + void draw(); + + // Data Member + int colors; }; #pragma pack(pop) diff --git a/test/timer.cpp b/test/timer.cpp index b74f2706..ccf0397e 100644 --- a/test/timer.cpp +++ b/test/timer.cpp @@ -13,11 +13,12 @@ class timer : public FWidget explicit timer (FWidget* = 0); protected: + // Method + void draw(); + // Event handlers void onTimer (FTimerEvent*); void onAccel (FAccelEvent*); - - void draw(); }; //---------------------------------------------------------------------- @@ -36,6 +37,19 @@ timer::timer (FWidget* parent) wc.term_bg = fc::Default; } +//---------------------------------------------------------------------- +void timer::draw() +{ + setNormal(); + setColor (fc::Default, fc::Default); + clearArea (vdesktop); + setPrintPos (1,1); + print ("---------------\n"); + print ("Press Q to quit\n"); + print ("---------------\n"); + setAreaCursor (1, 4, true, vdesktop); +} + //---------------------------------------------------------------------- void timer::onTimer (FTimerEvent* ev) { @@ -66,19 +80,6 @@ void timer::onAccel (FAccelEvent* ev) ev->accept(); } -//---------------------------------------------------------------------- -void timer::draw() -{ - setNormal(); - setColor (fc::Default, fc::Default); - clearArea (vdesktop); - setPrintPos (1,1); - print ("---------------\n"); - print ("Press Q to quit\n"); - print ("---------------\n"); - setAreaCursor (1, 4, true, vdesktop); -} - //---------------------------------------------------------------------- // main part diff --git a/test/transparent.cpp b/test/transparent.cpp index 864c1641..0f04d8b8 100644 --- a/test/transparent.cpp +++ b/test/transparent.cpp @@ -18,6 +18,7 @@ class Transparent : public FDialog { public: + // Typedef and Enumeration typedef enum ttype { transparent = 0, @@ -25,25 +26,28 @@ class Transparent : public FDialog inherit_background = 2 } trans_type; - private: - trans_type type; + public: + // Constructor + explicit Transparent (FWidget* = 0, trans_type = transparent); + + // Destructor + ~Transparent(); private: // Disable copy constructor Transparent (const Transparent&); + // Disable assignment operator (=) Transparent& operator = (const Transparent&); + // Method void draw(); // Event handlers void onKeyPress (FKeyEvent* ev); - public: - // Constructor - explicit Transparent (FWidget* = 0, trans_type = transparent); - // Destructor - ~Transparent(); + // Data Members + trans_type type; }; #pragma pack(pop) diff --git a/test/ui.cpp b/test/ui.cpp index 9328a1da..022a3fdb 100644 --- a/test/ui.cpp +++ b/test/ui.cpp @@ -15,11 +15,11 @@ class ProgressDialog : public FDialog { - private: - FProgressbar* progressBar; - FButton* reset; - FButton* more; - FButton* quit; + public: + // Constructor + explicit ProgressDialog (FWidget* = 0); + // Destructor + ~ProgressDialog(); private: // Disable copy constructor @@ -36,11 +36,11 @@ class ProgressDialog : public FDialog void cb_more_bar (FWidget*, void*); void cb_exit_bar (FWidget*, void*); - public: - // Constructor - explicit ProgressDialog (FWidget* = 0); - // Destructor - ~ProgressDialog(); + // Data Members + FProgressbar* progressBar; + FButton* reset; + FButton* more; + FButton* quit; }; #pragma pack(pop) @@ -134,8 +134,8 @@ void ProgressDialog::onTimer (FTimerEvent*) quit->setEnable(); redraw(); - if ( statusBar() ) - statusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); updateTerminal(); flush_out(); @@ -170,8 +170,13 @@ void ProgressDialog::cb_exit_bar (FWidget*, void*) class TextWindow : public FDialog { - private: - FTextView* scrollText; + public: + // Constructor + explicit TextWindow (FWidget* = 0); + // Destructor + ~TextWindow(); + + void append (const FString&); private: // Disable copy constructor @@ -181,13 +186,8 @@ class TextWindow : public FDialog void adjustSize(); - public: - // Constructor - explicit TextWindow (FWidget* = 0); - // Destructor - ~TextWindow(); - - void append (const FString&); + // Data Members + FTextView* scrollText; }; #pragma pack(pop) @@ -238,10 +238,11 @@ void TextWindow::adjustSize() class MyDialog : public FDialog { - private: - FLineEdit* myLineEdit; - FListBox* myList; - FString clipboard; + public: + // Constructor + explicit MyDialog (FWidget* = 0); + // Destructor + ~MyDialog(); private: // Disable copy constructor @@ -272,11 +273,10 @@ class MyDialog : public FDialog void adjustSize(); - public: - // Constructor - explicit MyDialog (FWidget* = 0); - // Destructor - ~MyDialog(); + // Data Members + FLineEdit* myLineEdit; + FListBox* myList; + FString clipboard; }; #pragma pack(pop) @@ -518,7 +518,7 @@ MyDialog::MyDialog (FWidget* parent) FLabel* sum_count = new FLabel (this); sum_count->setGeometry(29, 5, 5, 3); - sum_count->setNumber (myList->count()); + sum_count->setNumber (myList->getCount()); // Statusbar at the bottom FStatusBar* statusbar = new FStatusBar (this); @@ -790,7 +790,7 @@ void MyDialog::cb_updateNumber (FWidget* widget, void* data_ptr) FListBox* list = static_cast(widget); FLabel* num = static_cast(data_ptr); int select_num = 0; - uInt end = list->count(); + uInt end = list->getCount(); for (uInt n=1; n <= end; n++) if ( list->isSelected(int(n)) ) @@ -858,7 +858,7 @@ void MyDialog::cb_setInput (FWidget* widget, void* data_ptr) { FListBox* ListBox = static_cast(widget); FLineEdit* lineedit = static_cast(data_ptr); - lineedit->setText( ListBox->Item(ListBox->currentItem()).getText() ); + lineedit->setText( ListBox->getItem(ListBox->currentItem()).getText() ); lineedit->redraw(); } diff --git a/test/watch.cpp b/test/watch.cpp index 46e89bcb..bccb0c39 100644 --- a/test/watch.cpp +++ b/test/watch.cpp @@ -17,27 +17,14 @@ class watch : public FDialog { - private: - bool sec; - - private: - FLabel* time_label; - FLabel* time_str; - FSwitch* clock_sw; - FSwitch* seconds_sw; - - private: - // Disable copy constructor - watch (const watch&); - // Disable assignment operator (=) - watch& operator = (const watch&); - public: // Constructor explicit watch (FWidget* = 0); + // Destructor ~watch(); + // Method void printTime(); // Event handlers @@ -50,7 +37,22 @@ class watch : public FDialog void cb_exitApp (FWidget*, void*); protected: + // Method void adjustSize(); + + private: + // Disable copy constructor + watch (const watch&); + + // Disable assignment operator (=) + watch& operator = (const watch&); + + // Data Members + bool sec; + FLabel* time_label; + FLabel* time_str; + FSwitch* clock_sw; + FSwitch* seconds_sw; }; #pragma pack(pop) diff --git a/test/windows.cpp b/test/windows.cpp index 4c87b6cb..7a187ded 100644 --- a/test/windows.cpp +++ b/test/windows.cpp @@ -19,32 +19,33 @@ class smallWindow : public FDialog { - private: - FLabel* left_arrow; - FLabel* right_arrow; - FLabel* top_left_label; - FLabel* top_right_label; - FLabel* bottom_label; + public: + // Constructor + explicit smallWindow (FWidget* = 0); + + // Destructor + ~smallWindow(); private: // Disable copy constructor smallWindow (const smallWindow&); + // Disable assignment operator (=) smallWindow& operator = (const smallWindow&); + // Method void adjustSize(); // Event handlers void onShow (FShowEvent*); void onTimer (FTimerEvent*); - public: - // Constructor - explicit smallWindow (FWidget* = 0); - // Destructor - ~smallWindow(); - - void append (const FString&); + // Data Members + FLabel* left_arrow; + FLabel* right_arrow; + FLabel* top_left_label; + FLabel* top_right_label; + FLabel* bottom_label; }; #pragma pack(pop) @@ -164,7 +165,15 @@ void smallWindow::onTimer (FTimerEvent*) class Window : public FDialog { + public: + // Constructor + explicit Window (FWidget* = 0); + + // Destructor + ~Window(); + private: + // Typedef typedef struct { bool is_open; @@ -172,15 +181,16 @@ class Window : public FDialog FDialog* dgl; } win_data; - std::vector windows; - private: // Disable copy constructor Window (const Window&); + // Disable assignment operator (=) Window& operator = (const Window&); + // Method void activateWindow (FDialog*); + void adjustSize(); // Event handlers void onClose (FCloseEvent*); @@ -193,13 +203,8 @@ class Window : public FDialog void cb_exitApp (FWidget*, void*); void cb_destroyWindow (FWidget*, void*); - void adjustSize(); - - public: - // Constructor - explicit Window (FWidget* = 0); - // Destructor - ~Window(); + // Data Members + std::vector windows; }; #pragma pack(pop) @@ -351,6 +356,41 @@ void Window::activateWindow (FDialog* win) updateTerminal(); } +//---------------------------------------------------------------------- +void Window::adjustSize() +{ + int w,h,X,Y,dx,dy; + std::vector::const_iterator iter, begin; + w = getRootWidget()->getWidth(); + h = getRootWidget()->getHeight(); + X = int(1 + (w - 40) / 2); + Y = int(1 + (h - 22) / 2); + dx = (w > 80) ? (w - 80) / 2 : 0; + dy = (h > 24) ? (h - 24) / 2 : 0; + + if ( Y < 2) + Y = 2; + + setPos (X, Y); + iter = begin = windows.begin(); + + while ( iter != windows.end() ) + { + if ( (*iter)->is_open ) + { + int x,y,n; + n = int(std::distance(begin, iter)); + x = dx + 5 + (n%3)*25 + int(n/3)*3; + y = dy + 11 + int(n/3)*3; + (*iter)->dgl->setPos (x, y); + } + + ++iter; + } + + FDialog::adjustSize(); +} + //---------------------------------------------------------------------- void Window::onClose (FCloseEvent* ev) { @@ -524,40 +564,6 @@ void Window::cb_destroyWindow (FWidget*, void* data_ptr) win_dat->is_open = false; } -//---------------------------------------------------------------------- -void Window::adjustSize() -{ - int w,h,X,Y,dx,dy; - std::vector::const_iterator iter, begin; - w = getRootWidget()->getWidth(); - h = getRootWidget()->getHeight(); - X = int(1 + (w - 40) / 2); - Y = int(1 + (h - 22) / 2); - dx = (w > 80) ? (w - 80) / 2 : 0; - dy = (h > 24) ? (h - 24) / 2 : 0; - - if ( Y < 2) - Y = 2; - - setPos (X, Y); - iter = begin = windows.begin(); - - while ( iter != windows.end() ) - { - if ( (*iter)->is_open ) - { - int x,y,n; - n = int(std::distance(begin, iter)); - x = dx + 5 + (n%3)*25 + int(n/3)*3; - y = dy + 11 + int(n/3)*3; - (*iter)->dgl->setPos (x, y); - } - - ++iter; - } - - FDialog::adjustSize(); -} //---------------------------------------------------------------------- // main part