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>
* Uses termcap capability U8 to identify terminals that can't display
vt100 line-drawing in UTF-8 mode
* Uses termcap capability U8 to identify terminals that
can't display vt100 line-drawing in UTF-8 mode
2017-01-28 Markus Gans <guru.mail@muenster.de>
* Allow to change the focus out from FScrollView to another widget

View File

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

View File

@ -76,9 +76,19 @@ class FScrollView : public FWidget
virtual void setSize (int, int, bool = true);
void setGeometry (int, int, int, int, bool = true);
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 setVerticalScrollBarMode (fc::scrollBarMode);
// Inquiries
bool hasBorder();
bool isViewportPrint();
// Method
virtual void clearArea (int = ' ');
void scrollToX (int);
@ -138,6 +148,7 @@ class FScrollView : public FWidget
FScrollbar* vbar;
FScrollbar* hbar;
int nf_offset;
bool border;
bool use_own_print_area;
fc::scrollBarMode vMode; // fc:Auto, fc::Hidden or fc::Scroll
fc::scrollBarMode hMode;
@ -178,6 +189,30 @@ inline int FScrollView::getScrollX() const
inline int FScrollView::getScrollY() const
{ 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)
{ 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)
{
@ -255,6 +241,42 @@ void FVTerm::updateTerminal()
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, ...)
{
@ -690,26 +712,7 @@ void FVTerm::createArea ( int offset_top, int offset_left
// initialize virtual window
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->pre_proc_instance = 0;
area->pre_proc = 0;
resizeArea (offset_top, offset_left, width, height, rsw, bsh, area);
}
@ -1064,12 +1067,24 @@ void FVTerm::updateVTerm()
updateVTerm(win);
win->has_changes = false;
}
else if ( win->pre_proc_instance
&& win->pre_proc_instance->child_print_area
&& win->pre_proc_instance->child_print_area->has_changes )
else if ( ! win->preprocessing_call.empty() )
{
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);
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;
// Call preprocessing handler
if ( area->pre_proc_instance && area->pre_proc )
(area->pre_proc_instance->*area->pre_proc)();
if ( ! area->preprocessing_call.empty() )
{
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;
ay = area->offset_left;

View File

@ -58,8 +58,39 @@ class FVTerm : public FObject, public FTerm
typedef FOptiAttr::char_data char_data;
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_left; // Distance from left terminal side
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_y; // Y-position input cursor
FWidget* widget; // Widget that owns this term_area
FVTerm* pre_proc_instance;
FPreprocessingHandler pre_proc;
FPreprocessing preprocessing_call;
line_changes* changes;
char_data* text; // Text data for the output
bool input_cursor_visible;
bool has_changes;
bool visible;
} term_area;
};
enum covered_state
{
@ -177,9 +207,6 @@ class FVTerm : public FObject, public FTerm
static bool setInheritBackground();
static bool unsetInheritBackground();
void setPreprocessingHandler ( FVTerm*
, FPreprocessingHandler );
// Inquiries
static bool isCursorHidden();
static bool isBold();
@ -208,6 +235,9 @@ class FVTerm : public FObject, public FTerm
static void putVTerm();
static void updateTerminal (bool);
static void updateTerminal();
void addPreprocessingHandler ( FVTerm*
, FPreprocessingHandler );
void delPreprocessingHandler (FVTerm*);
int printf (const wchar_t*, ...);
int printf (const char*, ...)

View File

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

View File

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

View File

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