Allows a window to have more than one FScrollView widget

This commit is contained in:
Markus Gans 2017-02-18 23:37:10 +01:00
parent 09021d9c0a
commit 3f8ed6e78e
8 changed files with 192 additions and 70 deletions

View File

@ -1,6 +1,9 @@
2017-02-18 Markus Gans <guru.mail@muenster.de>
* Allows a window to have more than one FScrollView widget
2017-02-07 Markus Gans <guru.mail@muenster.de> 2017-02-07 Markus Gans <guru.mail@muenster.de>
* Uses termcap capability U8 to identify terminals that can't display * Uses termcap capability U8 to identify terminals that
vt100 line-drawing in UTF-8 mode can't display vt100 line-drawing in UTF-8 mode
2017-01-28 Markus Gans <guru.mail@muenster.de> 2017-01-28 Markus Gans <guru.mail@muenster.de>
* Allow to change the focus out from FScrollView to another widget * Allow to change the focus out from FScrollView to another widget

View File

@ -18,6 +18,7 @@ FScrollView::FScrollView (FWidget* parent)
, vbar(0) , vbar(0)
, hbar(0) , hbar(0)
, nf_offset(0) , nf_offset(0)
, border(true)
, use_own_print_area(false) , use_own_print_area(false)
, vMode(fc::Auto) , vMode(fc::Auto)
, hMode(fc::Auto) , hMode(fc::Auto)
@ -50,7 +51,8 @@ void FScrollView::setScrollWidth (int width)
FPoint no_shadow(0,0); FPoint no_shadow(0,0);
scroll_geometry.setWidth (width); scroll_geometry.setWidth (width);
resizeArea (scroll_geometry, no_shadow, viewport); resizeArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler
addPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
); );
@ -77,7 +79,7 @@ void FScrollView::setScrollHeight (int height)
FPoint no_shadow(0,0); FPoint no_shadow(0,0);
scroll_geometry.setHeight (height); scroll_geometry.setHeight (height);
resizeArea (scroll_geometry, no_shadow, viewport); resizeArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler addPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
); );
@ -107,7 +109,7 @@ void FScrollView::setScrollSize (int width, int height)
FPoint no_shadow(0,0); FPoint no_shadow(0,0);
scroll_geometry.setSize (width, height); scroll_geometry.setSize (width, height);
resizeArea (scroll_geometry, no_shadow, viewport); resizeArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler addPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
); );
@ -242,6 +244,18 @@ void FScrollView::setPrintPos (register int x, register int y)
FWidget::setPrintPos (x + getLeftPadding(), y + getTopPadding()); FWidget::setPrintPos (x + getLeftPadding(), y + getTopPadding());
} }
//----------------------------------------------------------------------
bool FScrollView::setViewportPrint (bool on)
{
return use_own_print_area = ! on;
}
//----------------------------------------------------------------------
bool FScrollView::setBorder (bool on)
{
return border = on;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::setHorizontalScrollBarMode (fc::scrollBarMode mode) void FScrollView::setHorizontalScrollBarMode (fc::scrollBarMode mode)
{ {
@ -325,7 +339,7 @@ void FScrollView::scrollBy (int dx, int dy)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollView::draw() void FScrollView::draw()
{ {
use_own_print_area = true; unsetViewportPrint();
if ( isMonochron() ) if ( isMonochron() )
setReverse(true); setReverse(true);
@ -335,15 +349,18 @@ void FScrollView::draw()
else else
setColor(); setColor();
if ( border )
{
if ( isNewFont() ) if ( isNewFont() )
drawBorder (1, 1, getWidth() - 1, getHeight()); drawBorder (1, 1, getWidth() - 1, getHeight());
else else
drawBorder(); drawBorder();
}
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
use_own_print_area = false; setViewportPrint();
copy2area(); copy2area();
redrawVBar(); redrawVBar();
redrawHBar(); redrawHBar();
@ -737,7 +754,7 @@ void FScrollView::init()
scroll_geometry.setRect (0, 0, w, h); scroll_geometry.setRect (0, 0, w, h);
createArea (scroll_geometry, no_shadow, viewport); createArea (scroll_geometry, no_shadow, viewport);
setPreprocessingHandler addPreprocessingHandler
( (
_PREPROC_HANDLER (this, &FScrollView::copy2area) _PREPROC_HANDLER (this, &FScrollView::copy2area)
); );

View File

@ -76,9 +76,19 @@ class FScrollView : public FWidget
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 setPrintPos (register int, register int); void setPrintPos (register int, register int);
bool setViewportPrint (bool);
bool setViewportPrint();
bool unsetViewportPrint();
bool setBorder (bool);
bool setBorder();
bool unsetBorder();
void setHorizontalScrollBarMode (fc::scrollBarMode); void setHorizontalScrollBarMode (fc::scrollBarMode);
void setVerticalScrollBarMode (fc::scrollBarMode); void setVerticalScrollBarMode (fc::scrollBarMode);
// Inquiries
bool hasBorder();
bool isViewportPrint();
// Method // Method
virtual void clearArea (int = ' '); virtual void clearArea (int = ' ');
void scrollToX (int); void scrollToX (int);
@ -138,6 +148,7 @@ class FScrollView : public FWidget
FScrollbar* vbar; FScrollbar* vbar;
FScrollbar* hbar; FScrollbar* hbar;
int nf_offset; int nf_offset;
bool border;
bool use_own_print_area; bool use_own_print_area;
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;
@ -178,6 +189,30 @@ inline int FScrollView::getScrollX() const
inline int FScrollView::getScrollY() const inline int FScrollView::getScrollY() const
{ return viewport_geometry.getY(); } { return viewport_geometry.getY(); }
//----------------------------------------------------------------------
inline bool FScrollView::setViewportPrint()
{ return setViewportPrint(true); }
//----------------------------------------------------------------------
inline bool FScrollView::unsetViewportPrint()
{ return setViewportPrint(false); }
//----------------------------------------------------------------------
inline bool FScrollView::setBorder()
{ return setBorder(true); }
//----------------------------------------------------------------------
inline bool FScrollView::unsetBorder()
{ return setBorder(false); }
//----------------------------------------------------------------------
inline bool FScrollView::hasBorder()
{ return border; }
//----------------------------------------------------------------------
inline bool FScrollView::isViewportPrint()
{ return ! use_own_print_area; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FScrollView::scrollTo (FPoint pos) inline void FScrollView::scrollTo (FPoint pos)
{ scrollTo(pos.getX(), pos.getY()); } { scrollTo(pos.getX(), pos.getY()); }

View File

@ -155,20 +155,6 @@ void FVTerm::setPrintCursor (register int x, register int y)
} }
} }
//----------------------------------------------------------------------
void FVTerm::setPreprocessingHandler ( FVTerm* instance
, FPreprocessingHandler handler )
{
if ( ! print_area )
FVTerm::getPrintArea();
if ( print_area )
{
print_area->pre_proc_instance = instance;
print_area->pre_proc = handler;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::clearArea (int fillchar) void FVTerm::clearArea (int fillchar)
{ {
@ -255,6 +241,42 @@ void FVTerm::updateTerminal()
updateTerminalCursor(); updateTerminalCursor();
} }
//----------------------------------------------------------------------
void FVTerm::addPreprocessingHandler ( FVTerm* instance
, FPreprocessingHandler handler )
{
if ( ! print_area )
FVTerm::getPrintArea();
if ( print_area )
{
vterm_preprocessing obj = { instance, handler };
delPreprocessingHandler (instance);
print_area->preprocessing_call.push_back(obj);
}
}
//----------------------------------------------------------------------
void FVTerm::delPreprocessingHandler (FVTerm* instance)
{
if ( ! print_area )
FVTerm::getPrintArea();
if ( ! print_area || ! print_area->preprocessing_call.empty() )
return;
FPreprocessing::iterator iter, end;
iter = print_area->preprocessing_call.begin();
while ( iter != print_area->preprocessing_call.end() )
{
if ( iter->instance == instance )
iter = print_area->preprocessing_call.erase(iter);
else
++iter;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FVTerm::printf (const wchar_t* format, ...) int FVTerm::printf (const wchar_t* format, ...)
{ {
@ -690,26 +712,7 @@ void FVTerm::createArea ( int offset_top, int offset_left
// initialize virtual window // initialize virtual window
area = new term_area; area = new term_area;
area->offset_top = 0;
area->offset_left = 0;
area->width = -1;
area->height = -1;
area->right_shadow = 0;
area->bottom_shadow = 0;
area->cursor_x = 0;
area->cursor_y = 0;
area->input_cursor_x = -1;
area->input_cursor_y = -1;
area->input_cursor_visible = false;
area->has_changes = false;
area->changes = 0;
area->text = 0;
area->visible = false;
area->widget = static_cast<FWidget*>(this); area->widget = static_cast<FWidget*>(this);
area->pre_proc_instance = 0;
area->pre_proc = 0;
resizeArea (offset_top, offset_left, width, height, rsw, bsh, area); resizeArea (offset_top, offset_left, width, height, rsw, bsh, area);
} }
@ -1064,12 +1067,24 @@ void FVTerm::updateVTerm()
updateVTerm(win); updateVTerm(win);
win->has_changes = false; win->has_changes = false;
} }
else if ( win->pre_proc_instance else if ( ! win->preprocessing_call.empty() )
&& win->pre_proc_instance->child_print_area {
&& win->pre_proc_instance->child_print_area->has_changes ) FPreprocessing::const_iterator iter, end;
iter = win->preprocessing_call.begin();
end = win->preprocessing_call.end();
while ( iter != end )
{
if ( iter->instance->child_print_area
&& iter->instance->child_print_area->has_changes )
{ {
updateVTerm(win); updateVTerm(win);
win->pre_proc_instance->child_print_area->has_changes = false; iter->instance->child_print_area->has_changes = false;
break;
}
++iter;
}
} }
} }
} }
@ -1090,8 +1105,20 @@ void FVTerm::updateVTerm (term_area* area)
return; return;
// Call preprocessing handler // Call preprocessing handler
if ( area->pre_proc_instance && area->pre_proc ) if ( ! area->preprocessing_call.empty() )
(area->pre_proc_instance->*area->pre_proc)(); {
FPreprocessing::const_iterator iter, end;
iter = area->preprocessing_call.begin();
end = area->preprocessing_call.end();
while ( iter != end )
{
FPreprocessingHandler handler = iter->handler;
// call the preprocessing handler
(iter->instance->*handler)();
++iter;
}
}
ax = area->offset_top; ax = area->offset_top;
ay = area->offset_left; ay = area->offset_left;

View File

@ -58,8 +58,39 @@ class FVTerm : public FObject, public FTerm
typedef FOptiAttr::char_data char_data; typedef FOptiAttr::char_data char_data;
typedef void (FVTerm::*FPreprocessingHandler)(); typedef void (FVTerm::*FPreprocessingHandler)();
typedef struct struct vterm_preprocessing
{ {
FVTerm* instance;
FPreprocessingHandler handler;
};
typedef std::vector<vterm_preprocessing> FPreprocessing;
struct term_area
{
term_area()
: offset_top (0)
, offset_left (0)
, width (-1)
, height (-1)
, right_shadow (0)
, bottom_shadow (0)
, cursor_x (0)
, cursor_y (0)
, input_cursor_x (-1)
, input_cursor_y (-1)
, widget()
, preprocessing_call()
, changes (0)
, text (0)
, input_cursor_visible (false)
, has_changes (false)
, visible (false)
{ }
~term_area()
{ }
int offset_top; // Distance from top of the terminal int offset_top; // Distance from top of the terminal
int offset_left; // Distance from left terminal side int offset_left; // Distance from left terminal side
int width; // Window width int width; // Window width
@ -71,14 +102,13 @@ class FVTerm : public FObject, public FTerm
int input_cursor_x; // X-position input cursor int input_cursor_x; // X-position input cursor
int input_cursor_y; // Y-position input cursor int input_cursor_y; // Y-position input cursor
FWidget* widget; // Widget that owns this term_area FWidget* widget; // Widget that owns this term_area
FVTerm* pre_proc_instance; FPreprocessing preprocessing_call;
FPreprocessingHandler pre_proc;
line_changes* changes; line_changes* changes;
char_data* text; // Text data for the output char_data* text; // Text data for the output
bool input_cursor_visible; bool input_cursor_visible;
bool has_changes; bool has_changes;
bool visible; bool visible;
} term_area; };
enum covered_state enum covered_state
{ {
@ -177,9 +207,6 @@ class FVTerm : public FObject, public FTerm
static bool setInheritBackground(); static bool setInheritBackground();
static bool unsetInheritBackground(); static bool unsetInheritBackground();
void setPreprocessingHandler ( FVTerm*
, FPreprocessingHandler );
// Inquiries // Inquiries
static bool isCursorHidden(); static bool isCursorHidden();
static bool isBold(); static bool isBold();
@ -208,6 +235,9 @@ class FVTerm : public FObject, public FTerm
static void putVTerm(); static void putVTerm();
static void updateTerminal (bool); static void updateTerminal (bool);
static void updateTerminal(); static void updateTerminal();
void addPreprocessingHandler ( FVTerm*
, FPreprocessingHandler );
void delPreprocessingHandler (FVTerm*);
int printf (const wchar_t*, ...); int printf (const wchar_t*, ...);
int printf (const char*, ...) int printf (const char*, ...)

View File

@ -865,7 +865,7 @@ bool FWidget::close()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::addCallback ( FString cb_signal void FWidget::addCallback ( FString cb_signal
, FWidget::FCallback cb_handler , FCallback cb_handler
, data_ptr data ) , data_ptr data )
{ {
// add a (normal) function pointer as callback // add a (normal) function pointer as callback
@ -876,7 +876,7 @@ void FWidget::addCallback ( FString cb_signal
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::addCallback ( FString cb_signal void FWidget::addCallback ( FString cb_signal
, FWidget* cb_instance , FWidget* cb_instance
, FWidget::FMemberCallback cb_handler , FMemberCallback cb_handler
, data_ptr data ) , data_ptr data )
{ {
// add a member function pointer as callback // add a member function pointer as callback
@ -885,11 +885,12 @@ void FWidget::addCallback ( FString cb_signal
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::delCallback (FWidget::FCallback cb_handler) void FWidget::delCallback (FCallback cb_handler)
{ {
FWidget::CallbackObjects::iterator iter;
// delete a cb_handler function pointer // delete a cb_handler function pointer
CallbackObjects::iterator iter;
if ( callback_objects.empty() ) if ( callback_objects.empty() )
return; return;
@ -907,9 +908,10 @@ void FWidget::delCallback (FWidget::FCallback cb_handler)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::delCallback (FWidget* cb_instance) void FWidget::delCallback (FWidget* cb_instance)
{ {
// delete all member function pointer from cb_instance
FWidget::MemberCallbackObjects::iterator iter; FWidget::MemberCallbackObjects::iterator iter;
// delete all member function pointer from cb_instance
if ( member_callback_objects.empty() ) if ( member_callback_objects.empty() )
return; return;
@ -939,7 +941,7 @@ void FWidget::emitCallback (FString emit_signal)
// member function pointer // member function pointer
if ( ! member_callback_objects.empty() ) if ( ! member_callback_objects.empty() )
{ {
FWidget::MemberCallbackObjects::const_iterator m_iter, m_end; MemberCallbackObjects::const_iterator m_iter, m_end;
m_iter = member_callback_objects.begin(); m_iter = member_callback_objects.begin();
m_end = member_callback_objects.end(); m_end = member_callback_objects.end();
@ -959,7 +961,7 @@ void FWidget::emitCallback (FString emit_signal)
// function pointer // function pointer
if ( ! callback_objects.empty() ) if ( ! callback_objects.empty() )
{ {
FWidget::CallbackObjects::const_iterator iter, end; CallbackObjects::const_iterator iter, end;
iter = callback_objects.begin(); iter = callback_objects.begin();
end = callback_objects.end(); end = callback_objects.end();

View File

@ -453,18 +453,22 @@ class FWidget : public FVTerm
, max_width (INT_MAX) , max_width (INT_MAX)
, max_height (INT_MAX) , max_height (INT_MAX)
{ } { }
~widget_size_hints() ~widget_size_hints()
{ } { }
void setMinimum (int w, int h) void setMinimum (int w, int h)
{ {
min_width = w; min_width = w;
min_height = h; min_height = h;
} }
void setMaximum (int w, int h) void setMaximum (int w, int h)
{ {
max_width = w; max_width = w;
max_height = h; max_height = h;
} }
int min_width; int min_width;
int min_height; int min_height;
int max_width; int max_width;
@ -475,8 +479,10 @@ class FWidget : public FVTerm
{ {
dbl_line_mask() : top(), right(), bottom(), left() dbl_line_mask() : top(), right(), bottom(), left()
{ } { }
~dbl_line_mask() ~dbl_line_mask()
{ } { }
std::vector<bool> top; std::vector<bool> top;
std::vector<bool> right; std::vector<bool> right;
std::vector<bool> bottom; std::vector<bool> bottom;
@ -487,8 +493,10 @@ class FWidget : public FVTerm
{ {
widget_padding() : top(0), left(0), bottom(0), right(0) widget_padding() : top(0), left(0), bottom(0), right(0)
{ } { }
~widget_padding() ~widget_padding()
{ } { }
int top; int top;
int left; int left;
int bottom; int bottom;

View File

@ -78,7 +78,7 @@ int main (int argc, char* argv[])
// Create radio buttons // Create radio buttons
FRadioButton* male = new FRadioButton("&Male", radioButtonGroup); FRadioButton* male = new FRadioButton("&Male", radioButtonGroup);
FRadioButton* female = new FRadioButton("&Female",radioButtonGroup); FRadioButton* female = new FRadioButton("&Female", radioButtonGroup);
male->setGeometry(1, 1, 7, 1); male->setGeometry(1, 1, 7, 1);
female->setGeometry(1, 2, 7, 1); female->setGeometry(1, 2, 7, 1);