From 51b1d18a8482eb31bb5afe919211235fa34c05e6 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 22 Jan 2017 23:04:40 +0100 Subject: [PATCH] FScrollView now allows client widget --- ChangeLog | 4 ++ README.md | 3 + build.sh | 2 +- doc/class-diagram.txt | 3 + src/fscrollview.cpp | 144 +++++++++++++++++++++++++----------------- src/fscrollview.h | 20 +++++- src/fvterm.cpp | 6 ++ src/fvterm.h | 17 +++++ src/fwidget.cpp | 102 ++++++++++++++++-------------- src/fwidget.h | 1 + src/fwindow.cpp | 27 ++++---- test/scrollview.cpp | 108 ++++++++++++++++++++++++++++++- test/ui.cpp | 42 ++++++------ 13 files changed, 335 insertions(+), 144 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e65163d..dacfb81a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-01-22 Markus Gans + * A FScrollView object can now have client widgets + on the scrolling area + 2017-01-15 Markus Gans * Virtual window gets a preprocessing handler. This allows a preprocessing method to be called before the vterm is updated. diff --git a/README.md b/README.md index ee4055ba..9e2c5099 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,9 @@ Class digramm : 1┌───────────┐ : : │ ┌──────────┐1 *┌──────────────┐1 : └---┤ FOptiMove │ : : ├────┤ FListBox ├-------┤ FListBoxItem ├-----┘ └───────────┘ : : │ └──────────┘ └──────────────┘ : + : : │ ┌─────────────┐ : + : : ├────┤ FScrollView │ : + : : │ └─────────────┘ : : : │ ┌────────────┐1 *┌────────────┐1 : : : │ ┌──┤ FStatusBar ├-----┤ FStatusKey ├-------┘ : : │ │ └────┬───────┘ └────────────┘ : diff --git a/build.sh b/build.sh index 269871a3..76097d52 100755 --- a/build.sh +++ b/build.sh @@ -8,7 +8,7 @@ case "$1" in ./configure --prefix="$PREFIX" CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -W -Wall -pedantic" ;; - "--/fulldebug"|"fulldebug") + "--fulldebug"|"fulldebug") ./configure --prefix="$PREFIX" CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -W -Wall -Weffc++ -pedantic -pedantic-errors -Wextra -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimport -Winit-self -Winvalid-pch -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -fstack-protector -Wstrict-aliasing -Wstrict-aliasing=3 -Wswitch -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wsign-promo -Woverloaded-virtual -Wstrict-null-sentinel -fext-numeric-literals -Wreorder -Wnoexcept -Wnarrowing -Wliteral-suffix -Wctor-dtor-privacy" ;; diff --git a/doc/class-diagram.txt b/doc/class-diagram.txt index b3803adb..209aedb2 100644 --- a/doc/class-diagram.txt +++ b/doc/class-diagram.txt @@ -63,6 +63,9 @@ : 1┌───────────┐ : : │ ┌──────────┐1 *┌──────────────┐1 : └---┤ FOptiMove │ : : ├────┤ FListBox ├-------┤ FListBoxItem ├-----┘ └───────────┘ : : │ └──────────┘ └──────────────┘ : + : : │ ┌─────────────┐ : + : : ├────┤ FScrollView │ : + : : │ └─────────────┘ : : : │ ┌────────────┐1 *┌────────────┐1 : : : │ ┌──┤ FStatusBar ├-----┤ FStatusKey ├-------┘ : : │ │ └────┬───────┘ └────────────┘ : diff --git a/src/fscrollview.cpp b/src/fscrollview.cpp index a89414ad..b6540d2d 100644 --- a/src/fscrollview.cpp +++ b/src/fscrollview.cpp @@ -39,8 +39,8 @@ FScrollView::~FScrollView() // destructor //---------------------------------------------------------------------- void FScrollView::setScrollWidth (int width) { - if ( width < getClientWidth() ) - width = getClientWidth(); + if ( width < getViewportWidth() ) + width = getViewportWidth(); if ( getScrollWidth() == width ) return; @@ -57,8 +57,8 @@ void FScrollView::setScrollWidth (int width) child_print_area = viewport; } - hbar->setMaximum (width - getClientWidth()); - hbar->setPageSize (width, getClientWidth()); + hbar->setMaximum (width - getViewportWidth()); + hbar->setPageSize (width, getViewportWidth()); hbar->calculateSliderValues(); setHorizontalScrollBarVisibility(); } @@ -66,8 +66,8 @@ void FScrollView::setScrollWidth (int width) //---------------------------------------------------------------------- void FScrollView::setScrollHeight (int height) { - if ( height < getClientHeight() ) - height = getClientHeight(); + if ( height < getViewportHeight() ) + height = getViewportHeight(); if ( getScrollHeight() == height ) return; @@ -84,8 +84,8 @@ void FScrollView::setScrollHeight (int height) child_print_area = viewport; } - vbar->setMaximum (height - getClientHeight()); - vbar->setPageSize (height, getClientHeight()); + vbar->setMaximum (height - getViewportHeight()); + vbar->setPageSize (height, getViewportHeight()); vbar->calculateSliderValues(); setVerticalScrollBarVisibility(); } @@ -93,11 +93,11 @@ void FScrollView::setScrollHeight (int height) //---------------------------------------------------------------------- void FScrollView::setScrollSize (int width, int height) { - if ( width < getClientWidth() ) - width = getClientWidth(); + if ( width < getViewportWidth() ) + width = getViewportWidth(); - if ( height < getClientHeight() ) - height = getClientHeight(); + if ( height < getViewportHeight() ) + height = getViewportHeight(); if ( getScrollWidth() == width && getScrollHeight() == height ) return; @@ -114,13 +114,18 @@ void FScrollView::setScrollSize (int width, int height) child_print_area = viewport; } - hbar->setMaximum (width - getClientWidth()); - hbar->setPageSize (width, getClientWidth()); + setTopPadding (1 - getScrollY()); + setLeftPadding (1 - getScrollX()); + setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - getScrollY())); + setRightPadding (1 - (getScrollWidth() - getViewportWidth() - getScrollX()) + nf_offset); + + hbar->setMaximum (width - getViewportWidth()); + hbar->setPageSize (width, getViewportWidth()); hbar->calculateSliderValues(); setHorizontalScrollBarVisibility(); - vbar->setMaximum (height - getClientHeight()); - vbar->setPageSize (height, getClientHeight()); + vbar->setMaximum (height - getViewportHeight()); + vbar->setPageSize (height, getViewportHeight()); vbar->calculateSliderValues(); setVerticalScrollBarVisibility(); } @@ -182,8 +187,8 @@ void FScrollView::setWidth (int w, bool adjust) FWidget::setWidth (w, adjust); calculateScrollbarPos(); - if ( getScrollWidth() < getClientWidth() ) - setScrollWidth (getClientWidth()); + if ( getScrollWidth() < getViewportWidth() ) + setScrollWidth (getViewportWidth()); } //---------------------------------------------------------------------- @@ -192,8 +197,8 @@ void FScrollView::setHeight (int h, bool adjust) FWidget::setHeight (h, adjust); calculateScrollbarPos(); - if ( getScrollHeight() < getClientHeight() ) - setScrollHeight (getClientHeight()); + if ( getScrollHeight() < getViewportHeight() ) + setScrollHeight (getViewportHeight()); } //---------------------------------------------------------------------- @@ -202,9 +207,9 @@ void FScrollView::setSize (int w, int h, bool adjust) FWidget::setSize (w, h, adjust); calculateScrollbarPos(); - if ( getScrollWidth() < getClientWidth() - || getScrollHeight() < getClientHeight() ) - setScrollSize (getClientWidth(), getClientHeight()); + if ( getScrollWidth() < getViewportWidth() + || getScrollHeight() < getViewportHeight() ) + setScrollSize (getViewportWidth(), getViewportHeight()); } //---------------------------------------------------------------------- @@ -215,10 +220,10 @@ void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust) , getTermY() + getTopPadding() - 1 ); calculateScrollbarPos(); - if ( getScrollWidth() < getClientWidth() - || getScrollHeight() < getClientHeight() ) + if ( getScrollWidth() < getViewportWidth() + || getScrollHeight() < getViewportHeight() ) { - setScrollSize (getClientWidth(), getClientHeight()); + setScrollSize (getViewportWidth(), getViewportHeight()); } else if ( ! adjust && viewport ) { @@ -257,13 +262,13 @@ void FScrollView::clearArea (int fillchar) //---------------------------------------------------------------------- void FScrollView::scrollToX (int x) { - scrollTo (x, scroll_offset.getY()); + scrollTo (x, scroll_offset.getY() + 1); } //---------------------------------------------------------------------- void FScrollView::scrollToY (int y) { - scrollTo (scroll_offset.getX(), y); + scrollTo (scroll_offset.getX() + 1, y); } //---------------------------------------------------------------------- @@ -271,8 +276,10 @@ 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()); + short xoffset_end = short(getScrollWidth() - getViewportWidth()); + short yoffset_end = short(getScrollHeight() - getViewportHeight()); + x--; + y--; if ( xoffset == short(x) && yoffset == short(y) ) return; @@ -297,6 +304,10 @@ void FScrollView::scrollTo (int x, int y) drawHBar(); drawVBar(); viewport->has_changes = true; + setTopPadding (1 - yoffset); + setLeftPadding (1 - xoffset); + setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - yoffset)); + setRightPadding (1 - (getScrollWidth() - getViewportWidth() - xoffset) + nf_offset); copy2area(); updateTerminal(); } @@ -337,8 +348,8 @@ void FScrollView::onKeyPress (FKeyEvent* ev) short& yoffset = scroll_offset.y_ref(); short xoffset_before = xoffset; short yoffset_before = yoffset; - short xoffset_end = short(getScrollWidth() - getClientWidth()); - short yoffset_end = short(getScrollHeight() - getClientHeight()); + short xoffset_end = short(getScrollWidth() - getViewportWidth()); + short yoffset_end = short(getScrollHeight() - getViewportHeight()); switch ( key ) { @@ -371,7 +382,7 @@ void FScrollView::onKeyPress (FKeyEvent* ev) break; case fc::Fkey_ppage: - yoffset -= getClientHeight(); + yoffset -= getViewportHeight(); if ( yoffset < 0 ) yoffset = 0; @@ -380,7 +391,7 @@ void FScrollView::onKeyPress (FKeyEvent* ev) break; case fc::Fkey_npage: - yoffset += getClientHeight(); + yoffset += getViewportHeight(); if ( yoffset > yoffset_end ) yoffset = yoffset_end; @@ -408,6 +419,10 @@ void FScrollView::onKeyPress (FKeyEvent* ev) && (xoffset_before != xoffset || yoffset_before != yoffset) ) { viewport->has_changes = true; + setTopPadding (1 - yoffset); + setLeftPadding (1 - xoffset); + setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - yoffset)); + setRightPadding (1 - (getScrollWidth() - getViewportWidth() - xoffset) + nf_offset); copy2area(); hasChanges = true; vbar->setValue (yoffset); @@ -444,7 +459,7 @@ void FScrollView::onWheel (FWheelEvent* ev) case fc::WheelDown: { - short yoffset_end = short(getScrollHeight() - getClientHeight()); + short yoffset_end = short(getScrollHeight() - getViewportHeight()); if ( yoffset_end < 0 ) yoffset_end = 0; @@ -466,6 +481,8 @@ void FScrollView::onWheel (FWheelEvent* ev) if ( isVisible() && viewport && yoffset_before != yoffset ) { viewport->has_changes = true; + setTopPadding (1 - yoffset); + setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - yoffset)); copy2area(); hasChanges = true; vbar->setValue (yoffset); @@ -512,22 +529,21 @@ void FScrollView::adjustSize() viewport->offset_left = scroll_size.getY(); } - hbar->setMaximum (getScrollWidth() - getClientWidth()); - hbar->setPageSize (getScrollWidth(), getClientWidth()); + hbar->setMaximum (getScrollWidth() - getViewportWidth()); + hbar->setPageSize (getScrollWidth(), getViewportWidth()); hbar->setY (height); hbar->setWidth (width - 2, false); hbar->setValue (xoffset); hbar->resize(); setHorizontalScrollBarVisibility(); - vbar->setMaximum (getScrollHeight() - getClientHeight()); - vbar->setPageSize (getScrollHeight(), getClientHeight()); + vbar->setMaximum (getScrollHeight() - getViewportHeight()); + vbar->setPageSize (getScrollHeight(), getViewportHeight()); vbar->setX (width); vbar->setHeight (height - 2, false); vbar->setValue (yoffset); vbar->resize(); setVerticalScrollBarVisibility(); - } //---------------------------------------------------------------------- @@ -539,10 +555,10 @@ void FScrollView::copy2area() char_data* vc; // viewport character char_data* ac; // area character - if ( ! print_area ) + if ( ! hasPrintArea() ) FVTerm::getPrintArea(); - if ( ! (print_area && viewport) ) + if ( ! (hasPrintArea() && viewport) ) return; if ( ! viewport->has_changes ) @@ -552,8 +568,8 @@ void FScrollView::copy2area() ay = getTermY() - print_area->offset_left; dx = scroll_offset.getX(); dy = scroll_offset.getY(); - y_end = getClientHeight(); - x_end = getClientWidth(); + y_end = getViewportHeight(); + x_end = getViewportWidth(); for (int y=0; y < y_end; y++) // line loop { @@ -605,13 +621,22 @@ void FScrollView::init() ); nf_offset = isNewFont() ? 1 : 0; - setTopPadding(1); - setLeftPadding(1); - setBottomPadding(1); - setRightPadding(1 + nf_offset); + setTopPadding (1 - getScrollY()); + setLeftPadding (1 - getScrollX()); + setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - getScrollY())); + setRightPadding (1 - (getScrollWidth() - getViewportWidth() - getScrollX()) + nf_offset); FPoint no_shadow(0,0); - scroll_size.setRect (1, 1, getClientWidth(), getClientHeight()); + int w = getViewportWidth(); + int h = getViewportHeight(); + + if ( w < 1 ) + w = 1; + + if ( h < 1 ) + h = 1; + + scroll_size.setRect (0, 0, w, h); createArea (scroll_size, no_shadow, viewport); setPreprocessingHandler ( @@ -639,7 +664,6 @@ void FScrollView::calculateScrollbarPos() hbar->setGeometry (2, height, width-2, 1); } - setRightPadding (1 + nf_offset); vbar->resize(); hbar->resize(); } @@ -650,7 +674,7 @@ void FScrollView::setHorizontalScrollBarVisibility() switch ( hMode ) { case fc::Auto: - if ( getScrollWidth() > getClientWidth() ) + if ( getScrollWidth() > getViewportWidth() ) hbar->setVisible(); else hbar->hide(); @@ -672,7 +696,7 @@ void FScrollView::setVerticalScrollBarVisibility() switch ( vMode ) { case fc::Auto: - if ( getScrollHeight() > getClientHeight() ) + if ( getScrollHeight() > getViewportHeight() ) vbar->setVisible(); else vbar->hide(); @@ -696,7 +720,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*) short distance = 1; short& yoffset = scroll_offset.y_ref(); short yoffset_before = yoffset; - short yoffset_end = short(getScrollHeight() - getClientHeight()); + short yoffset_end = short(getScrollHeight() - getViewportHeight()); scrollType = vbar->getScrollType(); switch ( scrollType ) @@ -705,7 +729,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*) break; case FScrollbar::scrollPageBackward: - distance = short(getClientHeight()); + distance = short(getViewportHeight()); // fall through case FScrollbar::scrollStepBackward: yoffset -= distance; @@ -716,7 +740,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*) break; case FScrollbar::scrollPageForward: - distance = short(getClientHeight()); + distance = short(getViewportHeight()); // fall through case FScrollbar::scrollStepForward: yoffset += distance; @@ -773,6 +797,8 @@ void FScrollView::cb_VBarChange (FWidget*, void*) if ( isVisible() && viewport && yoffset_before != yoffset ) { viewport->has_changes = true; + setTopPadding (1 - yoffset); + setBottomPadding (1 - (getScrollHeight() - getViewportHeight() - yoffset)); copy2area(); hasChanges = true; } @@ -797,7 +823,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*) short distance = 1; short& xoffset = scroll_offset.x_ref(); short xoffset_before = xoffset; - short xoffset_end = short(getScrollWidth() - getClientWidth()); + short xoffset_end = short(getScrollWidth() - getViewportWidth()); scrollType = hbar->getScrollType(); switch ( scrollType ) @@ -806,7 +832,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*) break; case FScrollbar::scrollPageBackward: - distance = short(getClientWidth()); + distance = short(getViewportWidth()); // fall through case FScrollbar::scrollStepBackward: xoffset -= distance; @@ -817,7 +843,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*) break; case FScrollbar::scrollPageForward: - distance = short(getClientWidth()); + distance = short(getViewportWidth()); // fall through case FScrollbar::scrollStepForward: xoffset += distance; @@ -874,6 +900,8 @@ void FScrollView::cb_HBarChange (FWidget*, void*) if ( isVisible() && viewport && xoffset_before != xoffset ) { viewport->has_changes = true; + setLeftPadding (1 - xoffset); + setRightPadding (1 - (getScrollWidth() - getViewportWidth() - xoffset) + nf_offset); copy2area(); hasChanges = true; } diff --git a/src/fscrollview.h b/src/fscrollview.h index 3efd145c..166af108 100644 --- a/src/fscrollview.h +++ b/src/fscrollview.h @@ -56,6 +56,8 @@ class FScrollView : public FWidget // Accessors const char* getClassName() const; + int getViewportWidth() const; + int getViewportHeight() const; int getScrollWidth() const; int getScrollHeight() const; const FPoint getScrollPos() const; @@ -63,9 +65,9 @@ class FScrollView : public FWidget int getScrollY() const; // Mutator - void setScrollWidth (int); - void setScrollHeight (int); - void setScrollSize (int, int); + virtual void setScrollWidth (int); + virtual void setScrollHeight (int); + virtual void setScrollSize (int, int); virtual void setX (int, bool = true); virtual void setY (int, bool = true); virtual void setPos (int, int, bool = true); @@ -102,6 +104,10 @@ class FScrollView : public FWidget void copy2area(); private: + // Constants + static const int vertical_border_spacing = 2; + static const int horizontal_border_spacing = 2; + // Disable copy constructor FScrollView (const FScrollView&); @@ -141,6 +147,14 @@ class FScrollView : public FWidget inline const char* FScrollView::getClassName() const { return "FScrollView"; } +//---------------------------------------------------------------------- +inline int FScrollView::getViewportWidth() const +{ return getWidth() - vertical_border_spacing - nf_offset; } + +//---------------------------------------------------------------------- +inline int FScrollView::getViewportHeight() const +{ return getHeight() - horizontal_border_spacing; } + //---------------------------------------------------------------------- inline int FScrollView::getScrollWidth() const { return scroll_size.getWidth(); } diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 858b320f..f376b594 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -733,6 +733,12 @@ void FVTerm::resizeArea ( int offset_top, int offset_left , int rsw, int bsh , term_area* area ) { + assert ( offset_top >= 0 ); + assert ( offset_left >= 0 ); + assert ( width > 0 ); + assert ( height > 0 ); + assert ( rsw >= 0 ); + assert ( bsh >= 0 ); int area_size; char_data default_char; line_changes unchanged; diff --git a/src/fvterm.h b/src/fvterm.h index 68f1696c..cabd5f04 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -242,6 +242,11 @@ class FVTerm : public FObject, public FTerm // Accessor virtual term_area* getPrintArea(); + // Inquiries + bool hasPrintArea() const; + bool hasChildPrintArea() const; + bool isVirtualWindow() const; + // Methods void createArea ( const FRect& , const FPoint& @@ -704,6 +709,18 @@ inline bool FVTerm::isInheritBackground() inline FVTerm& FVTerm::print() { return *this; } +//---------------------------------------------------------------------- +inline bool FVTerm::hasPrintArea() const +{ return print_area; } + +//---------------------------------------------------------------------- +inline bool FVTerm::hasChildPrintArea() const +{ return child_print_area; } + +//---------------------------------------------------------------------- +inline bool FVTerm::isVirtualWindow() const +{ return vwin; } + //---------------------------------------------------------------------- inline void FVTerm::setPrintArea (term_area* area) { print_area = area; } diff --git a/src/fwidget.cpp b/src/fwidget.cpp index c429a3ae..76e97acf 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -451,7 +451,7 @@ void FWidget::setTopPadding (int top, bool adjust) if ( padding.top == top ) return; - (top < 0) ? padding.top = 0 : padding.top = top; + padding.top = top; if ( adjust ) { @@ -472,7 +472,7 @@ void FWidget::setLeftPadding (int left, bool adjust) if ( padding.left == left ) return; - (left < 0) ? padding.left = 0 : padding.left = left; + padding.left = left; if ( adjust ) { @@ -493,7 +493,7 @@ void FWidget::setBottomPadding (int bottom, bool adjust) if ( padding.bottom == bottom ) return; - (bottom < 0) ? padding.bottom = 0 : padding.bottom = bottom; + padding.bottom = bottom; if ( adjust ) { @@ -514,7 +514,7 @@ void FWidget::setRightPadding (int right, bool adjust) if ( padding.right == right ) return; - (right < 0) ? padding.right = 0 : padding.right = right; + padding.right = right; if ( adjust ) { @@ -1697,48 +1697,9 @@ void FWidget::adjustSize() 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); - } + // Move and shrink in case of lack of space + if ( ! hasChildPrintArea() ) + insufficientSpaceAdjust(); client_offset.setCoordinates ( @@ -2202,6 +2163,55 @@ void FWidget::finish() } } +//---------------------------------------------------------------------- +inline void FWidget::insufficientSpaceAdjust() +{ + // Move and shrink widget if there is not enough space available + + if ( isWindowWidget() ) + return; + + // 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); +} + //---------------------------------------------------------------------- void FWidget::draw() { } diff --git a/src/fwidget.h b/src/fwidget.h index adfb26bc..42c96e0a 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -427,6 +427,7 @@ class FWidget : public FVTerm // Methods void init(); void finish(); + void insufficientSpaceAdjust(); void processDestroy(); virtual void draw(); static void setColorTheme(); diff --git a/src/fwindow.cpp b/src/fwindow.cpp index 661748f5..2a1f035f 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -232,7 +232,8 @@ bool FWindow::setAlwaysOnTop (bool on) bool FWindow::isWindowHidden() const { // returns the window hidden state - if ( vwin ) + + if ( isVirtualWindow() ) return ! vwin->visible; else return false; @@ -286,7 +287,7 @@ void FWindow::drawBorder() //---------------------------------------------------------------------- void FWindow::show() { - if ( vwin ) + if ( isVirtualWindow() ) vwin->visible = true; FWidget::show(); @@ -295,7 +296,7 @@ void FWindow::show() //---------------------------------------------------------------------- void FWindow::hide() { - if ( vwin ) + if ( isVirtualWindow() ) vwin->visible = false; FWidget::hide(); @@ -306,7 +307,7 @@ void FWindow::setX (int x, bool adjust) { FWidget::setX (x, adjust); - if ( vwin ) + if ( isVirtualWindow() ) vwin->offset_top = getTermX() - 1; } @@ -318,7 +319,7 @@ void FWindow::setY (int y, bool adjust) FWidget::setY (y, adjust); - if ( vwin ) + if ( isVirtualWindow() ) vwin->offset_left = getTermY() - 1; } @@ -330,7 +331,7 @@ void FWindow::setPos (int x, int y, bool adjust) FWidget::setPos (x, y, adjust); - if ( vwin ) + if ( isVirtualWindow() ) { vwin->offset_top = getTermX() - 1; vwin->offset_left = getTermY() - 1; @@ -343,7 +344,7 @@ void FWindow::setWidth (int w, bool adjust) int old_width = getWidth(); FWidget::setWidth (w, adjust); - if ( vwin && getWidth() != old_width ) + if ( isVirtualWindow() && getWidth() != old_width ) { FRect geometry = getTermGeometry(); geometry.move(-1,-1); @@ -357,7 +358,7 @@ void FWindow::setHeight (int h, bool adjust) int old_height = getHeight(); FWidget::setHeight (h, adjust); - if ( vwin && getHeight() != old_height ) + if ( isVirtualWindow() && getHeight() != old_height ) { FRect geometry = getTermGeometry(); geometry.move(-1,-1); @@ -372,7 +373,7 @@ void FWindow::setSize (int w, int h, bool adjust) int old_height = getHeight(); FWidget::setSize (w, h, adjust); - if ( vwin && (getWidth() != old_width || getHeight() != old_height) ) + if ( isVirtualWindow() && (getWidth() != old_width || getHeight() != old_height) ) { FRect geometry = getTermGeometry(); geometry.move(-1,-1); @@ -393,7 +394,7 @@ void FWindow::setGeometry (int x, int y, int w, int h, bool adjust) FWidget::setGeometry (x, y, w, h, adjust); - if ( ! vwin ) + if ( ! isVirtualWindow() ) return; if ( getWidth() != old_width || getHeight() != old_height ) @@ -417,7 +418,7 @@ void FWindow::move (int dx, int dy) { FWidget::move (dx,dy); - if ( vwin ) + if ( isVirtualWindow() ) { vwin->offset_top = getTermX() - 1; vwin->offset_left = getTermY() - 1; @@ -765,7 +766,7 @@ void FWindow::setShadowSize (int right, int bottom) new_right = getShadow().getX(); new_bottom = getShadow().getY(); - if ( vwin && (new_right != old_right || new_bottom != old_bottom) ) + if ( isVirtualWindow() && (new_right != old_right || new_bottom != old_bottom) ) { FRect geometry = getTermGeometry(); geometry.move(-1,-1); @@ -784,7 +785,7 @@ void FWindow::adjustSize() if ( zoomed ) setGeometry (1, 1, getMaxWidth(), getMaxHeight(), false); - else if ( vwin ) + else if ( isVirtualWindow() ) { if ( getX() != old_x ) vwin->offset_top = getTermX() - 1; diff --git a/test/scrollview.cpp b/test/scrollview.cpp index e94caa67..e850855b 100644 --- a/test/scrollview.cpp +++ b/test/scrollview.cpp @@ -23,21 +23,88 @@ class scrollview : public FScrollView // Destructor ~scrollview (); + // Mutator + void setScrollSize (int, int); + private: - // Methods + // Method void draw(); + + // Callback methods + void cb_go_east (FWidget*, void*); + void cb_go_south (FWidget*, void*); + void cb_go_west (FWidget*, void*); + void cb_go_north (FWidget*, void*); + + // Data Members + FButton* go_east; + FButton* go_south; + FButton* go_west; + FButton* go_north; }; #pragma pack(pop) //---------------------------------------------------------------------- scrollview::scrollview (FWidget* parent) : FScrollView(parent) -{ } +{ + go_east = new FButton(wchar_t(fc::BlackRightPointingPointer) , this); + go_east->setGeometry (1, 1, 5, 1); + + go_south = new FButton(wchar_t(fc::BlackDownPointingTriangle) , this); + go_south->setGeometry (getScrollWidth() - 5, 1, 5, 1); + + go_west = new FButton(wchar_t(fc::BlackLeftPointingPointer) , this); + go_west->setGeometry (getScrollWidth() - 5, getScrollHeight() - 2, 5, 1); + + go_north = new FButton(wchar_t(fc::BlackUpPointingTriangle) , this); + go_north->setGeometry (1, getScrollHeight() - 2, 5, 1); + + + if ( isCygwinTerminal() ) + { + go_south->setText ('v'); + go_north->setText ('^'); + } + + go_east->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &scrollview::cb_go_east) + ); + + go_south->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &scrollview::cb_go_south) + ); + + go_west->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &scrollview::cb_go_west) + ); + + go_north->addCallback + ( + "clicked", + _METHOD_CALLBACK (this, &scrollview::cb_go_north) + ); +} //---------------------------------------------------------------------- scrollview::~scrollview() { } +//---------------------------------------------------------------------- +void scrollview::setScrollSize (int width, int height) +{ + FScrollView::setScrollSize (width, height); + go_south->setPos (width - 5, 1); + go_west->setPos (width - 5, height - 1); + go_north->setPos (1, height - 1); +} + //---------------------------------------------------------------------- void scrollview::draw() { @@ -55,6 +122,41 @@ void scrollview::draw() FScrollView::draw(); } +//---------------------------------------------------------------------- +void scrollview::cb_go_east (FWidget*, void*) +{ + scrollToX (getScrollWidth() - getViewportWidth() + 1); + go_south->setFocus(); + go_east->redraw(); + go_south->redraw(); +} + +//---------------------------------------------------------------------- +void scrollview::cb_go_south (FWidget*, void*) +{ + scrollToY (getScrollHeight() - getViewportHeight() + 1); + go_west->setFocus(); + go_south->redraw(); + go_west->redraw(); +} + +//---------------------------------------------------------------------- +void scrollview::cb_go_west (FWidget*, void*) +{ + scrollToX (1); + go_north->setFocus(); + go_west->redraw(); + go_north->redraw();} + +//---------------------------------------------------------------------- +void scrollview::cb_go_north (FWidget*, void*) +{ + scrollToY (1); + go_east->setFocus(); + go_north->redraw(); + go_east->redraw(); +} + //---------------------------------------------------------------------- // class scrollviewdemo @@ -91,7 +193,7 @@ scrollviewdemo::scrollviewdemo (FWidget* parent) // The scrolling viewport widget scrollview* sview = new scrollview (this); sview->setGeometry(3, 2, 44, 12); - sview->setScrollSize(88, 24); + sview->setScrollSize(188, 124); // Quit button FButton* button = new FButton("&Quit", this); diff --git a/test/ui.cpp b/test/ui.cpp index a50b1701..1ff1aaf5 100644 --- a/test/ui.cpp +++ b/test/ui.cpp @@ -250,6 +250,9 @@ class MyDialog : public FDialog // Disable assignment operator (=) MyDialog& operator = (const MyDialog&); + // Method + void adjustSize(); + // Event handlers void onClose (FCloseEvent*); @@ -271,9 +274,7 @@ class MyDialog : public FDialog void cb_setInput (FWidget*, void*); void cb_exitApp (FWidget*, void*); - void adjustSize(); - - // Data Members + // Data Members FLineEdit* myLineEdit; FListBox* myList; FString clipboard; @@ -626,6 +627,24 @@ MyDialog::MyDialog (FWidget* parent) MyDialog::~MyDialog() { } +//---------------------------------------------------------------------- +void MyDialog::adjustSize() +{ + int h = getParentWidget()->getHeight() - 4; + setHeight (h, false); + int X = int((getParentWidget()->getWidth() - getWidth()) / 2); + + if ( X < 1 ) + X = 1; + + setX (X, false); + + if ( myList ) + myList->setHeight (getHeight() - 3, false); + + FDialog::adjustSize(); +} + //---------------------------------------------------------------------- void MyDialog::onClose (FCloseEvent* ev) { @@ -879,23 +898,6 @@ void MyDialog::cb_exitApp (FWidget*, void*) close(); } -//---------------------------------------------------------------------- -void MyDialog::adjustSize() -{ - int h = getParentWidget()->getHeight() - 4; - setHeight (h, false); - int X = int((getParentWidget()->getWidth() - getWidth()) / 2); - - if ( X < 1 ) - X = 1; - - setX (X, false); - - if ( myList ) - myList->setHeight (getHeight() - 3, false); - - FDialog::adjustSize(); -} //---------------------------------------------------------------------- // main part