Add FScrollView arrow keys support

This commit is contained in:
Markus Gans 2017-01-03 19:02:04 +01:00
parent 87ca58b898
commit 99ff28cbbe
3 changed files with 139 additions and 50 deletions

View File

@ -1,5 +1,6 @@
2017-01-03 Markus Gans <guru.mail@muenster.de> 2017-01-03 Markus Gans <guru.mail@muenster.de>
* FScrollView now has on-demand scroll bars * FScrollView now has on-demand scroll bars
* Arrow keys support for FScrollView viewport scrolling
2017-01-02 Markus Gans <guru.mail@muenster.de> 2017-01-02 Markus Gans <guru.mail@muenster.de>
* The new FScrollView widget provides a scrollable viewport * The new FScrollView widget provides a scrollable viewport

View File

@ -255,11 +255,109 @@ void FScrollView::draw()
hbar->redraw(); hbar->redraw();
} }
//----------------------------------------------------------------------
void FScrollView::onKeyPress (FKeyEvent* ev)
{
int key = ev->key();
bool hasChanges = false;
short& xoffset = scroll_offset.x_ref();
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());
switch ( key )
{
case fc::Fkey_up:
if ( yoffset > 0 )
yoffset--;
ev->accept();
break;
case fc::Fkey_down:
if ( yoffset < yoffset_end )
yoffset++;
ev->accept();
break;
case fc::Fkey_left:
if ( xoffset > 0 )
xoffset--;
ev->accept();
break;
case fc::Fkey_right:
if ( xoffset < xoffset_end )
xoffset++;
ev->accept();
break;
case fc::Fkey_ppage:
yoffset -= getClientHeight();
if ( yoffset < 0 )
yoffset = 0;
ev->accept();
break;
case fc::Fkey_npage:
yoffset += getClientHeight();
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
ev->accept();
break;
case fc::Fkey_home:
yoffset = 0;
ev->accept();
break;
case fc::Fkey_end:
yoffset = yoffset_end;
ev->accept();
break;
default:
break;
}
if ( ev->isAccepted() )
{
if ( isVisible() && viewport
&& (xoffset_before != xoffset || yoffset_before != yoffset) )
{
viewport->has_changes = true;
copy2area();
hasChanges = true;
vbar->setValue (yoffset);
hbar->setValue (xoffset);
if ( vbar->isVisible() )
vbar->drawBar();
if ( hbar->isVisible() )
hbar->drawBar();
}
if ( hasChanges )
updateTerminal();
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::onWheel (FWheelEvent* ev) void FScrollView::onWheel (FWheelEvent* ev)
{ {
int yoffset = scroll_offset.getY(); bool hasChanges = false;
int yoffset_before = yoffset; short& yoffset = scroll_offset.y_ref();
short yoffset_before = yoffset;
int wheel = ev->getWheel(); int wheel = ev->getWheel();
switch ( wheel ) switch ( wheel )
@ -277,7 +375,7 @@ void FScrollView::onWheel (FWheelEvent* ev)
case fc::WheelDown: case fc::WheelDown:
{ {
int yoffset_end = getScrollHeight() - getClientHeight(); short yoffset_end = short(getScrollHeight() - getClientHeight());
if ( yoffset_end < 0 ) if ( yoffset_end < 0 )
yoffset_end = 0; yoffset_end = 0;
@ -296,21 +394,18 @@ void FScrollView::onWheel (FWheelEvent* ev)
break; break;
} }
scroll_offset.setY (yoffset); if ( isVisible() && viewport && yoffset_before != yoffset )
if ( isVisible() )
{ {
if ( viewport && yoffset_before != yoffset )
viewport->has_changes = true; viewport->has_changes = true;
copy2area(); copy2area();
} hasChanges = true;
vbar->setValue (yoffset); vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset ) if ( vbar->isVisible() )
vbar->drawBar(); vbar->drawBar();
}
if ( hasChanges )
updateTerminal(); updateTerminal();
} }
@ -514,10 +609,10 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
{ {
FScrollbar::sType scrollType; FScrollbar::sType scrollType;
bool hasChanges = false; bool hasChanges = false;
int distance = 1; short distance = 1;
int yoffset = scroll_offset.getY(); short& yoffset = scroll_offset.y_ref();
int yoffset_before = yoffset; short yoffset_before = yoffset;
int yoffset_end = getScrollHeight() - getClientHeight(); short yoffset_end = short(getScrollHeight() - getClientHeight());
scrollType = vbar->getScrollType(); scrollType = vbar->getScrollType();
switch ( scrollType ) switch ( scrollType )
@ -526,7 +621,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
break; break;
case FScrollbar::scrollPageBackward: case FScrollbar::scrollPageBackward:
distance = getClientHeight(); distance = short(getClientHeight());
// fall through // fall through
case FScrollbar::scrollStepBackward: case FScrollbar::scrollStepBackward:
yoffset -= distance; yoffset -= distance;
@ -537,7 +632,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
break; break;
case FScrollbar::scrollPageForward: case FScrollbar::scrollPageForward:
distance = getClientHeight(); distance = short(getClientHeight());
// fall through // fall through
case FScrollbar::scrollStepForward: case FScrollbar::scrollStepForward:
yoffset += distance; yoffset += distance;
@ -549,7 +644,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
case FScrollbar::scrollJump: case FScrollbar::scrollJump:
{ {
int val = vbar->getValue(); short val = short(vbar->getValue());
if ( yoffset == val ) if ( yoffset == val )
break; break;
@ -591,24 +686,20 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
break; break;
} }
scroll_offset.setY (yoffset); if ( isVisible() && viewport && yoffset_before != yoffset )
if ( isVisible() )
{ {
if ( viewport && yoffset_before != yoffset )
viewport->has_changes = true; viewport->has_changes = true;
copy2area(); copy2area();
hasChanges = true; hasChanges = true;
} }
if ( scrollType >= FScrollbar::scrollStepBackward if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollWheelDown ) && scrollType <= FScrollbar::scrollWheelDown
&& hasChanges )
{ {
vbar->setValue (yoffset); vbar->setValue (yoffset);
hasChanges = true;
if ( vbar->isVisible() && yoffset_before != yoffset ) if ( vbar->isVisible() )
vbar->drawBar(); vbar->drawBar();
} }
@ -621,10 +712,10 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
{ {
FScrollbar::sType scrollType; FScrollbar::sType scrollType;
bool hasChanges = false; bool hasChanges = false;
int distance = 1; short distance = 1;
int xoffset = scroll_offset.getX(); short& xoffset = scroll_offset.x_ref();
int xoffset_before = xoffset; short xoffset_before = xoffset;
int xoffset_end = getScrollWidth() - getClientWidth(); short xoffset_end = short(getScrollWidth() - getClientWidth());
scrollType = hbar->getScrollType(); scrollType = hbar->getScrollType();
switch ( scrollType ) switch ( scrollType )
@ -633,7 +724,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
break; break;
case FScrollbar::scrollPageBackward: case FScrollbar::scrollPageBackward:
distance = getClientWidth(); distance = short(getClientWidth());
// fall through // fall through
case FScrollbar::scrollStepBackward: case FScrollbar::scrollStepBackward:
xoffset -= distance; xoffset -= distance;
@ -644,7 +735,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
break; break;
case FScrollbar::scrollPageForward: case FScrollbar::scrollPageForward:
distance = getClientWidth(); distance = short(getClientWidth());
// fall through // fall through
case FScrollbar::scrollStepForward: case FScrollbar::scrollStepForward:
xoffset += distance; xoffset += distance;
@ -659,7 +750,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
case FScrollbar::scrollJump: case FScrollbar::scrollJump:
{ {
int val = hbar->getValue(); short val = short(hbar->getValue());
if ( xoffset == val ) if ( xoffset == val )
break; break;
@ -698,24 +789,20 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
break; break;
} }
scroll_offset.setX (xoffset); if ( isVisible() && viewport && xoffset_before != xoffset )
if ( isVisible() )
{ {
if ( viewport && xoffset_before != xoffset )
viewport->has_changes = true; viewport->has_changes = true;
copy2area(); copy2area();
hasChanges = true; hasChanges = true;
} }
if ( scrollType >= FScrollbar::scrollStepBackward if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollWheelDown ) && scrollType <= FScrollbar::scrollWheelDown
&& hasChanges )
{ {
hbar->setValue (xoffset); hbar->setValue (xoffset);
hasChanges = true;
if ( hbar->isVisible() && xoffset_before != xoffset ) if ( hbar->isVisible() )
hbar->drawBar(); hbar->drawBar();
} }

View File

@ -79,6 +79,7 @@ class FScrollView : public FWidget
virtual void draw(); virtual void draw();
// Event handlers // Event handlers
void onKeyPress (FKeyEvent*);
void onWheel (FWheelEvent*); void onWheel (FWheelEvent*);
protected: protected: