FScrollView now has on-demand scroll bars

This commit is contained in:
Markus Gans 2017-01-03 05:19:44 +01:00
parent b2e4a59f54
commit 87ca58b898
5 changed files with 183 additions and 69 deletions

View File

@ -1,3 +1,6 @@
2017-01-03 Markus Gans <guru.mail@muenster.de>
* FScrollView now has on-demand scroll bars
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
to change the area of interest to change the area of interest

View File

@ -906,6 +906,14 @@ class fc
FocusDefiniteWidget = 0x03 FocusDefiniteWidget = 0x03
}; };
// scroll bar visibility mode
enum scrollBarMode
{
Auto = 0, // Shows a scroll bar when area is larger than viewport
Hidden = 1, // Never shows a scroll bar
Scroll = 2 // Always shows a scroll bar
};
// xterm cursor style // xterm cursor style
enum xtermCursorStyle enum xtermCursorStyle
{ {

View File

@ -18,7 +18,9 @@ FScrollView::FScrollView (FWidget* parent)
, vbar(0) , vbar(0)
, hbar(0) , hbar(0)
, nf_offset(0) , nf_offset(0)
, own_print_area(false) , use_own_print_area(false)
, vMode(fc::Auto)
, hMode(fc::Auto)
{ {
init(); init();
} }
@ -39,7 +41,7 @@ void FScrollView::setScrollWidth (int width)
if ( width < getClientWidth() ) if ( width < getClientWidth() )
width = getClientWidth(); width = getClientWidth();
if ( scroll_size.getWidth() == width ) if ( getScrollWidth() == width )
return; return;
if ( viewport ) if ( viewport )
@ -52,9 +54,7 @@ void FScrollView::setScrollWidth (int width)
hbar->setMaximum (width - getClientWidth()); hbar->setMaximum (width - getClientWidth());
hbar->setPageSize (width, getClientWidth()); hbar->setPageSize (width, getClientWidth());
hbar->calculateSliderValues(); hbar->calculateSliderValues();
setHorizontalScrollBarVisibility();
if ( ! hbar->isVisible() )
hbar->setVisible();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -63,7 +63,7 @@ void FScrollView::setScrollHeight (int height)
if ( height < getClientHeight() ) if ( height < getClientHeight() )
height = getClientHeight(); height = getClientHeight();
if ( scroll_size.getHeight() == height ) if ( getScrollHeight() == height )
return; return;
if ( viewport ) if ( viewport )
@ -76,9 +76,7 @@ void FScrollView::setScrollHeight (int height)
vbar->setMaximum (height - getClientHeight()); vbar->setMaximum (height - getClientHeight());
vbar->setPageSize (height, getClientHeight()); vbar->setPageSize (height, getClientHeight());
vbar->calculateSliderValues(); vbar->calculateSliderValues();
setVerticalScrollBarVisibility();
if ( ! vbar->isVisible() )
vbar->setVisible();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -90,8 +88,7 @@ void FScrollView::setScrollSize (int width, int height)
if ( height < getClientHeight() ) if ( height < getClientHeight() )
height = getClientHeight(); height = getClientHeight();
if ( scroll_size.getWidth() == width if ( getScrollWidth() == width && getScrollHeight() == height )
&& scroll_size.getHeight() == height )
return; return;
if ( viewport ) if ( viewport )
@ -104,30 +101,46 @@ void FScrollView::setScrollSize (int width, int height)
hbar->setMaximum (width - getClientWidth()); hbar->setMaximum (width - getClientWidth());
hbar->setPageSize (width, getClientWidth()); hbar->setPageSize (width, getClientWidth());
hbar->calculateSliderValues(); hbar->calculateSliderValues();
setHorizontalScrollBarVisibility();
if ( ! hbar->isVisible() )
hbar->setVisible();
vbar->setMaximum (height - getClientHeight()); vbar->setMaximum (height - getClientHeight());
vbar->setPageSize (height, getClientHeight()); vbar->setPageSize (height, getClientHeight());
vbar->calculateSliderValues(); vbar->calculateSliderValues();
setVerticalScrollBarVisibility();
if ( ! vbar->isVisible() )
vbar->setVisible();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::setX (int x, bool adjust) void FScrollView::setX (int x, bool adjust)
{ {
FWidget::setX (x, adjust); FWidget::setX (x, adjust);
if ( ! adjust )
{
scroll_size.setX (getTermX() - 1); scroll_size.setX (getTermX() - 1);
if ( viewport )
{
viewport->x_offset = scroll_size.getX();
viewport->y_offset = scroll_size.getY();
}
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::setY (int y, bool adjust) void FScrollView::setY (int y, bool adjust)
{ {
FWidget::setY (y, adjust); FWidget::setY (y, adjust);
if ( ! adjust )
{
scroll_size.setY (getTermY() - 1); scroll_size.setY (getTermY() - 1);
if ( viewport )
{
viewport->x_offset = scroll_size.getX();
viewport->y_offset = scroll_size.getY();
}
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -135,6 +148,15 @@ void FScrollView::setPos (int x, int y, bool adjust)
{ {
FWidget::setPos (x, y, adjust); FWidget::setPos (x, y, adjust);
scroll_size.setPos (getTermX() - 1, getTermY() - 1); scroll_size.setPos (getTermX() - 1, getTermY() - 1);
if ( ! adjust )
{
if ( viewport )
{
viewport->x_offset = scroll_size.getX();
viewport->y_offset = scroll_size.getY();
}
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -143,7 +165,7 @@ void FScrollView::setWidth (int w, bool adjust)
FWidget::setWidth (w, adjust); FWidget::setWidth (w, adjust);
calculateScrollbarPos(); calculateScrollbarPos();
if ( scroll_size.getWidth() < getClientWidth() ) if ( getScrollWidth() < getClientWidth() )
setScrollWidth (getClientWidth()); setScrollWidth (getClientWidth());
} }
@ -153,7 +175,7 @@ void FScrollView::setHeight (int h, bool adjust)
FWidget::setHeight (h, adjust); FWidget::setHeight (h, adjust);
calculateScrollbarPos(); calculateScrollbarPos();
if ( scroll_size.getHeight() < getClientHeight() ) if ( getScrollHeight() < getClientHeight() )
setScrollHeight (getClientHeight()); setScrollHeight (getClientHeight());
} }
@ -163,8 +185,8 @@ void FScrollView::setSize (int w, int h, bool adjust)
FWidget::setSize (w, h, adjust); FWidget::setSize (w, h, adjust);
calculateScrollbarPos(); calculateScrollbarPos();
if ( scroll_size.getWidth() < getClientWidth() if ( getScrollWidth() < getClientWidth()
|| scroll_size.getHeight() < getClientHeight() ) || getScrollHeight() < getClientHeight() )
setScrollSize (getClientWidth(), getClientHeight()); setScrollSize (getClientWidth(), getClientHeight());
} }
@ -175,9 +197,30 @@ void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust)
scroll_size.setPos (getTermX() - 1, getTermY() - 1); scroll_size.setPos (getTermX() - 1, getTermY() - 1);
calculateScrollbarPos(); calculateScrollbarPos();
if ( scroll_size.getWidth() < getClientWidth() if ( getScrollWidth() < getClientWidth()
|| scroll_size.getHeight() < getClientHeight() ) || getScrollHeight() < getClientHeight() )
{
setScrollSize (getClientWidth(), getClientHeight()); setScrollSize (getClientWidth(), getClientHeight());
}
else if ( ! adjust && viewport )
{
viewport->x_offset = scroll_size.getX();
viewport->y_offset = scroll_size.getY();
}
}
//----------------------------------------------------------------------
void FScrollView::setHorizontalScrollBarMode (fc::scrollBarMode mode)
{
hMode = mode;
setHorizontalScrollBarVisibility();
}
//----------------------------------------------------------------------
void FScrollView::setVerticalScrollBarMode (fc::scrollBarMode mode)
{
vMode = mode;
setVerticalScrollBarVisibility();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -190,7 +233,7 @@ void FScrollView::clearArea (int fillchar)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::draw() void FScrollView::draw()
{ {
own_print_area = true; use_own_print_area = true;
if ( FWidget* p = getParentWidget() ) if ( FWidget* p = getParentWidget() )
setColor (p->getForegroundColor(), p->getBackgroundColor()); setColor (p->getForegroundColor(), p->getBackgroundColor());
@ -202,7 +245,7 @@ void FScrollView::draw()
else else
drawBorder(); drawBorder();
own_print_area = false; use_own_print_area = false;
copy2area(); copy2area();
if ( vbar->isVisible() ) if ( vbar->isVisible() )
@ -210,7 +253,6 @@ void FScrollView::draw()
if ( hbar->isVisible() ) if ( hbar->isVisible() )
hbar->redraw(); hbar->redraw();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -235,7 +277,7 @@ void FScrollView::onWheel (FWheelEvent* ev)
case fc::WheelDown: case fc::WheelDown:
{ {
int yoffset_end = scroll_size.getHeight() - getClientHeight(); int yoffset_end = getScrollHeight() - getClientHeight();
if ( yoffset_end < 0 ) if ( yoffset_end < 0 )
yoffset_end = 0; yoffset_end = 0;
@ -279,7 +321,7 @@ FVTerm::term_area* FScrollView::getPrintArea()
{ {
// returns the viewport print area // returns the viewport print area
if ( viewport && ! own_print_area ) if ( viewport && ! use_own_print_area )
return viewport; return viewport;
else else
return FVTerm::getPrintArea(); return FVTerm::getPrintArea();
@ -294,19 +336,30 @@ void FScrollView::adjustSize()
int xoffset = scroll_offset.getX(); int xoffset = scroll_offset.getX();
int yoffset = scroll_offset.getY(); int yoffset = scroll_offset.getY();
hbar->setMaximum (scroll_size.getWidth() - getClientWidth()); scroll_size.setPos (getTermX() - 1, getTermY() - 1);
hbar->setPageSize (scroll_size.getWidth(), getClientWidth());
if ( viewport )
{
viewport->x_offset = scroll_size.getX();
viewport->y_offset = scroll_size.getY();
}
hbar->setMaximum (getScrollWidth() - getClientWidth());
hbar->setPageSize (getScrollWidth(), getClientWidth());
hbar->setY (height); hbar->setY (height);
hbar->setWidth (width - 2, false); hbar->setWidth (width - 2, false);
hbar->setValue (xoffset); hbar->setValue (xoffset);
hbar->resize(); hbar->resize();
setHorizontalScrollBarVisibility();
vbar->setMaximum (scroll_size.getHeight() - getClientHeight()); vbar->setMaximum (getScrollHeight() - getClientHeight());
vbar->setPageSize (scroll_size.getHeight(), getClientHeight()); vbar->setPageSize (getScrollHeight(), getClientHeight());
vbar->setX (width); vbar->setX (width);
vbar->setHeight (height - 2, false); vbar->setHeight (height - 2, false);
vbar->setValue (yoffset); vbar->setValue (yoffset);
vbar->resize(); vbar->resize();
setVerticalScrollBarVisibility();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -412,6 +465,50 @@ void FScrollView::calculateScrollbarPos()
hbar->resize(); hbar->resize();
} }
//----------------------------------------------------------------------
void FScrollView::setHorizontalScrollBarVisibility()
{
switch ( hMode )
{
case fc::Auto:
if ( getScrollWidth() > getClientWidth() )
hbar->setVisible();
else
hbar->hide();
break;
case fc::Hidden:
hbar->hide();
break;
case fc::Scroll:
hbar->setVisible();
break;
}
}
//----------------------------------------------------------------------
void FScrollView::setVerticalScrollBarVisibility()
{
switch ( vMode )
{
case fc::Auto:
if ( getScrollHeight() > getClientHeight() )
vbar->setVisible();
else
vbar->hide();
break;
case fc::Hidden:
vbar->hide();
break;
case fc::Scroll:
vbar->setVisible();
break;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::cb_VBarChange (FWidget*, void*) void FScrollView::cb_VBarChange (FWidget*, void*)
{ {
@ -420,7 +517,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
int distance = 1; int distance = 1;
int yoffset = scroll_offset.getY(); int yoffset = scroll_offset.getY();
int yoffset_before = yoffset; int yoffset_before = yoffset;
int yoffset_end = scroll_size.getHeight() - getClientHeight(); int yoffset_end = getScrollHeight() - getClientHeight();
scrollType = vbar->getScrollType(); scrollType = vbar->getScrollType();
switch ( scrollType ) switch ( scrollType )
@ -527,7 +624,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
int distance = 1; int distance = 1;
int xoffset = scroll_offset.getX(); int xoffset = scroll_offset.getX();
int xoffset_before = xoffset; int xoffset_before = xoffset;
int xoffset_end = scroll_size.getWidth() - getClientWidth(); int xoffset_end = getScrollWidth() - getClientWidth();
scrollType = hbar->getScrollType(); scrollType = hbar->getScrollType();
switch ( scrollType ) switch ( scrollType )

View File

@ -71,6 +71,8 @@ class FScrollView : public FWidget
virtual void setHeight (int, bool = true); virtual void setHeight (int, bool = true);
virtual void setSize (int, int, bool = true); virtual void setSize (int, int, bool = true);
void setGeometry (int, int, int, int, bool = true); void setGeometry (int, int, int, int, bool = true);
void setHorizontalScrollBarMode (fc::scrollBarMode);
void setVerticalScrollBarMode (fc::scrollBarMode);
// Method // Method
virtual void clearArea (int = ' '); virtual void clearArea (int = ' ');
@ -100,6 +102,8 @@ class FScrollView : public FWidget
// Methods // Methods
void init(); void init();
void calculateScrollbarPos(); void calculateScrollbarPos();
void setHorizontalScrollBarVisibility();
void setVerticalScrollBarVisibility();
// Callback methods // Callback methods
void cb_VBarChange (FWidget*, void*); void cb_VBarChange (FWidget*, void*);
@ -112,7 +116,9 @@ class FScrollView : public FWidget
FScrollbar* vbar; FScrollbar* vbar;
FScrollbar* hbar; FScrollbar* hbar;
int nf_offset; int nf_offset;
bool own_print_area; bool use_own_print_area;
fc::scrollBarMode vMode; // fc:Auto, fc::Hidden or fc::Scroll
fc::scrollBarMode hMode;
}; };
#pragma pack(pop) #pragma pack(pop)

View File

@ -1652,7 +1652,7 @@ void FVTerm::clearArea (term_area* area, int fillchar)
std::memcpy (&nc, &next_attribute, sizeof(char_data)); std::memcpy (&nc, &next_attribute, sizeof(char_data));
nc.code = fillchar; nc.code = fillchar;
if ( ! area ) if ( ! (area && area->text) )
return; return;
total_width = area->width + area->right_shadow; total_width = area->width + area->right_shadow;