FScrollView now scrolls automatically to the focused widget
This commit is contained in:
parent
51b1d18a84
commit
59189160fd
|
@ -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>
|
||||
* A FScrollView object can now have client widgets
|
||||
on the scrolling area
|
||||
|
|
|
@ -60,7 +60,7 @@ finalcutinclude_HEADERS = \
|
|||
fconfig.h \
|
||||
fswitch.h \
|
||||
fdialog.h \
|
||||
fenum.h \
|
||||
fc.h \
|
||||
fevent.h \
|
||||
ffiledialog.h \
|
||||
final.h \
|
||||
|
|
|
@ -423,7 +423,7 @@ finalcutinclude_HEADERS = \
|
|||
fconfig.h \
|
||||
fswitch.h \
|
||||
fdialog.h \
|
||||
fenum.h \
|
||||
fc.h \
|
||||
fevent.h \
|
||||
ffiledialog.h \
|
||||
final.h \
|
||||
|
|
|
@ -199,9 +199,15 @@ bool FButton::setShadow (bool on)
|
|||
if ( on
|
||||
&& (Encoding != fc::VT100 || isTeraTerm() )
|
||||
&& Encoding != fc::ASCII )
|
||||
{
|
||||
flags |= fc::shadow;
|
||||
setShadowSize(1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~fc::shadow;
|
||||
setShadowSize(0,0);
|
||||
}
|
||||
|
||||
return on;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// File: fenum.h
|
||||
// File: fc.h
|
||||
// Provides: class fc
|
||||
//
|
||||
// Standalone class
|
||||
|
@ -8,8 +8,8 @@
|
|||
// ▕ fc ▏
|
||||
// ▕▁▁▁▁▁▁▁▁▏
|
||||
|
||||
#ifndef _FENUM_H
|
||||
#define _FENUM_H
|
||||
#ifndef _FC_H
|
||||
#define _FC_H
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -36,6 +36,7 @@ class fc
|
|||
MouseMove_Event, // mouse move
|
||||
FocusIn_Event, // focus in
|
||||
FocusOut_Event, // focus out
|
||||
ChildFocusChanged_Event, // child focus changed
|
||||
WindowActive_Event, // activate window
|
||||
WindowInactive_Event, // deactivate window
|
||||
WindowRaised_Event, // raise window
|
||||
|
@ -1065,4 +1066,4 @@ class fc
|
|||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // _FENUM_H
|
||||
#endif // _FC_H
|
|
@ -53,7 +53,7 @@
|
|||
#ifndef _FEVENT_H
|
||||
#define _FEVENT_H
|
||||
|
||||
#include "fenum.h"
|
||||
#include "fc.h"
|
||||
#include "fpoint.h"
|
||||
|
||||
|
||||
|
|
|
@ -139,9 +139,15 @@ bool FLineEdit::setShadow (bool on)
|
|||
if ( on
|
||||
&& (Encoding != fc::VT100 || isTeraTerm() )
|
||||
&& Encoding != fc::ASCII )
|
||||
{
|
||||
flags |= fc::shadow;
|
||||
setShadowSize(1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~fc::shadow;
|
||||
setShadowSize(0,0);
|
||||
}
|
||||
|
||||
return on;
|
||||
}
|
||||
|
|
|
@ -72,9 +72,15 @@ bool FProgressbar::setShadow (bool on)
|
|||
if ( on
|
||||
&& (Encoding != fc::VT100 || isTeraTerm() )
|
||||
&& Encoding != fc::ASCII )
|
||||
{
|
||||
flags |= fc::shadow;
|
||||
setShadowSize(1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~fc::shadow;
|
||||
setShadowSize(0,0);
|
||||
}
|
||||
|
||||
return on;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
//----------------------------------------------------------------------
|
||||
FScrollView::FScrollView (FWidget* parent)
|
||||
: FWidget(parent)
|
||||
, scroll_size(1,1,1,1)
|
||||
, scroll_offset()
|
||||
, scroll_geometry(1,1,1,1)
|
||||
, viewport_geometry()
|
||||
, viewport(0)
|
||||
, vbar(0)
|
||||
, hbar(0)
|
||||
|
@ -48,8 +48,8 @@ void FScrollView::setScrollWidth (int width)
|
|||
if ( viewport )
|
||||
{
|
||||
FPoint no_shadow(0,0);
|
||||
scroll_size.setWidth (width);
|
||||
resizeArea (scroll_size, no_shadow, viewport);
|
||||
scroll_geometry.setWidth (width);
|
||||
resizeArea (scroll_geometry, no_shadow, viewport);
|
||||
setPreprocessingHandler
|
||||
(
|
||||
_PREPROC_HANDLER (this, &FScrollView::copy2area)
|
||||
|
@ -75,8 +75,8 @@ void FScrollView::setScrollHeight (int height)
|
|||
if ( viewport )
|
||||
{
|
||||
FPoint no_shadow(0,0);
|
||||
scroll_size.setHeight (height);
|
||||
resizeArea (scroll_size, no_shadow, viewport);
|
||||
scroll_geometry.setHeight (height);
|
||||
resizeArea (scroll_geometry, no_shadow, viewport);
|
||||
setPreprocessingHandler
|
||||
(
|
||||
_PREPROC_HANDLER (this, &FScrollView::copy2area)
|
||||
|
@ -105,8 +105,8 @@ void FScrollView::setScrollSize (int width, int height)
|
|||
if ( viewport )
|
||||
{
|
||||
FPoint no_shadow(0,0);
|
||||
scroll_size.setSize (width, height);
|
||||
resizeArea (scroll_size, no_shadow, viewport);
|
||||
scroll_geometry.setSize (width, height);
|
||||
resizeArea (scroll_geometry, no_shadow, viewport);
|
||||
setPreprocessingHandler
|
||||
(
|
||||
_PREPROC_HANDLER (this, &FScrollView::copy2area)
|
||||
|
@ -137,12 +137,12 @@ void FScrollView::setX (int x, bool adjust)
|
|||
|
||||
if ( ! adjust )
|
||||
{
|
||||
scroll_size.setX (getTermX() + getLeftPadding() - 1);
|
||||
scroll_geometry.setX (getTermX() + getLeftPadding() - 1);
|
||||
|
||||
if ( viewport )
|
||||
{
|
||||
viewport->offset_top = scroll_size.getX();
|
||||
viewport->offset_left = scroll_size.getY();
|
||||
viewport->offset_top = scroll_geometry.getX();
|
||||
viewport->offset_left = scroll_geometry.getY();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,12 +154,12 @@ void FScrollView::setY (int y, bool adjust)
|
|||
|
||||
if ( ! adjust )
|
||||
{
|
||||
scroll_size.setY (getTermY() + getTopPadding() - 1);
|
||||
scroll_geometry.setY (getTermY() + getTopPadding() - 1);
|
||||
|
||||
if ( viewport )
|
||||
{
|
||||
viewport->offset_top = scroll_size.getX();
|
||||
viewport->offset_left = scroll_size.getY();
|
||||
viewport->offset_top = scroll_geometry.getX();
|
||||
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)
|
||||
{
|
||||
FWidget::setPos (x, y, adjust);
|
||||
scroll_size.setPos ( getTermX() + getLeftPadding() - 1
|
||||
scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1
|
||||
, getTermY() + getTopPadding() - 1 );
|
||||
|
||||
if ( ! adjust )
|
||||
{
|
||||
if ( viewport )
|
||||
{
|
||||
viewport->offset_top = scroll_size.getX();
|
||||
viewport->offset_left = scroll_size.getY();
|
||||
viewport->offset_top = scroll_geometry.getX();
|
||||
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)
|
||||
{
|
||||
FWidget::setWidth (w, adjust);
|
||||
viewport_geometry.setWidth(w);
|
||||
calculateScrollbarPos();
|
||||
|
||||
if ( getScrollWidth() < getViewportWidth() )
|
||||
|
@ -195,6 +196,7 @@ void FScrollView::setWidth (int w, bool adjust)
|
|||
void FScrollView::setHeight (int h, bool adjust)
|
||||
{
|
||||
FWidget::setHeight (h, adjust);
|
||||
viewport_geometry.setHeight(h);
|
||||
calculateScrollbarPos();
|
||||
|
||||
if ( getScrollHeight() < getViewportHeight() )
|
||||
|
@ -205,6 +207,7 @@ void FScrollView::setHeight (int h, bool adjust)
|
|||
void FScrollView::setSize (int w, int h, bool adjust)
|
||||
{
|
||||
FWidget::setSize (w, h, adjust);
|
||||
viewport_geometry.setSize(w, h);
|
||||
calculateScrollbarPos();
|
||||
|
||||
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)
|
||||
{
|
||||
FWidget::setGeometry (x, y, w, h, adjust);
|
||||
scroll_size.setPos ( getTermX() + getLeftPadding() - 1
|
||||
scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1
|
||||
, getTermY() + getTopPadding() - 1 );
|
||||
viewport_geometry.setSize(w, h);
|
||||
calculateScrollbarPos();
|
||||
|
||||
if ( getScrollWidth() < getViewportWidth()
|
||||
|
@ -227,8 +231,8 @@ void FScrollView::setGeometry (int x, int y, int w, int h, bool adjust)
|
|||
}
|
||||
else if ( ! adjust && viewport )
|
||||
{
|
||||
viewport->offset_top = scroll_size.getX();
|
||||
viewport->offset_left = scroll_size.getY();
|
||||
viewport->offset_top = scroll_geometry.getX();
|
||||
viewport->offset_left = scroll_geometry.getY();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,20 +266,20 @@ void FScrollView::clearArea (int fillchar)
|
|||
//----------------------------------------------------------------------
|
||||
void FScrollView::scrollToX (int x)
|
||||
{
|
||||
scrollTo (x, scroll_offset.getY() + 1);
|
||||
scrollTo (x, viewport_geometry.getY() + 1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FScrollView::scrollToY (int y)
|
||||
{
|
||||
scrollTo (scroll_offset.getX() + 1, y);
|
||||
scrollTo (viewport_geometry.getX() + 1, y);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FScrollView::scrollTo (int x, int y)
|
||||
{
|
||||
short& xoffset = scroll_offset.x_ref();
|
||||
short& yoffset = scroll_offset.y_ref();
|
||||
short& xoffset = viewport_geometry.x1_ref();
|
||||
short& yoffset = viewport_geometry.y1_ref();
|
||||
short xoffset_end = short(getScrollWidth() - getViewportWidth());
|
||||
short yoffset_end = short(getScrollHeight() - getViewportHeight());
|
||||
x--;
|
||||
|
@ -344,8 +348,8 @@ 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 = viewport_geometry.x1_ref();
|
||||
short& yoffset = viewport_geometry.y1_ref();
|
||||
short xoffset_before = xoffset;
|
||||
short yoffset_before = yoffset;
|
||||
short xoffset_end = short(getScrollWidth() - getViewportWidth());
|
||||
|
@ -440,7 +444,7 @@ void FScrollView::onKeyPress (FKeyEvent* ev)
|
|||
void FScrollView::onWheel (FWheelEvent* ev)
|
||||
{
|
||||
bool hasChanges = false;
|
||||
short& yoffset = scroll_offset.y_ref();
|
||||
short& yoffset = viewport_geometry.y1_ref();
|
||||
short yoffset_before = yoffset;
|
||||
int wheel = ev->getWheel();
|
||||
|
||||
|
@ -493,6 +497,41 @@ void FScrollView::onWheel (FWheelEvent* ev)
|
|||
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
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -517,16 +556,16 @@ void FScrollView::adjustSize()
|
|||
FWidget::adjustSize();
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int xoffset = scroll_offset.getX();
|
||||
int yoffset = scroll_offset.getY();
|
||||
int xoffset = viewport_geometry.getX();
|
||||
int yoffset = viewport_geometry.getY();
|
||||
|
||||
scroll_size.setPos ( getTermX() + getLeftPadding() - 1
|
||||
scroll_geometry.setPos ( getTermX() + getLeftPadding() - 1
|
||||
, getTermY() + getTopPadding() - 1 );
|
||||
|
||||
if ( viewport )
|
||||
{
|
||||
viewport->offset_top = scroll_size.getX();
|
||||
viewport->offset_left = scroll_size.getY();
|
||||
viewport->offset_top = scroll_geometry.getX();
|
||||
viewport->offset_left = scroll_geometry.getY();
|
||||
}
|
||||
|
||||
hbar->setMaximum (getScrollWidth() - getViewportWidth());
|
||||
|
@ -566,8 +605,8 @@ void FScrollView::copy2area()
|
|||
|
||||
ax = getTermX() - print_area->offset_top;
|
||||
ay = getTermY() - print_area->offset_left;
|
||||
dx = scroll_offset.getX();
|
||||
dy = scroll_offset.getY();
|
||||
dx = viewport_geometry.getX();
|
||||
dy = viewport_geometry.getY();
|
||||
y_end = getViewportHeight();
|
||||
x_end = getViewportWidth();
|
||||
|
||||
|
@ -636,8 +675,8 @@ void FScrollView::init()
|
|||
if ( h < 1 )
|
||||
h = 1;
|
||||
|
||||
scroll_size.setRect (0, 0, w, h);
|
||||
createArea (scroll_size, no_shadow, viewport);
|
||||
scroll_geometry.setRect (0, 0, w, h);
|
||||
createArea (scroll_geometry, no_shadow, viewport);
|
||||
setPreprocessingHandler
|
||||
(
|
||||
_PREPROC_HANDLER (this, &FScrollView::copy2area)
|
||||
|
@ -718,7 +757,7 @@ void FScrollView::cb_VBarChange (FWidget*, void*)
|
|||
FScrollbar::sType scrollType;
|
||||
bool hasChanges = false;
|
||||
short distance = 1;
|
||||
short& yoffset = scroll_offset.y_ref();
|
||||
short& yoffset = viewport_geometry.y1_ref();
|
||||
short yoffset_before = yoffset;
|
||||
short yoffset_end = short(getScrollHeight() - getViewportHeight());
|
||||
scrollType = vbar->getScrollType();
|
||||
|
@ -821,7 +860,7 @@ void FScrollView::cb_HBarChange (FWidget*, void*)
|
|||
FScrollbar::sType scrollType;
|
||||
bool hasChanges = false;
|
||||
short distance = 1;
|
||||
short& xoffset = scroll_offset.x_ref();
|
||||
short& xoffset = viewport_geometry.x1_ref();
|
||||
short xoffset_before = xoffset;
|
||||
short xoffset_end = short(getScrollWidth() - getViewportWidth());
|
||||
scrollType = hbar->getScrollType();
|
||||
|
|
|
@ -91,6 +91,7 @@ class FScrollView : public FWidget
|
|||
// Event handlers
|
||||
void onKeyPress (FKeyEvent*);
|
||||
void onWheel (FWheelEvent*);
|
||||
void onChildFocusChanged (FFocusEvent*);
|
||||
|
||||
protected:
|
||||
// Using-declaration
|
||||
|
@ -129,8 +130,8 @@ class FScrollView : public FWidget
|
|||
void cb_HBarChange (FWidget*, void*);
|
||||
|
||||
// Data Members
|
||||
FRect scroll_size;
|
||||
FPoint scroll_offset;
|
||||
FRect scroll_geometry;
|
||||
FRect viewport_geometry;
|
||||
term_area* viewport; // virtual scroll content
|
||||
FScrollbar* vbar;
|
||||
FScrollbar* hbar;
|
||||
|
@ -157,23 +158,23 @@ inline int FScrollView::getViewportHeight() const
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FScrollView::getScrollWidth() const
|
||||
{ return scroll_size.getWidth(); }
|
||||
{ return scroll_geometry.getWidth(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FScrollView::getScrollHeight() const
|
||||
{ return scroll_size.getHeight(); }
|
||||
{ return scroll_geometry.getHeight(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const FPoint FScrollView::getScrollPos() const
|
||||
{ return scroll_offset; }
|
||||
{ return viewport_geometry.getPos(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FScrollView::getScrollX() const
|
||||
{ return scroll_offset.getX(); }
|
||||
{ return viewport_geometry.getX(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FScrollView::getScrollY() const
|
||||
{ return scroll_offset.getY(); }
|
||||
{ return viewport_geometry.getY(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FScrollView::scrollTo (FPoint pos)
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include <map>
|
||||
#include <queue>
|
||||
|
||||
#include "fenum.h"
|
||||
#include "fc.h"
|
||||
#include "fobject.h"
|
||||
#include "foptiattr.h"
|
||||
#include "foptimove.h"
|
||||
|
|
|
@ -264,6 +264,7 @@ void FWidget::setStatusbarMessage (FString msg)
|
|||
bool FWidget::setFocus (bool on)
|
||||
{
|
||||
FWindow* window;
|
||||
FWidget* last_focus;
|
||||
|
||||
if ( ! enable )
|
||||
return false;
|
||||
|
@ -271,13 +272,15 @@ bool FWidget::setFocus (bool on)
|
|||
if ( on == focus )
|
||||
return true;
|
||||
|
||||
last_focus = FWidget::getFocusWidget();
|
||||
|
||||
// set widget focus
|
||||
if ( on && ! focus )
|
||||
{
|
||||
int focusable_children = numOfFocusableChildren();
|
||||
|
||||
if ( FWidget::getFocusWidget() )
|
||||
FWidget::getFocusWidget()->unsetFocus();
|
||||
if ( last_focus )
|
||||
last_focus->unsetFocus();
|
||||
|
||||
if ( (!isDialogWidget() && focusable_children == 0)
|
||||
|| (isDialogWidget() && focusable_children == 1) )
|
||||
|
@ -302,6 +305,12 @@ bool FWidget::setFocus (bool on)
|
|||
window->setWindowFocusWidget(this);
|
||||
}
|
||||
|
||||
if ( hasParent() && last_focus != FWidget::getFocusWidget() )
|
||||
{
|
||||
FFocusEvent cfc (fc::ChildFocusChanged_Event);
|
||||
FApplication::sendEvent(getParentWidget(), &cfc);
|
||||
}
|
||||
|
||||
return focus = (on) ? true : false;
|
||||
}
|
||||
|
||||
|
@ -1995,6 +2004,10 @@ bool FWidget::event (FEvent* ev)
|
|||
onFocusOut ( static_cast<FFocusEvent*>(ev) );
|
||||
break;
|
||||
|
||||
case fc::ChildFocusChanged_Event:
|
||||
onChildFocusChanged ( static_cast<FFocusEvent*>(ev) );
|
||||
break;
|
||||
|
||||
case fc::Accelerator_Event:
|
||||
onAccel ( static_cast<FAccelEvent*>(ev) );
|
||||
break;
|
||||
|
@ -2065,6 +2078,10 @@ void FWidget::onFocusIn (FFocusEvent*)
|
|||
void FWidget::onFocusOut (FFocusEvent*)
|
||||
{ }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FWidget::onChildFocusChanged (FFocusEvent*)
|
||||
{ }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FWidget::onAccel (FAccelEvent*)
|
||||
{ }
|
||||
|
|
|
@ -313,6 +313,7 @@ class FWidget : public FVTerm
|
|||
virtual void onMouseMove (FMouseEvent*);
|
||||
virtual void onFocusIn (FFocusEvent*);
|
||||
virtual void onFocusOut (FFocusEvent*);
|
||||
virtual void onChildFocusChanged (FFocusEvent*);
|
||||
virtual void onAccel (FAccelEvent*);
|
||||
virtual void onResize (FResizeEvent*);
|
||||
virtual void onShow (FShowEvent*);
|
||||
|
|
|
@ -60,7 +60,6 @@ scrollview::scrollview (FWidget* parent)
|
|||
go_north = new FButton(wchar_t(fc::BlackUpPointingTriangle) , this);
|
||||
go_north->setGeometry (1, getScrollHeight() - 2, 5, 1);
|
||||
|
||||
|
||||
if ( isCygwinTerminal() )
|
||||
{
|
||||
go_south->setText ('v');
|
||||
|
|
Loading…
Reference in New Issue