Generalize scroll functions in FScrollView

This commit is contained in:
Markus Gans 2017-12-27 23:51:32 +01:00
parent b91f76710b
commit 9bd711dc0e
6 changed files with 251 additions and 403 deletions

View File

@ -1,4 +1,6 @@
2017-12-27 Markus Gans <guru.mail@muenster.de> 2017-12-27 Markus Gans <guru.mail@muenster.de>
* Generalize scroll functions in FScrollView
* Refactoring FScrollbar::drawBar
* Refactoring FLineEdit::onKeyPress * Refactoring FLineEdit::onKeyPress
* Refactoring FMenu::onKeyPress * Refactoring FMenu::onKeyPress
* Refactoring FDialog::onKeyPress * Refactoring FDialog::onKeyPress

View File

@ -107,7 +107,8 @@ class FScrollbar : public FWidget
void resize(); void resize();
void redraw(); void redraw();
void calculateSliderValues(); void calculateSliderValues();
void drawButtons(); void drawVerticalBar();
void drawHorizontalBar();
void drawBar(); void drawBar();
// Event handlers // Event handlers
@ -127,6 +128,7 @@ class FScrollbar : public FWidget
// Methods // Methods
void init(); void init();
void draw(); void draw();
void drawButtons();
sType getClickedScrollType (int, int); sType getClickedScrollType (int, int);
void processMiddleButton (int, int); void processMiddleButton (int, int);
void processScroll(); void processScroll();

View File

@ -179,6 +179,7 @@ class FScrollView : public FWidget
int nf_offset; int nf_offset;
bool border; bool border;
bool use_own_print_area; bool use_own_print_area;
bool update_scrollbar;
fc::scrollBarMode vMode; // fc:Auto, fc::Hidden or fc::Scroll fc::scrollBarMode vMode; // fc:Auto, fc::Hidden or fc::Scroll
fc::scrollBarMode hMode; fc::scrollBarMode hMode;
}; };

View File

@ -195,7 +195,7 @@ void FListBox::setGeometry (int x, int y, int w, int h, bool adjust)
if ( isNewFont() ) if ( isNewFont() )
{ {
vbar->setGeometry (getWidth(), 2, 2, getHeight() - 2); vbar->setGeometry (getWidth(), 2, 2, getHeight() - 2);
hbar->setGeometry (1, getHeight(), getWidth() - 2, 1); hbar->setGeometry (1, getHeight(), getWidth() - 2 - nf_offset, 1);
} }
else else
{ {
@ -1041,7 +1041,7 @@ void FListBox::adjustSize()
hbar->setMaximum (max_line_width - getClientWidth() + 2); hbar->setMaximum (max_line_width - getClientWidth() + 2);
hbar->setPageSize (max_line_width, getClientWidth() - 2); hbar->setPageSize (max_line_width, getClientWidth() - 2);
hbar->setY (getHeight()); hbar->setY (getHeight());
hbar->setWidth (getClientWidth(), false); hbar->setWidth (getClientWidth() + nf_offset, false);
hbar->resize(); hbar->resize();
if ( element_count <= getClientHeight() ) if ( element_count <= getClientHeight() )

View File

@ -166,6 +166,7 @@ void FScrollbar::setOrientation (int o)
if ( isNewFont() ) if ( isNewFont() )
nf = 2; nf = 2;
} }
slider_length = bar_length = length - nf - 2; slider_length = bar_length = length - nf - 2;
bar_orientation = o; bar_orientation = o;
} }
@ -249,66 +250,9 @@ void FScrollbar::calculateSliderValues()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::drawButtons() void FScrollbar::drawVerticalBar()
{
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);
}
}
//----------------------------------------------------------------------
void FScrollbar::drawBar()
{ {
int z; int z;
if ( slider_pos == current_slider_pos || length < 3 )
return;
if ( bar_orientation == fc::vertical )
{
setColor (wc.scrollbar_fg, wc.scrollbar_bg); setColor (wc.scrollbar_fg, wc.scrollbar_bg);
for (z = 1; z <= slider_pos; z++) for (z = 1; z <= slider_pos; z++)
@ -356,16 +300,21 @@ void FScrollbar::drawBar()
else else
print (' '); print (' ');
} }
if ( isMonochron() )
setReverse(false);
} }
else // horizontal
//----------------------------------------------------------------------
void FScrollbar::drawHorizontalBar()
{ {
int z;
setColor (wc.scrollbar_fg, wc.scrollbar_bg); setColor (wc.scrollbar_fg, wc.scrollbar_bg);
z = 0;
if ( isNewFont() ) if ( isNewFont() )
setPrintPos (3 + z, 1); setPrintPos (3, 1);
else else
setPrintPos (2 + z, 1); setPrintPos (2, 1);
for (; z < slider_pos; z++) for (; z < slider_pos; z++)
{ {
@ -382,9 +331,7 @@ void FScrollbar::drawBar()
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
z = 0; for (z = 0; z < slider_length; z++)
for (; z < slider_length; z++)
print (' '); print (' ');
if ( isMonochron() ) if ( isMonochron() )
@ -402,14 +349,25 @@ void FScrollbar::drawBar()
else else
print (' '); print (' ');
} }
}
current_slider_pos = slider_pos;
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
} }
//----------------------------------------------------------------------
void FScrollbar::drawBar()
{
if ( slider_pos == current_slider_pos || length < 3 )
return;
if ( bar_orientation == fc::vertical )
drawVerticalBar();
else // horizontal
drawHorizontalBar();
current_slider_pos = slider_pos;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::onMouseDown (FMouseEvent* ev) void FScrollbar::onMouseDown (FMouseEvent* ev)
{ {
@ -431,7 +389,7 @@ void FScrollbar::onMouseDown (FMouseEvent* ev)
return; return;
} }
// process LeftButton // Process left button
scroll_type = getClickedScrollType(mouse_x, mouse_y); scroll_type = getClickedScrollType(mouse_x, mouse_y);
if ( scroll_type == FScrollbar::noScroll ) if ( scroll_type == FScrollbar::noScroll )
@ -519,7 +477,7 @@ void FScrollbar::onMouseMove (FMouseEvent* ev)
return; return;
} }
// process LeftButton // Process left button
new_scroll_type = getClickedScrollType(mouse_x, mouse_y); new_scroll_type = getClickedScrollType(mouse_x, mouse_y);
if ( scroll_type == FScrollbar::scrollJump ) if ( scroll_type == FScrollbar::scrollJump )
@ -639,6 +597,57 @@ void FScrollbar::draw()
drawBar(); 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) FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y)
{ {

View File

@ -41,6 +41,7 @@ FScrollView::FScrollView (FWidget* parent)
, nf_offset(0) , nf_offset(0)
, border(true) , border(true)
, use_own_print_area(false) , use_own_print_area(false)
, update_scrollbar(true)
, vMode(fc::Auto) , vMode(fc::Auto)
, hMode(fc::Auto) , hMode(fc::Auto)
{ {
@ -330,10 +331,14 @@ void FScrollView::scrollTo (int x, int y)
{ {
short& xoffset = viewport_geometry.x1_ref(); short& xoffset = viewport_geometry.x1_ref();
short& yoffset = viewport_geometry.y1_ref(); short& yoffset = viewport_geometry.y1_ref();
short xoffset_before = xoffset;
short yoffset_before = yoffset;
short xoffset_end = short(getScrollWidth() - getViewportWidth()); short xoffset_end = short(getScrollWidth() - getViewportWidth());
short yoffset_end = short(getScrollHeight() - getViewportHeight()); short yoffset_end = short(getScrollHeight() - getViewportHeight());
int save_width = viewport_geometry.getWidth(); int save_width = viewport_geometry.getWidth();
int save_height = viewport_geometry.getHeight(); int save_height = viewport_geometry.getHeight();
bool changeX = false;
bool changeY = false;
x--; x--;
y--; y--;
@ -355,25 +360,48 @@ void FScrollView::scrollTo (int x, int y)
if ( xoffset > xoffset_end ) if ( xoffset > xoffset_end )
xoffset = xoffset_end; xoffset = xoffset_end;
changeX = bool(xoffset_before != xoffset);
changeY = bool(yoffset_before != yoffset);
if ( ! isVisible() || ! viewport || ! (changeX || changeY) )
return;
if ( changeX )
{
viewport_geometry.setWidth(save_width); viewport_geometry.setWidth(save_width);
viewport_geometry.setHeight(save_height);
viewport->has_changes = true;
setTopPadding (1 - yoffset); setTopPadding (1 - yoffset);
setLeftPadding (1 - xoffset);
setBottomPadding (1 - (yoffset_end - yoffset)); setBottomPadding (1 - (yoffset_end - yoffset));
setRightPadding (1 - (xoffset_end - xoffset) + nf_offset);
copy2area(); if ( update_scrollbar )
{
hbar->setValue (xoffset); hbar->setValue (xoffset);
vbar->setValue (yoffset);
drawHBar(); 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(); drawVBar();
}
}
viewport->has_changes = true;
copy2area();
updateTerminal(); updateTerminal();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::scrollBy (int dx, int dy) 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) 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()); short yoffset_end = short(getScrollHeight() - getViewportHeight());
int save_width = viewport_geometry.getWidth();
int save_height = viewport_geometry.getHeight();
switch ( key ) switch ( ev->key() )
{ {
case fc::Fkey_up: case fc::Fkey_up:
if ( yoffset > 0 ) scrollBy (0, -1);
yoffset--;
ev->accept(); ev->accept();
break; break;
case fc::Fkey_down: case fc::Fkey_down:
if ( yoffset < yoffset_end ) scrollBy (0, 1);
yoffset++;
ev->accept(); ev->accept();
break; break;
case fc::Fkey_left: case fc::Fkey_left:
if ( xoffset > 0 ) scrollBy (-1, 0);
xoffset--;
ev->accept(); ev->accept();
break; break;
case fc::Fkey_right: case fc::Fkey_right:
if ( xoffset < xoffset_end ) scrollBy (1, 0);
xoffset++;
ev->accept(); ev->accept();
break; break;
case fc::Fkey_ppage: case fc::Fkey_ppage:
yoffset -= getViewportHeight(); scrollBy (0, -getViewportHeight());
if ( yoffset < 0 )
yoffset = 0;
ev->accept(); ev->accept();
break; break;
case fc::Fkey_npage: case fc::Fkey_npage:
yoffset += getViewportHeight(); scrollBy (0, getViewportHeight());
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
ev->accept(); ev->accept();
break; break;
case fc::Fkey_home: case fc::Fkey_home:
yoffset = 0; scrollToY (1);
ev->accept(); ev->accept();
break; break;
case fc::Fkey_end: case fc::Fkey_end:
yoffset = yoffset_end; scrollToY (1 + yoffset_end);
ev->accept(); ev->accept();
break; break;
default: default:
break; 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) void FScrollView::onWheel (FWheelEvent* ev)
{ {
bool hasChanges = false; short distance = 4;
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();
switch ( wheel ) switch ( ev->getWheel() )
{ {
case fc::WheelUp: case fc::WheelUp:
if ( yoffset == 0 ) scrollBy (0, -distance);
break;
yoffset -= 4;
if ( yoffset < 0 )
yoffset = 0;
break; break;
case fc::WheelDown: case fc::WheelDown:
{ scrollBy (0, distance);
if ( yoffset_end < 0 )
yoffset_end = 0;
if ( yoffset == yoffset_end )
break;
yoffset += 4;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
}
break; break;
default: default:
break; 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) void FScrollView::cb_VBarChange (FWidget*, data_ptr)
{ {
FScrollbar::sType scrollType; FScrollbar::sType scrollType = vbar->getScrollType();
bool hasChanges = false;
short distance = 1; short distance = 1;
short& yoffset = viewport_geometry.y1_ref(); short wheel_distance = 4;
short yoffset_before = yoffset;
short yoffset_end = short(getScrollHeight() - getViewportHeight()); if ( scrollType >= FScrollbar::scrollStepBackward
int save_height = viewport_geometry.getHeight(); && scrollType <= FScrollbar::scrollWheelDown )
scrollType = vbar->getScrollType(); {
update_scrollbar = true;
}
else
{
update_scrollbar = false;
}
switch ( scrollType ) switch ( scrollType )
{ {
@ -960,101 +905,48 @@ void FScrollView::cb_VBarChange (FWidget*, data_ptr)
distance = short(getViewportHeight()); distance = short(getViewportHeight());
// fall through // fall through
case FScrollbar::scrollStepBackward: case FScrollbar::scrollStepBackward:
yoffset -= distance; scrollBy (0, -distance);
if ( yoffset < 0 )
yoffset = 0;
break; break;
case FScrollbar::scrollPageForward: case FScrollbar::scrollPageForward:
distance = short(getViewportHeight()); distance = short(getViewportHeight());
// fall through // fall through
case FScrollbar::scrollStepForward: case FScrollbar::scrollStepForward:
yoffset += distance; scrollBy (0, distance);
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
break; break;
case FScrollbar::scrollJump: case FScrollbar::scrollJump:
{ scrollToY (1 + short(vbar->getValue()));
short val = short(vbar->getValue());
if ( yoffset == val )
break; break;
yoffset = val;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
if ( yoffset < 0 )
yoffset = 0;
break;
}
case FScrollbar::scrollWheelUp: case FScrollbar::scrollWheelUp:
if ( yoffset == 0 ) scrollBy (0, -wheel_distance);
break;
yoffset -= 4;
if ( yoffset < 0 )
yoffset = 0;
break; break;
case FScrollbar::scrollWheelDown: case FScrollbar::scrollWheelDown:
if ( yoffset_end < 0 ) scrollBy (0, wheel_distance);
yoffset_end = 0;
if ( yoffset == yoffset_end )
break;
yoffset += 4;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
break; break;
} }
if ( isVisible() && viewport && yoffset_before != yoffset ) update_scrollbar = true;
{
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();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::cb_HBarChange (FWidget*, data_ptr) void FScrollView::cb_HBarChange (FWidget*, data_ptr)
{ {
FScrollbar::sType scrollType; FScrollbar::sType scrollType = hbar->getScrollType();
bool hasChanges = false;
short distance = 1; short distance = 1;
short& xoffset = viewport_geometry.x1_ref(); short wheel_distance = 4;
short xoffset_before = xoffset;
short xoffset_end = short(getScrollWidth() - getViewportWidth()); if ( scrollType >= FScrollbar::scrollStepBackward
int save_width = viewport_geometry.getWidth(); && scrollType <= FScrollbar::scrollWheelDown )
scrollType = hbar->getScrollType(); {
update_scrollbar = true;
}
else
{
update_scrollbar = false;
}
switch ( scrollType ) switch ( scrollType )
{ {
@ -1065,88 +957,30 @@ void FScrollView::cb_HBarChange (FWidget*, data_ptr)
distance = short(getViewportWidth()); distance = short(getViewportWidth());
// fall through // fall through
case FScrollbar::scrollStepBackward: case FScrollbar::scrollStepBackward:
xoffset -= distance; scrollBy (-distance, 0);
if ( xoffset < 0 )
xoffset = 0;
break; break;
case FScrollbar::scrollPageForward: case FScrollbar::scrollPageForward:
distance = short(getViewportWidth()); distance = short(getViewportWidth());
// fall through // fall through
case FScrollbar::scrollStepForward: case FScrollbar::scrollStepForward:
xoffset += distance; scrollBy (distance, 0);
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
if ( xoffset < 0 )
xoffset = 0;
break; break;
case FScrollbar::scrollJump: case FScrollbar::scrollJump:
{ scrollToX (1 + short(hbar->getValue()));
short val = short(hbar->getValue());
if ( xoffset == val )
break; break;
xoffset = val;
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
if ( xoffset < 0 )
xoffset = 0;
break;
}
case FScrollbar::scrollWheelUp: case FScrollbar::scrollWheelUp:
if ( xoffset == 0 ) scrollBy (-wheel_distance, 0);
break;
xoffset -= 4;
if ( xoffset < 0 )
xoffset = 0;
break; break;
case FScrollbar::scrollWheelDown: case FScrollbar::scrollWheelDown:
if ( xoffset == xoffset_end ) scrollBy (wheel_distance, 0);
break;
xoffset += 4;
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
break; break;
} }
if ( isVisible() && viewport && xoffset_before != xoffset ) update_scrollbar = true;
{
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();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------