Avoid scroll bar overshooting

This commit is contained in:
Markus Gans 2018-02-18 21:50:24 +01:00
parent 0f16b51e04
commit 69956ce76f
3 changed files with 112 additions and 59 deletions

View File

@ -1,3 +1,7 @@
2017-02-18 Markus Gans <guru.mail@muenster.de>
* Avoid scroll bar overshooting
* Refactoring FListView::onMouseMove
2017-02-17 Markus Gans <guru.mail@muenster.de> 2017-02-17 Markus Gans <guru.mail@muenster.de>
* Generalize scroll functions in FTextView * Generalize scroll functions in FTextView
* Refactoring FButtonGroup::drawLabel * Refactoring FButtonGroup::drawLabel

View File

@ -132,7 +132,10 @@ class FScrollbar : public FWidget
sType getClickedScrollType (int, int); sType getClickedScrollType (int, int);
sType getVerticalClickedScrollType (int); sType getVerticalClickedScrollType (int);
sType getHorizontalClickedScrollType (int); sType getHorizontalClickedScrollType (int);
void processMiddleButton (int, int); int getSliderClickPos (int, int);
void jumpToClickPos (int, int);
void jumpToClickPos (int);
void avoidScrollOvershoot();
void processScroll(); void processScroll();
// Data Members // Data Members

View File

@ -385,7 +385,7 @@ void FScrollbar::onMouseDown (FMouseEvent* ev)
if ( ev->getButton() == fc::MiddleButton ) if ( ev->getButton() == fc::MiddleButton )
{ {
processMiddleButton (mouse_x, mouse_y); jumpToClickPos (mouse_x, mouse_y);
return; return;
} }
@ -394,27 +394,7 @@ void FScrollbar::onMouseDown (FMouseEvent* ev)
if ( scroll_type == FScrollbar::noScroll ) if ( scroll_type == FScrollbar::noScroll )
{ {
if ( bar_orientation == fc::vertical ) slider_click_pos = getSliderClickPos (mouse_x, mouse_y);
{
if ( mouse_y > slider_pos + 1
&& mouse_y <= slider_pos + slider_length + 1 )
slider_click_pos = mouse_y; // on slider
}
else // horizontal
{
if ( isNewFont() )
{
if ( mouse_x > slider_pos + 2
&& mouse_x <= slider_pos + slider_length + 2 )
slider_click_pos = mouse_x; // on slider
}
else
{
if ( mouse_x > slider_pos + 1
&& mouse_x <= slider_pos + slider_length + 1 )
slider_click_pos = mouse_x; // on slider
}
}
if ( slider_click_pos > 0 ) if ( slider_click_pos > 0 )
scroll_type = FScrollbar::scrollJump; scroll_type = FScrollbar::scrollJump;
@ -473,7 +453,7 @@ void FScrollbar::onMouseMove (FMouseEvent* ev)
if ( ev->getButton() == fc::MiddleButton ) if ( ev->getButton() == fc::MiddleButton )
{ {
processMiddleButton (mouse_x, mouse_y); jumpToClickPos (mouse_x, mouse_y);
return; return;
} }
@ -556,16 +536,24 @@ void FScrollbar::onTimer (FTimerEvent*)
addTimer(repeat_time); addTimer(repeat_time);
} }
// Timer stop condition
if ( ( scroll_type == FScrollbar::scrollPageBackward if ( ( scroll_type == FScrollbar::scrollPageBackward
&& slider_pos < slider_click_stop_pos ) && slider_pos == slider_click_stop_pos )
|| ( scroll_type == FScrollbar::scrollPageForward || ( scroll_type == FScrollbar::scrollPageForward
&& slider_pos + slider_length > slider_click_stop_pos ) ) && slider_pos == slider_click_stop_pos ) )
{ {
// Scroll to the end int max_slider_pos = bar_length - slider_length;
if ( scroll_type == FScrollbar::scrollPageForward
&& slider_pos + slider_length > slider_click_stop_pos ) if ( scroll_type == FScrollbar::scrollPageBackward
&& slider_pos == 0 )
{ {
setValue(max); jumpToClickPos(0); // Scroll to the start
processScroll();
}
else if ( scroll_type == FScrollbar::scrollPageForward
&& slider_pos == max_slider_pos )
{
jumpToClickPos (max_slider_pos); // Scroll to the end
processScroll(); processScroll();
} }
@ -732,46 +720,104 @@ FScrollbar::sType FScrollbar::getHorizontalClickedScrollType (int x)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::processMiddleButton (int x, int y) int FScrollbar::getSliderClickPos (int mouse_x, int mouse_y)
{ {
int new_val; // Get the clicked position on the slider
if ( bar_orientation == fc::vertical ) if ( bar_orientation == fc::vertical )
{
if ( mouse_y > slider_pos + 1
&& mouse_y <= slider_pos + slider_length + 1 )
return mouse_y; // on slider
}
else // horizontal bar orientation
{
if ( isNewFont() )
{ {
if ( y >1 && y < getHeight() ) if ( mouse_x > slider_pos + 2
{ && mouse_x <= slider_pos + slider_length + 2 )
new_val = int( round ( double(max - min) * (y - 2.0 - (slider_length/2)) return mouse_x; // on slider
/ double(bar_length - slider_length) ) );
}
else
return;
} }
else // horizontal else
{ {
int nf = isNewFont() ? 1 : 0; if ( mouse_x > slider_pos + 1
&& mouse_x <= slider_pos + slider_length + 1 )
return mouse_x; // on slider
}
}
if ( x > 1 + nf && x < getWidth() - nf ) return -1;
{
new_val = int( round ( double(max - min) * (x - 2.0 - nf - (slider_length/2))
/ double(bar_length - slider_length) ) );
}
else
return;
}
if ( new_val != val )
{
setValue(new_val);
drawBar();
updateTerminal();
scroll_type = FScrollbar::scrollJump;
processScroll();
}
} }
//----------------------------------------------------------------------
void FScrollbar::jumpToClickPos (int x, int y)
{
int new_val;
if ( bar_orientation == fc::vertical )
{
if ( y >1 && y < getHeight() )
{
new_val = int( round ( double(max - min) * (y - 2.0 - (slider_length/2))
/ double(bar_length - slider_length) ) );
}
else
return;
}
else // horizontal
{
int nf = isNewFont() ? 1 : 0;
if ( x > 1 + nf && x < getWidth() - nf )
{
new_val = int( round ( double(max - min) * (x - 2.0 - nf - (slider_length/2))
/ double(bar_length - slider_length) ) );
}
else
return;
}
if ( new_val != val )
{
setValue(new_val);
drawBar();
updateTerminal();
scroll_type = FScrollbar::scrollJump;
processScroll();
}
}
//----------------------------------------------------------------------
void FScrollbar::jumpToClickPos (int pos)
{
if ( bar_orientation == fc::vertical )
jumpToClickPos (0, pos + 2);
else
{
if ( isNewFont() )
jumpToClickPos (pos + 3, 0);
else
jumpToClickPos (pos + 2, 0);
}
}
//----------------------------------------------------------------------
void FScrollbar::avoidScrollOvershoot()
{
// Avoid overshoot
if ( ( scroll_type == FScrollbar::scrollPageBackward
&& slider_pos < slider_click_stop_pos )
|| ( scroll_type == FScrollbar::scrollPageForward
&& slider_pos > slider_click_stop_pos ) )
{
jumpToClickPos (slider_click_stop_pos);
delOwnTimer();
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::processScroll() void FScrollbar::processScroll()
{ {
emitCallback("change-value"); emitCallback("change-value");
avoidScrollOvershoot();
} }