From 9bd711dc0edd2ddd1d57a94c7c9a550c50653bc6 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Wed, 27 Dec 2017 23:51:32 +0100 Subject: [PATCH] Generalize scroll functions in FScrollView --- ChangeLog | 2 + include/final/fscrollbar.h | 4 +- include/final/fscrollview.h | 1 + src/flistbox.cpp | 4 +- src/fscrollbar.cpp | 297 ++++++++++++++++--------------- src/fscrollview.cpp | 346 ++++++++++-------------------------- 6 files changed, 251 insertions(+), 403 deletions(-) diff --git a/ChangeLog b/ChangeLog index b85cbec4..f899d67e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ 2017-12-27 Markus Gans + * Generalize scroll functions in FScrollView + * Refactoring FScrollbar::drawBar * Refactoring FLineEdit::onKeyPress * Refactoring FMenu::onKeyPress * Refactoring FDialog::onKeyPress diff --git a/include/final/fscrollbar.h b/include/final/fscrollbar.h index 0d2f365a..d9d0fd4e 100644 --- a/include/final/fscrollbar.h +++ b/include/final/fscrollbar.h @@ -107,7 +107,8 @@ class FScrollbar : public FWidget void resize(); void redraw(); void calculateSliderValues(); - void drawButtons(); + void drawVerticalBar(); + void drawHorizontalBar(); void drawBar(); // Event handlers @@ -127,6 +128,7 @@ class FScrollbar : public FWidget // Methods void init(); void draw(); + void drawButtons(); sType getClickedScrollType (int, int); void processMiddleButton (int, int); void processScroll(); diff --git a/include/final/fscrollview.h b/include/final/fscrollview.h index fc789b81..fee84ba0 100644 --- a/include/final/fscrollview.h +++ b/include/final/fscrollview.h @@ -179,6 +179,7 @@ class FScrollView : public FWidget int nf_offset; bool border; bool use_own_print_area; + bool update_scrollbar; fc::scrollBarMode vMode; // fc:Auto, fc::Hidden or fc::Scroll fc::scrollBarMode hMode; }; diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 80f280a9..cdac0ee1 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -195,7 +195,7 @@ void FListBox::setGeometry (int x, int y, int w, int h, bool adjust) if ( isNewFont() ) { vbar->setGeometry (getWidth(), 2, 2, getHeight() - 2); - hbar->setGeometry (1, getHeight(), getWidth() - 2, 1); + hbar->setGeometry (1, getHeight(), getWidth() - 2 - nf_offset, 1); } else { @@ -1041,7 +1041,7 @@ void FListBox::adjustSize() hbar->setMaximum (max_line_width - getClientWidth() + 2); hbar->setPageSize (max_line_width, getClientWidth() - 2); hbar->setY (getHeight()); - hbar->setWidth (getClientWidth(), false); + hbar->setWidth (getClientWidth() + nf_offset, false); hbar->resize(); if ( element_count <= getClientHeight() ) diff --git a/src/fscrollbar.cpp b/src/fscrollbar.cpp index 0b0fc50e..615a0794 100644 --- a/src/fscrollbar.cpp +++ b/src/fscrollbar.cpp @@ -106,7 +106,7 @@ void FScrollbar::setMaximum (int maximum) } //---------------------------------------------------------------------- -void FScrollbar::setRange(int minimum, int maximum) +void FScrollbar::setRange (int minimum, int maximum) { min = minimum; max = maximum; @@ -166,6 +166,7 @@ void FScrollbar::setOrientation (int o) if ( isNewFont() ) nf = 2; } + slider_length = bar_length = length - nf - 2; bar_orientation = o; } @@ -249,165 +250,122 @@ void FScrollbar::calculateSliderValues() } //---------------------------------------------------------------------- -void FScrollbar::drawButtons() +void FScrollbar::drawVerticalBar() { - setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg); + int z; + 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 (' '); + } + + if ( isMonochron() ) + setReverse(false); +} + +//---------------------------------------------------------------------- +void FScrollbar::drawHorizontalBar() +{ + int z; + setColor (wc.scrollbar_fg, wc.scrollbar_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); - } - } + setPrintPos (3, 1); else + setPrintPos (2, 1); + + for (; z < slider_pos; z++) { - setPrintPos (1,1); - - if ( isMonochron() ) - setReverse(true); - - if ( bar_orientation == fc::vertical ) - { - print (fc::BlackUpPointingTriangle); // ▲ - setPrintPos (1, length); - print (fc::BlackDownPointingTriangle); // ▼ - } - else // horizontal - { - print (fc::BlackLeftPointingPointer); // ◄ - setPrintPos (length, 1); - print (fc::BlackRightPointingPointer); // ► - } - - if ( isMonochron() ) - setReverse(false); + 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); + + for (z = 0; 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 ( isMonochron() ) + setReverse(false); } //---------------------------------------------------------------------- void FScrollbar::drawBar() { - int z; - if ( slider_pos == current_slider_pos || length < 3 ) return; 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 (' '); - } - } + drawVerticalBar(); else // horizontal - { - setColor (wc.scrollbar_fg, wc.scrollbar_bg); - z = 0; - - if ( isNewFont() ) - setPrintPos (3 + z, 1); - 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 (' '); - } - } + drawHorizontalBar(); current_slider_pos = slider_pos; - - if ( isMonochron() ) - setReverse(false); } //---------------------------------------------------------------------- @@ -431,7 +389,7 @@ void FScrollbar::onMouseDown (FMouseEvent* ev) return; } - // process LeftButton + // Process left button scroll_type = getClickedScrollType(mouse_x, mouse_y); if ( scroll_type == FScrollbar::noScroll ) @@ -519,7 +477,7 @@ void FScrollbar::onMouseMove (FMouseEvent* ev) return; } - // process LeftButton + // Process left button new_scroll_type = getClickedScrollType(mouse_x, mouse_y); if ( scroll_type == FScrollbar::scrollJump ) @@ -639,6 +597,57 @@ void FScrollbar::draw() drawBar(); } +//---------------------------------------------------------------------- +void FScrollbar::drawButtons() +{ + 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 ) + { + print (fc::BlackUpPointingTriangle); // ▲ + setPrintPos (1, length); + print (fc::BlackDownPointingTriangle); // ▼ + } + else // horizontal + { + print (fc::BlackLeftPointingPointer); // ◄ + setPrintPos (length, 1); + print (fc::BlackRightPointingPointer); // ► + } + + if ( isMonochron() ) + setReverse(false); + } +} + //---------------------------------------------------------------------- FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y) { diff --git a/src/fscrollview.cpp b/src/fscrollview.cpp index 551cbcfa..625f6b51 100644 --- a/src/fscrollview.cpp +++ b/src/fscrollview.cpp @@ -41,6 +41,7 @@ FScrollView::FScrollView (FWidget* parent) , nf_offset(0) , border(true) , use_own_print_area(false) + , update_scrollbar(true) , vMode(fc::Auto) , hMode(fc::Auto) { @@ -330,10 +331,14 @@ void FScrollView::scrollTo (int x, int y) { short& xoffset = viewport_geometry.x1_ref(); short& yoffset = viewport_geometry.y1_ref(); + short xoffset_before = xoffset; + short yoffset_before = yoffset; short xoffset_end = short(getScrollWidth() - getViewportWidth()); short yoffset_end = short(getScrollHeight() - getViewportHeight()); int save_width = viewport_geometry.getWidth(); int save_height = viewport_geometry.getHeight(); + bool changeX = false; + bool changeY = false; x--; y--; @@ -355,25 +360,48 @@ void FScrollView::scrollTo (int x, int y) if ( xoffset > xoffset_end ) xoffset = xoffset_end; - viewport_geometry.setWidth(save_width); - viewport_geometry.setHeight(save_height); + changeX = bool(xoffset_before != xoffset); + changeY = bool(yoffset_before != yoffset); + + if ( ! isVisible() || ! viewport || ! (changeX || changeY) ) + return; + + if ( changeX ) + { + viewport_geometry.setWidth(save_width); + setTopPadding (1 - yoffset); + setBottomPadding (1 - (yoffset_end - yoffset)); + + if ( update_scrollbar ) + { + hbar->setValue (xoffset); + drawHBar(); + } + } + + if ( changeY ) + { + viewport_geometry.setHeight(save_height); + setLeftPadding (1 - xoffset); + setRightPadding (1 - (xoffset_end - xoffset) + nf_offset); + + if ( update_scrollbar ) + { + vbar->setValue (yoffset); + drawVBar(); + } + } + viewport->has_changes = true; - setTopPadding (1 - yoffset); - setLeftPadding (1 - xoffset); - setBottomPadding (1 - (yoffset_end - yoffset)); - setRightPadding (1 - (xoffset_end - xoffset) + nf_offset); copy2area(); - hbar->setValue (xoffset); - vbar->setValue (yoffset); - drawHBar(); - drawVBar(); updateTerminal(); + } //---------------------------------------------------------------------- void FScrollView::scrollBy (int dx, int dy) { - scrollTo (getScrollX() + dx, getScrollY() + dy); + scrollTo (1 + getScrollX() + dx, 1 + getScrollY() + dy); } //---------------------------------------------------------------------- @@ -409,161 +437,73 @@ void FScrollView::draw() //---------------------------------------------------------------------- void FScrollView::onKeyPress (FKeyEvent* ev) { - int key = ev->key(); - short& xoffset = viewport_geometry.x1_ref(); - short& yoffset = viewport_geometry.y1_ref(); - short xoffset_before = xoffset; - short yoffset_before = yoffset; - short xoffset_end = short(getScrollWidth() - getViewportWidth()); - short yoffset_end = short(getScrollHeight() - getViewportHeight()); - int save_width = viewport_geometry.getWidth(); - int save_height = viewport_geometry.getHeight(); + short yoffset_end = short(getScrollHeight() - getViewportHeight()); - switch ( key ) + switch ( ev->key() ) { case fc::Fkey_up: - if ( yoffset > 0 ) - yoffset--; - + scrollBy (0, -1); ev->accept(); break; case fc::Fkey_down: - if ( yoffset < yoffset_end ) - yoffset++; - + scrollBy (0, 1); ev->accept(); break; case fc::Fkey_left: - if ( xoffset > 0 ) - xoffset--; - + scrollBy (-1, 0); ev->accept(); break; case fc::Fkey_right: - if ( xoffset < xoffset_end ) - xoffset++; - + scrollBy (1, 0); ev->accept(); break; case fc::Fkey_ppage: - yoffset -= getViewportHeight(); - - if ( yoffset < 0 ) - yoffset = 0; - + scrollBy (0, -getViewportHeight()); ev->accept(); break; case fc::Fkey_npage: - yoffset += getViewportHeight(); - - if ( yoffset > yoffset_end ) - yoffset = yoffset_end; - + scrollBy (0, getViewportHeight()); ev->accept(); break; case fc::Fkey_home: - yoffset = 0; + scrollToY (1); ev->accept(); break; case fc::Fkey_end: - yoffset = yoffset_end; + scrollToY (1 + yoffset_end); ev->accept(); break; default: break; } - - if ( ev->isAccepted() ) - { - bool hasChanges = false; - - if ( isVisible() && viewport - && (xoffset_before != xoffset || yoffset_before != yoffset) ) - { - viewport_geometry.setWidth(save_width); - viewport_geometry.setHeight(save_height); - viewport->has_changes = true; - setTopPadding (1 - yoffset); - setLeftPadding (1 - xoffset); - setBottomPadding (1 - (yoffset_end - yoffset)); - setRightPadding (1 - (xoffset_end - xoffset) + nf_offset); - copy2area(); - hasChanges = true; - vbar->setValue (yoffset); - hbar->setValue (xoffset); - drawVBar(); - drawHBar(); - } - - if ( hasChanges ) - updateTerminal(); - } } //---------------------------------------------------------------------- void FScrollView::onWheel (FWheelEvent* ev) { - bool hasChanges = false; - short& yoffset = viewport_geometry.y1_ref(); - short yoffset_before = yoffset; - short yoffset_end = short(getScrollHeight() - getViewportHeight()); - int save_height = viewport_geometry.getHeight(); - int wheel = ev->getWheel(); + short distance = 4; - switch ( wheel ) + switch ( ev->getWheel() ) { case fc::WheelUp: - if ( yoffset == 0 ) - break; - - yoffset -= 4; - - if ( yoffset < 0 ) - yoffset = 0; - + scrollBy (0, -distance); break; case fc::WheelDown: - { - if ( yoffset_end < 0 ) - yoffset_end = 0; - - if ( yoffset == yoffset_end ) - break; - - yoffset += 4; - - if ( yoffset > yoffset_end ) - yoffset = yoffset_end; - } + scrollBy (0, distance); break; default: break; } - - if ( isVisible() && viewport && yoffset_before != yoffset ) - { - viewport_geometry.setHeight(save_height); - viewport->has_changes = true; - setTopPadding (1 - yoffset); - setBottomPadding (1 - (yoffset_end - yoffset)); - copy2area(); - hasChanges = true; - vbar->setValue (yoffset); - drawVBar(); - } - - if ( hasChanges ) - updateTerminal(); } //---------------------------------------------------------------------- @@ -942,14 +882,19 @@ void FScrollView::setViewportCursor() //---------------------------------------------------------------------- void FScrollView::cb_VBarChange (FWidget*, data_ptr) { - FScrollbar::sType scrollType; - bool hasChanges = false; - short distance = 1; - short& yoffset = viewport_geometry.y1_ref(); - short yoffset_before = yoffset; - short yoffset_end = short(getScrollHeight() - getViewportHeight()); - int save_height = viewport_geometry.getHeight(); - scrollType = vbar->getScrollType(); + FScrollbar::sType scrollType = vbar->getScrollType(); + short distance = 1; + short wheel_distance = 4; + + if ( scrollType >= FScrollbar::scrollStepBackward + && scrollType <= FScrollbar::scrollWheelDown ) + { + update_scrollbar = true; + } + else + { + update_scrollbar = false; + } switch ( scrollType ) { @@ -960,101 +905,48 @@ void FScrollView::cb_VBarChange (FWidget*, data_ptr) distance = short(getViewportHeight()); // fall through case FScrollbar::scrollStepBackward: - yoffset -= distance; - - if ( yoffset < 0 ) - yoffset = 0; - + scrollBy (0, -distance); break; case FScrollbar::scrollPageForward: distance = short(getViewportHeight()); // fall through case FScrollbar::scrollStepForward: - yoffset += distance; - - if ( yoffset > yoffset_end ) - yoffset = yoffset_end; - + scrollBy (0, distance); break; case FScrollbar::scrollJump: - { - short val = short(vbar->getValue()); - - if ( yoffset == val ) - break; - - yoffset = val; - - if ( yoffset > yoffset_end ) - yoffset = yoffset_end; - - if ( yoffset < 0 ) - yoffset = 0; - + scrollToY (1 + short(vbar->getValue())); break; - } case FScrollbar::scrollWheelUp: - if ( yoffset == 0 ) - break; - - yoffset -= 4; - - if ( yoffset < 0 ) - yoffset = 0; - + scrollBy (0, -wheel_distance); break; case FScrollbar::scrollWheelDown: - if ( yoffset_end < 0 ) - yoffset_end = 0; - - if ( yoffset == yoffset_end ) - break; - - yoffset += 4; - - if ( yoffset > yoffset_end ) - yoffset = yoffset_end; - + scrollBy (0, wheel_distance); break; } - if ( isVisible() && viewport && yoffset_before != yoffset ) - { - viewport_geometry.setHeight(save_height); - viewport->has_changes = true; - setTopPadding (1 - yoffset); - setBottomPadding (1 - (yoffset_end - yoffset)); - copy2area(); - hasChanges = true; - } - - if ( scrollType >= FScrollbar::scrollStepBackward - && scrollType <= FScrollbar::scrollWheelDown - && hasChanges ) - { - vbar->setValue (yoffset); - drawVBar(); - } - - if ( hasChanges ) - updateTerminal(); + update_scrollbar = true; } //---------------------------------------------------------------------- void FScrollView::cb_HBarChange (FWidget*, data_ptr) { - FScrollbar::sType scrollType; - bool hasChanges = false; + FScrollbar::sType scrollType = hbar->getScrollType(); short distance = 1; - short& xoffset = viewport_geometry.x1_ref(); - short xoffset_before = xoffset; - short xoffset_end = short(getScrollWidth() - getViewportWidth()); - int save_width = viewport_geometry.getWidth(); - scrollType = hbar->getScrollType(); + short wheel_distance = 4; + + if ( scrollType >= FScrollbar::scrollStepBackward + && scrollType <= FScrollbar::scrollWheelDown ) + { + update_scrollbar = true; + } + else + { + update_scrollbar = false; + } switch ( scrollType ) { @@ -1065,88 +957,30 @@ void FScrollView::cb_HBarChange (FWidget*, data_ptr) distance = short(getViewportWidth()); // fall through case FScrollbar::scrollStepBackward: - xoffset -= distance; - - if ( xoffset < 0 ) - xoffset = 0; - + scrollBy (-distance, 0); break; case FScrollbar::scrollPageForward: distance = short(getViewportWidth()); // fall through case FScrollbar::scrollStepForward: - xoffset += distance; - - if ( xoffset > xoffset_end ) - xoffset = xoffset_end; - - if ( xoffset < 0 ) - xoffset = 0; - + scrollBy (distance, 0); break; case FScrollbar::scrollJump: - { - short val = short(hbar->getValue()); - - if ( xoffset == val ) - break; - - xoffset = val; - - if ( xoffset > xoffset_end ) - xoffset = xoffset_end; - - if ( xoffset < 0 ) - xoffset = 0; - + scrollToX (1 + short(hbar->getValue())); break; - } case FScrollbar::scrollWheelUp: - if ( xoffset == 0 ) - break; - - xoffset -= 4; - - if ( xoffset < 0 ) - xoffset = 0; - + scrollBy (-wheel_distance, 0); break; case FScrollbar::scrollWheelDown: - if ( xoffset == xoffset_end ) - break; - - xoffset += 4; - - if ( xoffset > xoffset_end ) - xoffset = xoffset_end; - + scrollBy (wheel_distance, 0); break; } - if ( isVisible() && viewport && xoffset_before != xoffset ) - { - viewport_geometry.setWidth(save_width); - viewport->has_changes = true; - setLeftPadding (1 - xoffset); - setRightPadding (1 - (xoffset_end - xoffset) + nf_offset); - copy2area(); - hasChanges = true; - } - - if ( scrollType >= FScrollbar::scrollStepBackward - && scrollType <= FScrollbar::scrollWheelDown - && hasChanges ) - { - hbar->setValue (xoffset); - drawHBar(); - } - - if ( hasChanges ) - updateTerminal(); + update_scrollbar = true; } //----------------------------------------------------------------------