FScrollView now scrolls automatically to the focused widget

This commit is contained in:
Markus Gans 2017-01-26 00:31:07 +01:00
parent 51b1d18a84
commit 59189160fd
14 changed files with 158 additions and 79 deletions

View File

@ -1,3 +1,6 @@
2017-01-26 Markus Gans <guru.mail@muenster.de>
* FScrollView now scrolls automatically to the focused widget
2017-01-22 Markus Gans <guru.mail@muenster.de> 2017-01-22 Markus Gans <guru.mail@muenster.de>
* A FScrollView object can now have client widgets * A FScrollView object can now have client widgets
on the scrolling area on the scrolling area

View File

@ -60,7 +60,7 @@ finalcutinclude_HEADERS = \
fconfig.h \ fconfig.h \
fswitch.h \ fswitch.h \
fdialog.h \ fdialog.h \
fenum.h \ fc.h \
fevent.h \ fevent.h \
ffiledialog.h \ ffiledialog.h \
final.h \ final.h \

View File

@ -423,7 +423,7 @@ finalcutinclude_HEADERS = \
fconfig.h \ fconfig.h \
fswitch.h \ fswitch.h \
fdialog.h \ fdialog.h \
fenum.h \ fc.h \
fevent.h \ fevent.h \
ffiledialog.h \ ffiledialog.h \
final.h \ final.h \

View File

@ -199,9 +199,15 @@ bool FButton::setShadow (bool on)
if ( on if ( on
&& (Encoding != fc::VT100 || isTeraTerm() ) && (Encoding != fc::VT100 || isTeraTerm() )
&& Encoding != fc::ASCII ) && Encoding != fc::ASCII )
{
flags |= fc::shadow; flags |= fc::shadow;
setShadowSize(1,1);
}
else else
{
flags &= ~fc::shadow; flags &= ~fc::shadow;
setShadowSize(0,0);
}
return on; return on;
} }

View File

@ -1,4 +1,4 @@
// File: fenum.h // File: fc.h
// Provides: class fc // Provides: class fc
// //
// Standalone class // Standalone class
@ -8,8 +8,8 @@
// ▕ fc ▏ // ▕ fc ▏
// ▕▁▁▁▁▁▁▁▁▏ // ▕▁▁▁▁▁▁▁▁▏
#ifndef _FENUM_H #ifndef _FC_H
#define _FENUM_H #define _FC_H
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -36,6 +36,7 @@ class fc
MouseMove_Event, // mouse move MouseMove_Event, // mouse move
FocusIn_Event, // focus in FocusIn_Event, // focus in
FocusOut_Event, // focus out FocusOut_Event, // focus out
ChildFocusChanged_Event, // child focus changed
WindowActive_Event, // activate window WindowActive_Event, // activate window
WindowInactive_Event, // deactivate window WindowInactive_Event, // deactivate window
WindowRaised_Event, // raise window WindowRaised_Event, // raise window
@ -1065,4 +1066,4 @@ class fc
#pragma pack(pop) #pragma pack(pop)
#endif // _FENUM_H #endif // _FC_H

View File

@ -53,7 +53,7 @@
#ifndef _FEVENT_H #ifndef _FEVENT_H
#define _FEVENT_H #define _FEVENT_H
#include "fenum.h" #include "fc.h"
#include "fpoint.h" #include "fpoint.h"

View File

@ -139,9 +139,15 @@ bool FLineEdit::setShadow (bool on)
if ( on if ( on
&& (Encoding != fc::VT100 || isTeraTerm() ) && (Encoding != fc::VT100 || isTeraTerm() )
&& Encoding != fc::ASCII ) && Encoding != fc::ASCII )
{
flags |= fc::shadow; flags |= fc::shadow;
setShadowSize(1,1);
}
else else
{
flags &= ~fc::shadow; flags &= ~fc::shadow;
setShadowSize(0,0);
}
return on; return on;
} }

View File

@ -72,9 +72,15 @@ bool FProgressbar::setShadow (bool on)
if ( on if ( on
&& (Encoding != fc::VT100 || isTeraTerm() ) && (Encoding != fc::VT100 || isTeraTerm() )
&& Encoding != fc::ASCII ) && Encoding != fc::ASCII )
{
flags |= fc::shadow; flags |= fc::shadow;
setShadowSize(1,1);
}
else else
{
flags &= ~fc::shadow; flags &= ~fc::shadow;
setShadowSize(0,0);
}
return on; return on;
} }

View File

@ -12,8 +12,8 @@
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FScrollView::FScrollView (FWidget* parent) FScrollView::FScrollView (FWidget* parent)
: FWidget(parent) : FWidget(parent)
, scroll_size(1,1,1,1) , scroll_geometry(1,1,1,1)
, scroll_offset() , viewport_geometry()
, viewport(0) , viewport(0)
, vbar(0) , vbar(0)
, hbar(0) , hbar(0)
@ -48,8 +48,8 @@ void FScrollView::setScrollWidth (int width)
if ( viewport ) if ( viewport )
{ {
FPoint no_shadow(0,0); FPoint no_shadow(0,0);
scroll_size.setWidth (width); scroll_geometry.setWidth (width);
resizeArea (scroll_size, no_shadow, viewport); resizeArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler setPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
@ -75,8 +75,8 @@ void FScrollView::setScrollHeight (int height)
if ( viewport ) if ( viewport )
{ {
FPoint no_shadow(0,0); FPoint no_shadow(0,0);
scroll_size.setHeight (height); scroll_geometry.setHeight (height);
resizeArea (scroll_size, no_shadow, viewport); resizeArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler setPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
@ -105,8 +105,8 @@ void FScrollView::setScrollSize (int width, int height)
if ( viewport ) if ( viewport )
{ {
FPoint no_shadow(0,0); FPoint no_shadow(0,0);
scroll_size.setSize (width, height); scroll_geometry.setSize (width, height);
resizeArea (scroll_size, no_shadow, viewport); resizeArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler setPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
@ -137,12 +137,12 @@ void FScrollView::setX (int x, bool adjust)
if ( ! adjust ) if ( ! adjust )
{ {
scroll_size.setX (getTermX() + getLeftPadding() - 1); scroll_geometry.setX (getTermX() + getLeftPadding() - 1);
if ( viewport ) if ( viewport )
{ {
viewport->offset_top = scroll_size.getX(); viewport->offset_top = scroll_geometry.getX();
viewport->offset_left = scroll_size.getY(); viewport->offset_left = scroll_geometry.getY();
} }
} }
} }
@ -154,12 +154,12 @@ void FScrollView::setY (int y, bool adjust)
if ( ! adjust ) if ( ! adjust )
{ {
scroll_size.setY (getTermY() + getTopPadding() - 1); scroll_geometry.setY (getTermY() + getTopPadding() - 1);
if ( viewport ) if ( viewport )
{ {
viewport->offset_top = scroll_size.getX(); viewport->offset_top = scroll_geometry.getX();
viewport->offset_left = scroll_size.getY(); viewport->offset_left = scroll_geometry.getY();
} }
} }
} }
@ -168,15 +168,15 @@ void FScrollView::setY (int y, bool adjust)
void FScrollView::setPos (int x, int y, bool adjust) void FScrollView::setPos (int x, int y, bool adjust)
{ {
FWidget::setPos (x, y, adjust); FWidget::setPos (x, y, adjust);
scroll_size.setPos ( getTermX() + getLeftPadding() - 1 scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1
, getTermY() + getTopPadding() - 1 ); , getTermY() + getTopPadding() - 1 );
if ( ! adjust ) if ( ! adjust )
{ {
if ( viewport ) if ( viewport )
{ {
viewport->offset_top = scroll_size.getX(); viewport->offset_top = scroll_geometry.getX();
viewport->offset_left = scroll_size.getY(); viewport->offset_left = scroll_geometry.getY();
} }
} }
} }
@ -185,6 +185,7 @@ void FScrollView::setPos (int x, int y, bool adjust)
void FScrollView::setWidth (int w, bool adjust) void FScrollView::setWidth (int w, bool adjust)
{ {
FWidget::setWidth (w, adjust); FWidget::setWidth (w, adjust);
viewport_geometry.setWidth(w);
calculateScrollbarPos(); calculateScrollbarPos();
if ( getScrollWidth() < getViewportWidth() ) if ( getScrollWidth() < getViewportWidth() )
@ -195,6 +196,7 @@ void FScrollView::setWidth (int w, bool adjust)
void FScrollView::setHeight (int h, bool adjust) void FScrollView::setHeight (int h, bool adjust)
{ {
FWidget::setHeight (h, adjust); FWidget::setHeight (h, adjust);
viewport_geometry.setHeight(h);
calculateScrollbarPos(); calculateScrollbarPos();
if ( getScrollHeight() < getViewportHeight() ) if ( getScrollHeight() < getViewportHeight() )
@ -205,6 +207,7 @@ void FScrollView::setHeight (int h, bool adjust)
void FScrollView::setSize (int w, int h, bool adjust) void FScrollView::setSize (int w, int h, bool adjust)
{ {
FWidget::setSize (w, h, adjust); FWidget::setSize (w, h, adjust);
viewport_geometry.setSize(w, h);
calculateScrollbarPos(); calculateScrollbarPos();
if ( getScrollWidth() < getViewportWidth() if ( getScrollWidth() < getViewportWidth()
@ -216,8 +219,9 @@ void FScrollView::setSize (int w, int h, bool adjust)
void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust) void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust)
{ {
FWidget::setGeometry (x, y, w, h, adjust); FWidget::setGeometry (x, y, w, h, adjust);
scroll_size.setPos ( getTermX() + getLeftPadding() - 1 scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1
, getTermY() + getTopPadding() - 1 ); , getTermY() + getTopPadding() - 1 );
viewport_geometry.setSize(w, h);
calculateScrollbarPos(); calculateScrollbarPos();
if ( getScrollWidth() < getViewportWidth() if ( getScrollWidth() < getViewportWidth()
@ -227,8 +231,8 @@ void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust)
} }
else if ( ! adjust && viewport ) else if ( ! adjust && viewport )
{ {
viewport->offset_top = scroll_size.getX(); viewport->offset_top = scroll_geometry.getX();
viewport->offset_left = scroll_size.getY(); viewport->offset_left = scroll_geometry.getY();
} }
} }
@ -262,20 +266,20 @@ void FScrollView::clearArea (int fillchar)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::scrollToX (int x) void FScrollView::scrollToX (int x)
{ {
scrollTo (x, scroll_offset.getY() + 1); scrollTo (x, viewport_geometry.getY() + 1);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::scrollToY (int y) void FScrollView::scrollToY (int y)
{ {
scrollTo (scroll_offset.getX() + 1, y); scrollTo (viewport_geometry.getX() + 1, y);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::scrollTo (int x, int y) void FScrollView::scrollTo (int x, int y)
{ {
short& xoffset = scroll_offset.x_ref(); short& xoffset = viewport_geometry.x1_ref();
short& yoffset = scroll_offset.y_ref(); short& yoffset = viewport_geometry.y1_ref();
short xoffset_end = short(getScrollWidth() - getViewportWidth()); short xoffset_end = short(getScrollWidth() - getViewportWidth());
short yoffset_end = short(getScrollHeight() - getViewportHeight()); short yoffset_end = short(getScrollHeight() - getViewportHeight());
x--; x--;
@ -344,8 +348,8 @@ void FScrollView::onKeyPress (FKeyEvent* ev)
{ {
int key = ev->key(); int key = ev->key();
bool hasChanges = false; bool hasChanges = false;
short& xoffset = scroll_offset.x_ref(); short& xoffset = viewport_geometry.x1_ref();
short& yoffset = scroll_offset.y_ref(); short& yoffset = viewport_geometry.y1_ref();
short xoffset_before = xoffset; short xoffset_before = xoffset;
short yoffset_before = yoffset; short yoffset_before = yoffset;
short xoffset_end = short(getScrollWidth() - getViewportWidth()); short xoffset_end = short(getScrollWidth() - getViewportWidth());
@ -440,7 +444,7 @@ void FScrollView::onKeyPress (FKeyEvent* ev)
void FScrollView::onWheel (FWheelEvent* ev) void FScrollView::onWheel (FWheelEvent* ev)
{ {
bool hasChanges = false; bool hasChanges = false;
short& yoffset = scroll_offset.y_ref(); short& yoffset = viewport_geometry.y1_ref();
short yoffset_before = yoffset; short yoffset_before = yoffset;
int wheel = ev->getWheel(); int wheel = ev->getWheel();
@ -493,6 +497,41 @@ void FScrollView::onWheel (FWheelEvent* ev)
updateTerminal(); updateTerminal();
} }
//----------------------------------------------------------------------
void FScrollView::onChildFocusChanged (FFocusEvent*)
{
// Scrolls the viewport so that the focused widget is visible
FRect widget_geometry;
FWidget* focus_widget = FWidget::getFocusWidget();
if ( ! focus_widget )
return;
widget_geometry = focus_widget->getGeometryWithShadow();
if ( ! viewport_geometry.contains(widget_geometry) )
{
int x, y;
int vx = viewport_geometry.getX();
int vy = viewport_geometry.getY();
int wx = widget_geometry.getX();
int wy = widget_geometry.getY();
if ( wx > vx )
x = widget_geometry.getX2() - viewport_geometry.getWidth() + 3;
else if ( wx < vx )
x = wx;
if ( wy > vy )
y = widget_geometry.getY2() - viewport_geometry.getHeight() + 3;
else if ( wy < vy )
y = wy;
scrollTo (x, y);
}
}
// protected methods of FScrollView // protected methods of FScrollView
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -517,16 +556,16 @@ void FScrollView::adjustSize()
FWidget::adjustSize(); FWidget::adjustSize();
int width = getWidth(); int width = getWidth();
int height = getHeight(); int height = getHeight();
int xoffset = scroll_offset.getX(); int xoffset = viewport_geometry.getX();
int yoffset = scroll_offset.getY(); int yoffset = viewport_geometry.getY();
scroll_size.setPos ( getTermX() + getLeftPadding() - 1 scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1
, getTermY() + getTopPadding() - 1 ); , getTermY() + getTopPadding() - 1 );
if ( viewport ) if ( viewport )
{ {
viewport->offset_top = scroll_size.getX(); viewport->offset_top = scroll_geometry.getX();
viewport->offset_left = scroll_size.getY(); viewport->offset_left = scroll_geometry.getY();
} }
hbar->setMaximum (getScrollWidth() - getViewportWidth()); hbar->setMaximum (getScrollWidth() - getViewportWidth());
@ -566,8 +605,8 @@ void FScrollView::copy2area()
ax = getTermX() - print_area->offset_top; ax = getTermX() - print_area->offset_top;
ay = getTermY() - print_area->offset_left; ay = getTermY() - print_area->offset_left;
dx = scroll_offset.getX(); dx = viewport_geometry.getX();
dy = scroll_offset.getY(); dy = viewport_geometry.getY();
y_end = getViewportHeight(); y_end = getViewportHeight();
x_end = getViewportWidth(); x_end = getViewportWidth();
@ -636,8 +675,8 @@ void FScrollView::init()
if ( h < 1 ) if ( h < 1 )
h = 1; h = 1;
scroll_size.setRect (0, 0, w, h); scroll_geometry.setRect (0, 0, w, h);
createArea (scroll_size, no_shadow, viewport); createArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler setPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
@ -718,7 +757,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
FScrollbar::sType scrollType; FScrollbar::sType scrollType;
bool hasChanges = false; bool hasChanges = false;
short distance = 1; short distance = 1;
short& yoffset = scroll_offset.y_ref(); short& yoffset = viewport_geometry.y1_ref();
short yoffset_before = yoffset; short yoffset_before = yoffset;
short yoffset_end = short(getScrollHeight() - getViewportHeight()); short yoffset_end = short(getScrollHeight() - getViewportHeight());
scrollType = vbar->getScrollType(); scrollType = vbar->getScrollType();
@ -821,7 +860,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
FScrollbar::sType scrollType; FScrollbar::sType scrollType;
bool hasChanges = false; bool hasChanges = false;
short distance = 1; short distance = 1;
short& xoffset = scroll_offset.x_ref(); short& xoffset = viewport_geometry.x1_ref();
short xoffset_before = xoffset; short xoffset_before = xoffset;
short xoffset_end = short(getScrollWidth() - getViewportWidth()); short xoffset_end = short(getScrollWidth() - getViewportWidth());
scrollType = hbar->getScrollType(); scrollType = hbar->getScrollType();

View File

@ -91,6 +91,7 @@ class FScrollView : public FWidget
// Event handlers // Event handlers
void onKeyPress (FKeyEvent*); void onKeyPress (FKeyEvent*);
void onWheel (FWheelEvent*); void onWheel (FWheelEvent*);
void onChildFocusChanged (FFocusEvent*);
protected: protected:
// Using-declaration // Using-declaration
@ -129,8 +130,8 @@ class FScrollView : public FWidget
void cb_HBarChange (FWidget*, void*); void cb_HBarChange (FWidget*, void*);
// Data Members // Data Members
FRect scroll_size; FRect scroll_geometry;
FPoint scroll_offset; FRect viewport_geometry;
term_area* viewport; // virtual scroll content term_area* viewport; // virtual scroll content
FScrollbar* vbar; FScrollbar* vbar;
FScrollbar* hbar; FScrollbar* hbar;
@ -157,23 +158,23 @@ inline int FScrollView::getViewportHeight() const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline int FScrollView::getScrollWidth() const inline int FScrollView::getScrollWidth() const
{ return scroll_size.getWidth(); } { return scroll_geometry.getWidth(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline int FScrollView::getScrollHeight() const inline int FScrollView::getScrollHeight() const
{ return scroll_size.getHeight(); } { return scroll_geometry.getHeight(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline const FPoint FScrollView::getScrollPos() const inline const FPoint FScrollView::getScrollPos() const
{ return scroll_offset; } { return viewport_geometry.getPos(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline int FScrollView::getScrollX() const inline int FScrollView::getScrollX() const
{ return scroll_offset.getX(); } { return viewport_geometry.getX(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline int FScrollView::getScrollY() const inline int FScrollView::getScrollY() const
{ return scroll_offset.getY(); } { return viewport_geometry.getY(); }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FScrollView::scrollTo (FPoint pos) inline void FScrollView::scrollTo (FPoint pos)

View File

@ -52,7 +52,7 @@
#include <map> #include <map>
#include <queue> #include <queue>
#include "fenum.h" #include "fc.h"
#include "fobject.h" #include "fobject.h"
#include "foptiattr.h" #include "foptiattr.h"
#include "foptimove.h" #include "foptimove.h"

View File

@ -264,6 +264,7 @@ void FWidget::setStatusbarMessage (FString msg)
bool FWidget::setFocus (bool on) bool FWidget::setFocus (bool on)
{ {
FWindow* window; FWindow* window;
FWidget* last_focus;
if ( ! enable ) if ( ! enable )
return false; return false;
@ -271,13 +272,15 @@ bool FWidget::setFocus (bool on)
if ( on == focus ) if ( on == focus )
return true; return true;
last_focus = FWidget::getFocusWidget();
// set widget focus // set widget focus
if ( on && ! focus ) if ( on && ! focus )
{ {
int focusable_children = numOfFocusableChildren(); int focusable_children = numOfFocusableChildren();
if ( FWidget::getFocusWidget() ) if ( last_focus )
FWidget::getFocusWidget()->unsetFocus(); last_focus->unsetFocus();
if ( (!isDialogWidget() && focusable_children == 0) if ( (!isDialogWidget() && focusable_children == 0)
|| (isDialogWidget() && focusable_children == 1) ) || (isDialogWidget() && focusable_children == 1) )
@ -302,6 +305,12 @@ bool FWidget::setFocus (bool on)
window->setWindowFocusWidget(this); window->setWindowFocusWidget(this);
} }
if ( hasParent() && last_focus != FWidget::getFocusWidget() )
{
FFocusEvent cfc (fc::ChildFocusChanged_Event);
FApplication::sendEvent(getParentWidget(), &cfc);
}
return focus = (on) ? true : false; return focus = (on) ? true : false;
} }
@ -1995,6 +2004,10 @@ bool FWidget::event (FEvent* ev)
onFocusOut ( static_cast<FFocusEvent*>(ev) ); onFocusOut ( static_cast<FFocusEvent*>(ev) );
break; break;
case fc::ChildFocusChanged_Event:
onChildFocusChanged ( static_cast<FFocusEvent*>(ev) );
break;
case fc::Accelerator_Event: case fc::Accelerator_Event:
onAccel ( static_cast<FAccelEvent*>(ev) ); onAccel ( static_cast<FAccelEvent*>(ev) );
break; break;
@ -2065,6 +2078,10 @@ void FWidget::onFocusIn (FFocusEvent*)
void FWidget::onFocusOut (FFocusEvent*) void FWidget::onFocusOut (FFocusEvent*)
{ } { }
//----------------------------------------------------------------------
void FWidget::onChildFocusChanged (FFocusEvent*)
{ }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::onAccel (FAccelEvent*) void FWidget::onAccel (FAccelEvent*)
{ } { }

View File

@ -313,6 +313,7 @@ class FWidget : public FVTerm
virtual void onMouseMove (FMouseEvent*); virtual void onMouseMove (FMouseEvent*);
virtual void onFocusIn (FFocusEvent*); virtual void onFocusIn (FFocusEvent*);
virtual void onFocusOut (FFocusEvent*); virtual void onFocusOut (FFocusEvent*);
virtual void onChildFocusChanged (FFocusEvent*);
virtual void onAccel (FAccelEvent*); virtual void onAccel (FAccelEvent*);
virtual void onResize (FResizeEvent*); virtual void onResize (FResizeEvent*);
virtual void onShow (FShowEvent*); virtual void onShow (FShowEvent*);

View File

@ -60,7 +60,6 @@ scrollview::scrollview (FWidget* parent)
go_north = new FButton(wchar_t(fc::BlackUpPointingTriangle) , this); go_north = new FButton(wchar_t(fc::BlackUpPointingTriangle) , this);
go_north->setGeometry (1, getScrollHeight() - 2, 5, 1); go_north->setGeometry (1, getScrollHeight() - 2, 5, 1);
if ( isCygwinTerminal() ) if ( isCygwinTerminal() )
{ {
go_south->setText ('v'); go_south->setText ('v');