From 3f8ed6e78ef76752e3a9a87f4b182011a194dbbd Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sat, 18 Feb 2017 23:37:10 +0100 Subject: [PATCH] Allows a window to have more than one FScrollView widget --- ChangeLog | 7 ++- src/fscrollview.cpp | 39 ++++++++++----- src/fscrollview.h | 35 ++++++++++++++ src/fvterm.cpp | 109 ++++++++++++++++++++++++++---------------- src/fvterm.h | 44 ++++++++++++++--- src/fwidget.cpp | 18 +++---- src/fwidget.h | 8 ++++ test/input-dialog.cpp | 2 +- 8 files changed, 192 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index f35201f7..52ca5c04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ +2017-02-18 Markus Gans + * Allows a window to have more than one FScrollView widget + 2017-02-07 Markus Gans - * Uses termcap capability U8 to identify terminals that can't display - vt100 line-drawing in UTF-8 mode + * Uses termcap capability U8 to identify terminals that + can't display vt100 line-drawing in UTF-8 mode 2017-01-28 Markus Gans * Allow to change the focus out from FScrollView to another widget diff --git a/src/fscrollview.cpp b/src/fscrollview.cpp index 6c0094ed..0a139f46 100644 --- a/src/fscrollview.cpp +++ b/src/fscrollview.cpp @@ -18,6 +18,7 @@ FScrollView::FScrollView (FWidget* parent) , vbar(0) , hbar(0) , nf_offset(0) + , border(true) , use_own_print_area(false) , vMode(fc::Auto) , hMode(fc::Auto) @@ -50,7 +51,8 @@ void FScrollView::setScrollWidth (int width) FPoint no_shadow(0,0); scroll_geometry.setWidth (width); resizeArea (scroll_geometry, no_shadow, viewport); - setPreprocessingHandler + + addPreprocessingHandler ( _PREPROC_HANDLER (this, &FScrollView::copy2area) ); @@ -77,7 +79,7 @@ void FScrollView::setScrollHeight (int height) FPoint no_shadow(0,0); scroll_geometry.setHeight (height); resizeArea (scroll_geometry, no_shadow, viewport); - setPreprocessingHandler + addPreprocessingHandler ( _PREPROC_HANDLER (this, &FScrollView::copy2area) ); @@ -107,7 +109,7 @@ void FScrollView::setScrollSize (int width, int height) FPoint no_shadow(0,0); scroll_geometry.setSize (width, height); resizeArea (scroll_geometry, no_shadow, viewport); - setPreprocessingHandler + addPreprocessingHandler ( _PREPROC_HANDLER (this, &FScrollView::copy2area) ); @@ -169,7 +171,7 @@ void FScrollView::setPos (int x, int y, bool adjust) { FWidget::setPos (x, y, adjust); scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1 - , getTermY() + getTopPadding() - 1 ); + , getTermY() + getTopPadding() - 1 ); if ( ! adjust ) { @@ -242,6 +244,18 @@ void FScrollView::setPrintPos (register int x, register int y) FWidget::setPrintPos (x + getLeftPadding(), y + getTopPadding()); } +//---------------------------------------------------------------------- +bool FScrollView::setViewportPrint (bool on) +{ + return use_own_print_area = ! on; +} + +//---------------------------------------------------------------------- +bool FScrollView::setBorder (bool on) +{ + return border = on; +} + //---------------------------------------------------------------------- void FScrollView::setHorizontalScrollBarMode (fc::scrollBarMode mode) { @@ -325,7 +339,7 @@ void FScrollView::scrollBy (int dx, int dy) //---------------------------------------------------------------------- void FScrollView::draw() { - use_own_print_area = true; + unsetViewportPrint(); if ( isMonochron() ) setReverse(true); @@ -335,15 +349,18 @@ void FScrollView::draw() else setColor(); - if ( isNewFont() ) - drawBorder (1, 1, getWidth() - 1, getHeight()); - else - drawBorder(); + if ( border ) + { + if ( isNewFont() ) + drawBorder (1, 1, getWidth() - 1, getHeight()); + else + drawBorder(); + } if ( isMonochron() ) setReverse(false); - use_own_print_area = false; + setViewportPrint(); copy2area(); redrawVBar(); redrawHBar(); @@ -737,7 +754,7 @@ void FScrollView::init() scroll_geometry.setRect (0, 0, w, h); createArea (scroll_geometry, no_shadow, viewport); - setPreprocessingHandler + addPreprocessingHandler ( _PREPROC_HANDLER (this, &FScrollView::copy2area) ); diff --git a/src/fscrollview.h b/src/fscrollview.h index 131b3a59..ef525e78 100644 --- a/src/fscrollview.h +++ b/src/fscrollview.h @@ -76,9 +76,19 @@ class FScrollView : public FWidget virtual void setSize (int, int, bool = true); void setGeometry (int, int, int, int, bool = true); void setPrintPos (register int, register int); + bool setViewportPrint (bool); + bool setViewportPrint(); + bool unsetViewportPrint(); + bool setBorder (bool); + bool setBorder(); + bool unsetBorder(); void setHorizontalScrollBarMode (fc::scrollBarMode); void setVerticalScrollBarMode (fc::scrollBarMode); + // Inquiries + bool hasBorder(); + bool isViewportPrint(); + // Method virtual void clearArea (int = ' '); void scrollToX (int); @@ -138,6 +148,7 @@ class FScrollView : public FWidget FScrollbar* vbar; FScrollbar* hbar; int nf_offset; + bool border; bool use_own_print_area; fc::scrollBarMode vMode; // fc:Auto, fc::Hidden or fc::Scroll fc::scrollBarMode hMode; @@ -178,6 +189,30 @@ inline int FScrollView::getScrollX() const inline int FScrollView::getScrollY() const { return viewport_geometry.getY(); } +//---------------------------------------------------------------------- +inline bool FScrollView::setViewportPrint() +{ return setViewportPrint(true); } + +//---------------------------------------------------------------------- +inline bool FScrollView::unsetViewportPrint() +{ return setViewportPrint(false); } + +//---------------------------------------------------------------------- +inline bool FScrollView::setBorder() +{ return setBorder(true); } + +//---------------------------------------------------------------------- +inline bool FScrollView::unsetBorder() +{ return setBorder(false); } + +//---------------------------------------------------------------------- +inline bool FScrollView::hasBorder() +{ return border; } + +//---------------------------------------------------------------------- +inline bool FScrollView::isViewportPrint() +{ return ! use_own_print_area; } + //---------------------------------------------------------------------- inline void FScrollView::scrollTo (FPoint pos) { scrollTo(pos.getX(), pos.getY()); } diff --git a/src/fvterm.cpp b/src/fvterm.cpp index e7b36be1..de314437 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -155,20 +155,6 @@ void FVTerm::setPrintCursor (register int x, register int y) } } -//---------------------------------------------------------------------- -void FVTerm::setPreprocessingHandler ( FVTerm* instance - , FPreprocessingHandler handler ) -{ - if ( ! print_area ) - FVTerm::getPrintArea(); - - if ( print_area ) - { - print_area->pre_proc_instance = instance; - print_area->pre_proc = handler; - } -} - //---------------------------------------------------------------------- void FVTerm::clearArea (int fillchar) { @@ -255,6 +241,42 @@ void FVTerm::updateTerminal() updateTerminalCursor(); } +//---------------------------------------------------------------------- +void FVTerm::addPreprocessingHandler ( FVTerm* instance + , FPreprocessingHandler handler ) +{ + if ( ! print_area ) + FVTerm::getPrintArea(); + + if ( print_area ) + { + vterm_preprocessing obj = { instance, handler }; + delPreprocessingHandler (instance); + print_area->preprocessing_call.push_back(obj); + } +} + +//---------------------------------------------------------------------- +void FVTerm::delPreprocessingHandler (FVTerm* instance) +{ + if ( ! print_area ) + FVTerm::getPrintArea(); + + if ( ! print_area || ! print_area->preprocessing_call.empty() ) + return; + + FPreprocessing::iterator iter, end; + iter = print_area->preprocessing_call.begin(); + + while ( iter != print_area->preprocessing_call.end() ) + { + if ( iter->instance == instance ) + iter = print_area->preprocessing_call.erase(iter); + else + ++iter; + } +} + //---------------------------------------------------------------------- int FVTerm::printf (const wchar_t* format, ...) { @@ -690,26 +712,7 @@ void FVTerm::createArea ( int offset_top, int offset_left // initialize virtual window area = new term_area; - - area->offset_top = 0; - area->offset_left = 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->has_changes = false; - area->changes = 0; - area->text = 0; - area->visible = false; - area->widget = static_cast(this); - area->pre_proc_instance = 0; - area->pre_proc = 0; - + area->widget = static_cast(this); resizeArea (offset_top, offset_left, width, height, rsw, bsh, area); } @@ -1064,12 +1067,24 @@ void FVTerm::updateVTerm() updateVTerm(win); win->has_changes = false; } - else if ( win->pre_proc_instance - && win->pre_proc_instance->child_print_area - && win->pre_proc_instance->child_print_area->has_changes ) + else if ( ! win->preprocessing_call.empty() ) { - updateVTerm(win); - win->pre_proc_instance->child_print_area->has_changes = false; + FPreprocessing::const_iterator iter, end; + iter = win->preprocessing_call.begin(); + end = win->preprocessing_call.end(); + + while ( iter != end ) + { + if ( iter->instance->child_print_area + && iter->instance->child_print_area->has_changes ) + { + updateVTerm(win); + iter->instance->child_print_area->has_changes = false; + break; + } + + ++iter; + } } } } @@ -1090,8 +1105,20 @@ void FVTerm::updateVTerm (term_area* area) return; // Call preprocessing handler - if ( area->pre_proc_instance && area->pre_proc ) - (area->pre_proc_instance->*area->pre_proc)(); + if ( ! area->preprocessing_call.empty() ) + { + FPreprocessing::const_iterator iter, end; + iter = area->preprocessing_call.begin(); + end = area->preprocessing_call.end(); + + while ( iter != end ) + { + FPreprocessingHandler handler = iter->handler; + // call the preprocessing handler + (iter->instance->*handler)(); + ++iter; + } + } ax = area->offset_top; ay = area->offset_left; diff --git a/src/fvterm.h b/src/fvterm.h index cabd5f04..5c7a2366 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -58,8 +58,39 @@ class FVTerm : public FObject, public FTerm typedef FOptiAttr::char_data char_data; typedef void (FVTerm::*FPreprocessingHandler)(); - typedef struct + struct vterm_preprocessing { + FVTerm* instance; + FPreprocessingHandler handler; + }; + + typedef std::vector FPreprocessing; + + struct term_area + { + term_area() + : offset_top (0) + , offset_left (0) + , width (-1) + , height (-1) + , right_shadow (0) + , bottom_shadow (0) + , cursor_x (0) + , cursor_y (0) + , input_cursor_x (-1) + , input_cursor_y (-1) + , widget() + , preprocessing_call() + , changes (0) + , text (0) + , input_cursor_visible (false) + , has_changes (false) + , visible (false) + { } + + ~term_area() + { } + int offset_top; // Distance from top of the terminal int offset_left; // Distance from left terminal side int width; // Window width @@ -71,14 +102,13 @@ class FVTerm : public FObject, public FTerm int input_cursor_x; // X-position input cursor int input_cursor_y; // Y-position input cursor FWidget* widget; // Widget that owns this term_area - FVTerm* pre_proc_instance; - FPreprocessingHandler pre_proc; + FPreprocessing preprocessing_call; line_changes* changes; char_data* text; // Text data for the output bool input_cursor_visible; bool has_changes; bool visible; - } term_area; + }; enum covered_state { @@ -177,9 +207,6 @@ class FVTerm : public FObject, public FTerm static bool setInheritBackground(); static bool unsetInheritBackground(); - void setPreprocessingHandler ( FVTerm* - , FPreprocessingHandler ); - // Inquiries static bool isCursorHidden(); static bool isBold(); @@ -208,6 +235,9 @@ class FVTerm : public FObject, public FTerm static void putVTerm(); static void updateTerminal (bool); static void updateTerminal(); + void addPreprocessingHandler ( FVTerm* + , FPreprocessingHandler ); + void delPreprocessingHandler (FVTerm*); int printf (const wchar_t*, ...); int printf (const char*, ...) diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 60b077ef..cd3a198a 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -865,7 +865,7 @@ bool FWidget::close() //---------------------------------------------------------------------- void FWidget::addCallback ( FString cb_signal - , FWidget::FCallback cb_handler + , FCallback cb_handler , data_ptr data ) { // add a (normal) function pointer as callback @@ -876,7 +876,7 @@ void FWidget::addCallback ( FString cb_signal //---------------------------------------------------------------------- void FWidget::addCallback ( FString cb_signal , FWidget* cb_instance - , FWidget::FMemberCallback cb_handler + , FMemberCallback cb_handler , data_ptr data ) { // add a member function pointer as callback @@ -885,11 +885,12 @@ void FWidget::addCallback ( FString cb_signal } //---------------------------------------------------------------------- -void FWidget::delCallback (FWidget::FCallback cb_handler) +void FWidget::delCallback (FCallback cb_handler) { - FWidget::CallbackObjects::iterator iter; - // delete a cb_handler function pointer + + CallbackObjects::iterator iter; + if ( callback_objects.empty() ) return; @@ -907,9 +908,10 @@ void FWidget::delCallback (FWidget::FCallback cb_handler) //---------------------------------------------------------------------- void FWidget::delCallback (FWidget* cb_instance) { + // delete all member function pointer from cb_instance + FWidget::MemberCallbackObjects::iterator iter; - // delete all member function pointer from cb_instance if ( member_callback_objects.empty() ) return; @@ -939,7 +941,7 @@ void FWidget::emitCallback (FString emit_signal) // member function pointer if ( ! member_callback_objects.empty() ) { - FWidget::MemberCallbackObjects::const_iterator m_iter, m_end; + MemberCallbackObjects::const_iterator m_iter, m_end; m_iter = member_callback_objects.begin(); m_end = member_callback_objects.end(); @@ -959,7 +961,7 @@ void FWidget::emitCallback (FString emit_signal) // function pointer if ( ! callback_objects.empty() ) { - FWidget::CallbackObjects::const_iterator iter, end; + CallbackObjects::const_iterator iter, end; iter = callback_objects.begin(); end = callback_objects.end(); diff --git a/src/fwidget.h b/src/fwidget.h index 96ad0481..37b52dee 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -453,18 +453,22 @@ class FWidget : public FVTerm , max_width (INT_MAX) , max_height (INT_MAX) { } + ~widget_size_hints() { } + void setMinimum (int w, int h) { min_width = w; min_height = h; } + void setMaximum (int w, int h) { max_width = w; max_height = h; } + int min_width; int min_height; int max_width; @@ -475,8 +479,10 @@ class FWidget : public FVTerm { dbl_line_mask() : top(), right(), bottom(), left() { } + ~dbl_line_mask() { } + std::vector top; std::vector right; std::vector bottom; @@ -487,8 +493,10 @@ class FWidget : public FVTerm { widget_padding() : top(0), left(0), bottom(0), right(0) { } + ~widget_padding() { } + int top; int left; int bottom; diff --git a/test/input-dialog.cpp b/test/input-dialog.cpp index c5ccd5a5..d29b6aad 100644 --- a/test/input-dialog.cpp +++ b/test/input-dialog.cpp @@ -78,7 +78,7 @@ int main (int argc, char* argv[]) // Create radio buttons FRadioButton* male = new FRadioButton("&Male", radioButtonGroup); - FRadioButton* female = new FRadioButton("&Female",radioButtonGroup); + FRadioButton* female = new FRadioButton("&Female", radioButtonGroup); male->setGeometry(1, 1, 7, 1); female->setGeometry(1, 2, 7, 1);