From 49e36e52034237e5541f2a60a3ebcd9325d524cc Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sat, 7 Jan 2017 22:09:09 +0100 Subject: [PATCH] Add scrollTo and scrollBy methods to FScrollView --- ChangeLog | 3 + src/fscrollview.cpp | 166 +++++++++++++++++++++++++++++++++++--------- src/fscrollview.h | 41 ++++++++--- src/fvterm.cpp | 8 ++- src/fvterm.h | 1 + 5 files changed, 177 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index ed7392d6..3a272d6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2017-01-07 Markus Gans + * Add scrollTo and scrollBy methods to FScrollView + 2017-01-03 Markus Gans * FScrollView now has on-demand scroll bars * Arrow keys support for FScrollView viewport scrolling diff --git a/src/fscrollview.cpp b/src/fscrollview.cpp index 2c6cccf1..96c55d93 100644 --- a/src/fscrollview.cpp +++ b/src/fscrollview.cpp @@ -31,6 +31,7 @@ FScrollView::~FScrollView() // destructor delete vbar; delete hbar; removeArea (viewport); + child_print_area = viewport = 0; } @@ -49,6 +50,7 @@ void FScrollView::setScrollWidth (int width) FPoint no_shadow(0,0); scroll_size.setWidth (width); resizeArea (scroll_size, no_shadow, viewport); + child_print_area = viewport; } hbar->setMaximum (width - getClientWidth()); @@ -71,6 +73,7 @@ void FScrollView::setScrollHeight (int height) FPoint no_shadow(0,0); scroll_size.setHeight (height); resizeArea (scroll_size, no_shadow, viewport); + child_print_area = viewport; } vbar->setMaximum (height - getClientHeight()); @@ -96,6 +99,7 @@ void FScrollView::setScrollSize (int width, int height) FPoint no_shadow(0,0); scroll_size.setSize (width, height); resizeArea (scroll_size, no_shadow, viewport); + child_print_area = viewport; } hbar->setMaximum (width - getClientWidth()); @@ -116,7 +120,7 @@ void FScrollView::setX (int x, bool adjust) if ( ! adjust ) { - scroll_size.setX (getTermX() - 1); + scroll_size.setX (getTermX() + getLeftPadding() - 1); if ( viewport ) { @@ -133,7 +137,7 @@ void FScrollView::setY (int y, bool adjust) if ( ! adjust ) { - scroll_size.setY (getTermY() - 1); + scroll_size.setY (getTermY() + getTopPadding() - 1); if ( viewport ) { @@ -147,7 +151,8 @@ void FScrollView::setY (int y, bool adjust) void FScrollView::setPos (int x, int y, bool adjust) { FWidget::setPos (x, y, adjust); - scroll_size.setPos (getTermX() - 1, getTermY() - 1); + scroll_size.setPos ( getTermX() + getLeftPadding() - 1 + , getTermY() + getTopPadding() - 1 ); if ( ! adjust ) { @@ -194,7 +199,8 @@ void FScrollView::setSize (int w, int h, bool adjust) void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust) { FWidget::setGeometry (x, y, w, h, adjust); - scroll_size.setPos (getTermX() - 1, getTermY() - 1); + scroll_size.setPos ( getTermX() + getLeftPadding() - 1 + , getTermY() + getTopPadding() - 1 ); calculateScrollbarPos(); if ( getScrollWidth() < getClientWidth() @@ -209,6 +215,12 @@ void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust) } } +//---------------------------------------------------------------------- +void FScrollView::setPrintPos (register int x, register int y) +{ + FWidget::setPrintPos (x + getLeftPadding(), y + getTopPadding()); +} + //---------------------------------------------------------------------- void FScrollView::setHorizontalScrollBarMode (fc::scrollBarMode mode) { @@ -230,6 +242,59 @@ void FScrollView::clearArea (int fillchar) clearArea (viewport, fillchar); } +//---------------------------------------------------------------------- +void FScrollView::scrollToX (int x) +{ + scrollTo (x, scroll_offset.getY()); +} + +//---------------------------------------------------------------------- +void FScrollView::scrollToY (int y) +{ + scrollTo (scroll_offset.getX(), y); +} + +//---------------------------------------------------------------------- +void FScrollView::scrollTo (int x, int y) +{ + short& xoffset = scroll_offset.x_ref(); + short& yoffset = scroll_offset.y_ref(); + short xoffset_end = short(getScrollWidth() - getClientWidth()); + short yoffset_end = short(getScrollHeight() - getClientHeight()); + + if ( xoffset == short(x) && yoffset == short(y) ) + return; + + xoffset = short(x); + yoffset = short(y); + + if ( yoffset < 0 ) + yoffset = 0; + + if ( yoffset > yoffset_end ) + yoffset = yoffset_end; + + if ( xoffset < 0 ) + xoffset = 0; + + if ( xoffset > xoffset_end ) + xoffset = xoffset_end; + + hbar->setValue (xoffset); + vbar->setValue (yoffset); + drawHBar(); + drawVBar(); + viewport->has_changes = true; + copy2area(); + updateTerminal(); +} + +//---------------------------------------------------------------------- +void FScrollView::scrollBy (int dx, int dy) +{ + scrollTo (getScrollX() + dx, getScrollY() + dy); +} + //---------------------------------------------------------------------- void FScrollView::draw() { @@ -247,12 +312,8 @@ void FScrollView::draw() use_own_print_area = false; copy2area(); - - if ( vbar->isVisible() ) - vbar->redraw(); - - if ( hbar->isVisible() ) - hbar->redraw(); + redrawVBar(); + redrawHBar(); } //---------------------------------------------------------------------- @@ -339,12 +400,8 @@ void FScrollView::onKeyPress (FKeyEvent* ev) hasChanges = true; vbar->setValue (yoffset); hbar->setValue (xoffset); - - if ( vbar->isVisible() ) - vbar->drawBar(); - - if ( hbar->isVisible() ) - hbar->drawBar(); + drawVBar(); + drawHBar(); } if ( hasChanges ) @@ -400,9 +457,7 @@ void FScrollView::onWheel (FWheelEvent* ev) copy2area(); hasChanges = true; vbar->setValue (yoffset); - - if ( vbar->isVisible() ) - vbar->drawBar(); + drawVBar(); } if ( hasChanges ) @@ -414,12 +469,17 @@ void FScrollView::onWheel (FWheelEvent* ev) //---------------------------------------------------------------------- FVTerm::term_area* FScrollView::getPrintArea() { - // returns the viewport print area + // returns print area or viewport - if ( viewport && ! use_own_print_area ) - return viewport; + if ( use_own_print_area || ! viewport ) + { + child_print_area = 0; + term_area* area = FVTerm::getPrintArea(); + child_print_area = viewport; + return area; + } else - return FVTerm::getPrintArea(); + return viewport; } //---------------------------------------------------------------------- @@ -431,7 +491,8 @@ void FScrollView::adjustSize() int xoffset = scroll_offset.getX(); int yoffset = scroll_offset.getY(); - scroll_size.setPos (getTermX() - 1, getTermY() - 1); + scroll_size.setPos ( getTermX() + getLeftPadding() - 1 + , getTermY() + getTopPadding() - 1 ); if ( viewport ) { @@ -534,8 +595,11 @@ void FScrollView::init() setRightPadding(1 + nf_offset); FPoint no_shadow(0,0); - scroll_size.setRect (0, 0, getClientWidth(), getClientHeight()); + scroll_size.setRect (1, 1, getClientWidth(), getClientHeight()); createArea (scroll_size, no_shadow, viewport); + + if ( viewport ) + child_print_area = viewport; } //---------------------------------------------------------------------- @@ -698,9 +762,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*) && hasChanges ) { vbar->setValue (yoffset); - - if ( vbar->isVisible() ) - vbar->drawBar(); + drawVBar(); } if ( hasChanges ) @@ -801,11 +863,53 @@ void FScrollView::cb_HBarChange (FWidget*, void*) && hasChanges ) { hbar->setValue (xoffset); - - if ( hbar->isVisible() ) - hbar->drawBar(); + drawHBar(); } if ( hasChanges ) updateTerminal(); } + +//---------------------------------------------------------------------- +inline void FScrollView::redrawHBar() +{ + child_print_area = 0; + + if ( hbar->isVisible() ) + hbar->redraw(); + + child_print_area = viewport; +} + +//---------------------------------------------------------------------- +inline void FScrollView::redrawVBar() +{ + child_print_area = 0; + + if ( vbar->isVisible() ) + vbar->redraw(); + + child_print_area = viewport; +} + +//---------------------------------------------------------------------- +inline void FScrollView::drawHBar() +{ + child_print_area = 0; + + if ( hbar->isVisible() ) + hbar->drawBar(); + + child_print_area = viewport; +} + +//---------------------------------------------------------------------- +inline void FScrollView::drawVBar() +{ + child_print_area = 0; + + if ( vbar->isVisible() ) + vbar->drawBar(); + + child_print_area = viewport; +} diff --git a/src/fscrollview.h b/src/fscrollview.h index add83a96..3efd145c 100644 --- a/src/fscrollview.h +++ b/src/fscrollview.h @@ -45,6 +45,7 @@ class FScrollView : public FWidget public: // Using-declaration using FWidget::setGeometry; + using FWidget::setPrintPos; using FWidget::setPos; // Constructor @@ -55,15 +56,16 @@ class FScrollView : public FWidget // Accessors const char* getClassName() const; - int getScrollWidth(); - int getScrollHeight(); + int getScrollWidth() const; + int getScrollHeight() const; + const FPoint getScrollPos() const; + int getScrollX() const; + int getScrollY() const; // Mutator void setScrollWidth (int); void setScrollHeight (int); void setScrollSize (int, int); - void setScrollOffset (FPoint); - void setScrollOffset (int, int); virtual void setX (int, bool = true); virtual void setY (int, bool = true); virtual void setPos (int, int, bool = true); @@ -71,11 +73,17 @@ class FScrollView : public FWidget virtual void setHeight (int, bool = true); virtual void setSize (int, int, bool = true); void setGeometry (int, int, int, int, bool = true); + void setPrintPos (register int, register int); void setHorizontalScrollBarMode (fc::scrollBarMode); void setVerticalScrollBarMode (fc::scrollBarMode); // Method virtual void clearArea (int = ' '); + void scrollToX (int); + void scrollToY (int); + void scrollTo (FPoint); + void scrollTo (int, int); + void scrollBy (int, int); virtual void draw(); // Event handlers @@ -105,6 +113,10 @@ class FScrollView : public FWidget void calculateScrollbarPos(); void setHorizontalScrollBarVisibility(); void setVerticalScrollBarVisibility(); + void redrawHBar(); + void redrawVBar(); + void drawHBar(); + void drawVBar(); // Callback methods void cb_VBarChange (FWidget*, void*); @@ -130,19 +142,28 @@ inline const char* FScrollView::getClassName() const { return "FScrollView"; } //---------------------------------------------------------------------- -inline int FScrollView::getScrollWidth() +inline int FScrollView::getScrollWidth() const { return scroll_size.getWidth(); } //---------------------------------------------------------------------- -inline int FScrollView::getScrollHeight() +inline int FScrollView::getScrollHeight() const { return scroll_size.getHeight(); } //---------------------------------------------------------------------- -inline void FScrollView::setScrollOffset (FPoint pos) -{ scroll_offset = pos; } +inline const FPoint FScrollView::getScrollPos() const +{ return scroll_offset; } //---------------------------------------------------------------------- -inline void FScrollView::setScrollOffset (int x, int y) -{ scroll_offset.setPoint (x, y); } +inline int FScrollView::getScrollX() const +{ return scroll_offset.getX(); } + +//---------------------------------------------------------------------- +inline int FScrollView::getScrollY() const +{ return scroll_offset.getY(); } + +//---------------------------------------------------------------------- +inline void FScrollView::scrollTo (FPoint pos) +{ scrollTo(pos.getX(), pos.getY()); } + #endif // _FSCROLLVIEW_H diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 5d438fc0..d2967817 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -36,6 +36,7 @@ FVTerm::char_data FVTerm::next_attribute; FVTerm::FVTerm (FVTerm* parent) : FObject(parent) , print_area(0) + , child_print_area(0) , vwin(0) { terminal_update_complete = false; @@ -631,7 +632,7 @@ FVTerm::term_area* FVTerm::getPrintArea() FVTerm* obj = static_cast(this); FVTerm* p_obj = static_cast(obj->getParent()); - while ( ! obj->vwin && p_obj ) + while ( ! obj->vwin && ! obj->child_print_area && p_obj ) { obj = p_obj; p_obj = static_cast(p_obj->getParent()); @@ -642,6 +643,11 @@ FVTerm::term_area* FVTerm::getPrintArea() print_area = obj->vwin; return print_area; } + else if ( obj->child_print_area ) + { + print_area = obj->child_print_area; + return print_area; + } } return vdesktop; diff --git a/src/fvterm.h b/src/fvterm.h index bcda4242..48a972e2 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -302,6 +302,7 @@ class FVTerm : public FObject, public FTerm static term_area* vdesktop; // virtual desktop static term_area* active_area; // active area term_area* print_area; // print area for this object + term_area* child_print_area; // print area for children term_area* vwin; // virtual window private: