Refactoring FOptiMove::verticalMove and FOptiMove::horizontalMove

This commit is contained in:
Markus Gans 2018-02-10 17:35:09 +01:00
parent c2d7f8b8ee
commit 2af1b1d0d4
8 changed files with 364 additions and 315 deletions

View File

@ -1,3 +1,8 @@
2017-10-02 Markus Gans <guru.mail@muenster.de>
* Refactoring FOptiMove::verticalMove and FOptiMove::horizontalMove
* Refactoring FVTerm::getCharacter
* Refactoring FWidget::drawBorder
2017-02-02 Markus Gans <guru.mail@muenster.de> 2017-02-02 Markus Gans <guru.mail@muenster.de>
* Avoids flickering when redrawing a focused widget * Avoids flickering when redrawing a focused widget

View File

@ -139,7 +139,12 @@ class FOptiMove
int repeatedAppend (const capability&, volatile int, char*); int repeatedAppend (const capability&, volatile int, char*);
int relativeMove (char[], int, int, int, int); int relativeMove (char[], int, int, int, int);
int verticalMove (char[], int, int); int verticalMove (char[], int, int);
void downMove (char[], int&, int, int);
void upMove (char[], int&, int, int);
int horizontalMove (char[], int, int); int horizontalMove (char[], int, int);
void rightMove (char[], int&, int, int);
void leftMove (char[], int&, int, int);
bool isWideMove (int, int, int, int); bool isWideMove (int, int, int, int);
bool isMethod0Faster (int&, int, int); bool isMethod0Faster (int&, int, int);
bool isMethod1Faster (int&, int, int, int, int); bool isMethod1Faster (int&, int, int, int, int);

View File

@ -401,6 +401,8 @@ class FVTerm : public FTerm
static void putAreaLine (char_data*, char_data*, int); static void putAreaLine (char_data*, char_data*, int);
static void putAreaCharacter ( int, int, FVTerm* static void putAreaCharacter ( int, int, FVTerm*
, char_data*, char_data* ); , char_data*, char_data* );
static void getAreaCharacter ( int, int, term_area*
, char_data*& );
static bool clearTerm (int = ' '); static bool clearTerm (int = ' ');
static bool clearFullArea (term_area*, char_data&); static bool clearFullArea (term_area*, char_data&);
static void clearAreaWithShadow (term_area*, char_data&); static void clearAreaWithShadow (term_area*, char_data&);
@ -412,6 +414,7 @@ class FVTerm : public FTerm
static exit_state eraseCharacters (uInt&, uInt, uInt, bool); static exit_state eraseCharacters (uInt&, uInt, uInt, bool);
static exit_state repeatCharacter (uInt&, uInt, uInt); static exit_state repeatCharacter (uInt&, uInt, uInt);
static void cursorWrap(); static void cursorWrap();
bool printWrap (term_area*);
static void updateTerminalLine (uInt); static void updateTerminalLine (uInt);
static bool updateTerminalCursor(); static bool updateTerminalCursor();
static bool isInsideTerminal (int, int); static bool isInsideTerminal (int, int);
@ -436,6 +439,8 @@ class FVTerm : public FTerm
static std::queue<int>* output_buffer; static std::queue<int>* output_buffer;
static char_data term_attribute; static char_data term_attribute;
static char_data next_attribute; static char_data next_attribute;
static char_data s_ch; // shadow character
static char_data i_ch; // inherit background character
static FPoint* term_pos; // terminal cursor position static FPoint* term_pos; // terminal cursor position
static termcap_map* tcap; static termcap_map* tcap;
static bool hidden_cursor; static bool hidden_cursor;
@ -570,24 +575,9 @@ inline void FVTerm::setColor (register short fg, register short bg)
inline void FVTerm::setNormal() inline void FVTerm::setNormal()
{ {
// reset all character attributes // reset all character attributes
next_attribute.attr.bit.bold = \ next_attribute.attr.byte[0] = 0;
next_attribute.attr.bit.dim = \ next_attribute.attr.byte[1] = 0;
next_attribute.attr.bit.italic = \
next_attribute.attr.bit.underline = \
next_attribute.attr.bit.blink = \
next_attribute.attr.bit.reverse = \
next_attribute.attr.bit.standout = \
next_attribute.attr.bit.invisible = \
next_attribute.attr.bit.protect = \
next_attribute.attr.bit.crossed_out = \
next_attribute.attr.bit.dbl_underline = \
next_attribute.attr.bit.alt_charset = \
next_attribute.attr.bit.pc_charset = \
next_attribute.attr.bit.transparent = \
next_attribute.attr.bit.trans_shadow = \
next_attribute.attr.bit.inherit_bg = \
next_attribute.attr.bit.no_changes = false; next_attribute.attr.bit.no_changes = false;
next_attribute.fg_color = fc::Default; next_attribute.fg_color = fc::Default;
next_attribute.bg_color = fc::Default; next_attribute.bg_color = fc::Default;
} }

View File

@ -394,9 +394,9 @@ class FWidget : public FVTerm, public FObject
void drawChildren(); void drawChildren();
void drawTransparentShadow (int, int, int, int); void drawTransparentShadow (int, int, int, int);
void drawBlockShadow (int, int, int, int); void drawBlockShadow (int, int, int, int);
void drawBox (int, int, int, int);
void drawNewFontBox (int, int, int, int);
static void setColorTheme(); static void setColorTheme();
static void set8ColorTheme();
static void set16ColorTheme();
// Data Members // Data Members
bool enable; bool enable;
@ -598,6 +598,7 @@ inline const FRect& FWidget::getGeometryWithShadow()
adjust_wsize.x2_ref() + wshadow.x_ref(), adjust_wsize.x2_ref() + wshadow.x_ref(),
adjust_wsize.y2_ref() + wshadow.y_ref() adjust_wsize.y2_ref() + wshadow.y_ref()
); );
return adjust_wsize_shadow; return adjust_wsize_shadow;
} }
@ -611,6 +612,7 @@ inline const FRect& FWidget::getTermGeometry()
adjust_wsize.x2_ref() + offset.x1_ref(), adjust_wsize.x2_ref() + offset.x1_ref(),
adjust_wsize.y2_ref() + offset.y1_ref() adjust_wsize.y2_ref() + offset.y1_ref()
); );
return adjust_wsize_term; return adjust_wsize_term;
} }
@ -624,6 +626,7 @@ inline const FRect& FWidget::getTermGeometryWithShadow()
adjust_wsize.x2_ref() + offset.x1_ref() + wshadow.x_ref(), adjust_wsize.x2_ref() + offset.x1_ref() + wshadow.x_ref(),
adjust_wsize.y2_ref() + offset.y1_ref() + wshadow.y_ref() adjust_wsize.y2_ref() + offset.y1_ref() + wshadow.y_ref()
); );
return adjust_wsize_term_shadow; return adjust_wsize_term_shadow;
} }

View File

@ -1437,22 +1437,22 @@ inline void FDialog::moveSizeKey (FKeyEvent* ev)
switch ( ev->key() ) switch ( ev->key() )
{ {
case fc::Fkey_up: case fc::Fkey_up:
if ( moveUp(1) ) moveUp(1);
ev->accept(); ev->accept();
break; break;
case fc::Fkey_down: case fc::Fkey_down:
if ( moveDown(1) ) moveDown(1);
ev->accept(); ev->accept();
break; break;
case fc::Fkey_left: case fc::Fkey_left:
if ( moveLeft(1) ) moveLeft(1);
ev->accept(); ev->accept();
break; break;
case fc::Fkey_right: case fc::Fkey_right:
if ( moveRight(1) ) moveRight(1);
ev->accept(); ev->accept();
break; break;

View File

@ -727,6 +727,16 @@ inline int FOptiMove::verticalMove (char move[], int from_y, int to_y)
} }
if ( to_y > from_y ) if ( to_y > from_y )
downMove (move, vtime, from_y, to_y);
else // to_y < from_y
upMove (move, vtime, from_y, to_y);
return vtime;
}
//----------------------------------------------------------------------
inline void FOptiMove::downMove ( char move[], int& vtime
, int from_y, int to_y )
{ {
int num = to_y - from_y; int num = to_y - from_y;
@ -748,7 +758,10 @@ inline int FOptiMove::verticalMove (char move[], int from_y, int to_y)
vtime = repeatedAppend (F_cursor_down, num, move); vtime = repeatedAppend (F_cursor_down, num, move);
} }
} }
else // to_y < from_y
//----------------------------------------------------------------------
inline void FOptiMove::upMove ( char move[], int& vtime
, int from_y, int to_y )
{ {
int num = from_y - to_y; int num = from_y - to_y;
@ -771,17 +784,14 @@ inline int FOptiMove::verticalMove (char move[], int from_y, int to_y)
} }
} }
return vtime;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x) inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
{ {
char str[BUF_SIZE] = {};
int htime = LONG_DURATION; int htime = LONG_DURATION;
if ( F_column_address.cap ) if ( F_column_address.cap )
{ {
// Move to fixed column position1
std::strncat ( hmove std::strncat ( hmove
, tparm(F_column_address.cap, to_x, 0, 0, 0, 0, 0, 0, 0, 0) , tparm(F_column_address.cap, to_x, 0, 0, 0, 0, 0, 0, 0, 0)
, BUF_SIZE - std::strlen(hmove) - 1 ); , BUF_SIZE - std::strlen(hmove) - 1 );
@ -789,14 +799,25 @@ inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
} }
if ( to_x > from_x ) if ( to_x > from_x )
rightMove (hmove, htime, from_x, to_x);
else // to_x < from_x
leftMove (hmove, htime, from_x, to_x);
return htime;
}
//----------------------------------------------------------------------
inline void FOptiMove::rightMove ( char hmove[], int& htime
, int from_x, int to_x )
{ {
char str[BUF_SIZE] = {};
int num = to_x - from_x; int num = to_x - from_x;
if ( F_parm_right_cursor.cap && F_parm_right_cursor.duration < htime ) if ( F_parm_right_cursor.cap && F_parm_right_cursor.duration < htime )
{ {
std::strncat ( hmove std::strncpy ( hmove
, tparm(F_parm_right_cursor.cap, num, 0, 0, 0, 0, 0, 0, 0, 0) , tparm(F_parm_right_cursor.cap, num, 0, 0, 0, 0, 0, 0, 0, 0)
, BUF_SIZE - std::strlen(hmove) - 1 ); , BUF_SIZE - 1 );
htime = F_parm_right_cursor.duration; htime = F_parm_right_cursor.duration;
} }
@ -837,15 +858,19 @@ inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
} }
} }
} }
else // to_x < from_x
//----------------------------------------------------------------------
inline void FOptiMove::leftMove ( char hmove[], int& htime
, int from_x, int to_x )
{ {
char str[BUF_SIZE] = {};
int num = from_x - to_x; int num = from_x - to_x;
if ( F_parm_left_cursor.cap && F_parm_left_cursor.duration < htime ) if ( F_parm_left_cursor.cap && F_parm_left_cursor.duration < htime )
{ {
std::strncat ( hmove std::strncpy ( hmove
, tparm(F_parm_left_cursor.cap, num, 0, 0, 0, 0, 0, 0, 0, 0) , tparm(F_parm_left_cursor.cap, num, 0, 0, 0, 0, 0, 0, 0, 0)
, BUF_SIZE - std::strlen(hmove) - 1 ); , BUF_SIZE - 1 );
htime = F_parm_left_cursor.duration; htime = F_parm_left_cursor.duration;
} }
@ -887,9 +912,6 @@ inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
} }
} }
return htime;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FOptiMove::isWideMove ( int xold, int yold inline bool FOptiMove::isWideMove ( int xold, int yold
, int xnew, int ynew ) , int xnew, int ynew )

View File

@ -48,6 +48,8 @@ FVTerm::termcap_map* FVTerm::tcap = 0;
FTermcap::tcap_map* FTermcap::tcap = 0; FTermcap::tcap_map* FTermcap::tcap = 0;
FVTerm::char_data FVTerm::term_attribute; FVTerm::char_data FVTerm::term_attribute;
FVTerm::char_data FVTerm::next_attribute; FVTerm::char_data FVTerm::next_attribute;
FVTerm::char_data FVTerm::s_ch;
FVTerm::char_data FVTerm::i_ch;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -517,10 +519,6 @@ int FVTerm::print (term_area* area, const std::vector<char_data>& term_string)
while ( iter != term_string.end() ) while ( iter != term_string.end() )
{ {
int width = area->width,
height = area->height,
rsh = area->right_shadow,
bsh = area->bottom_shadow;
bool printable_character = false; bool printable_character = false;
switch ( (*iter).code ) switch ( (*iter).code )
@ -556,26 +554,12 @@ int FVTerm::print (term_area* area, const std::vector<char_data>& term_string)
} }
} }
if ( ! printable_character ) if ( ! printable_character && printWrap(area) )
{ break; // end of area reached
// Line break at right margin
if ( area->cursor_x > width + rsh )
{
area->cursor_x = 1;
area->cursor_y++;
}
// Prevent up scrolling
if ( area->cursor_y > height + bsh )
{
area->cursor_y--;
break;
}
}
len++; len++;
++iter; ++iter;
} // end of while }
return len; return len;
} }
@ -1979,11 +1963,10 @@ FVTerm::char_data FVTerm::getCharacter ( character_type char_type
, FVTerm* obj ) , FVTerm* obj )
{ {
// Gets the overlapped or the covered character for the position (x,y) // Gets the overlapped or the covered character for the position (x,y)
int xx, yy; int xx, yy, layer;
char_data* cc; // covered character char_data* cc; // covered character
char_data s_ch; // shadow character
char_data i_ch; // inherit background character
FWidget* w; FWidget* w;
FWidget::widgetList::const_iterator iter, end;
x--; x--;
y--; y--;
@ -2005,11 +1988,11 @@ FVTerm::char_data FVTerm::getCharacter ( character_type char_type
cc = &vdesktop->text[yy * vdesktop->width + xx]; cc = &vdesktop->text[yy * vdesktop->width + xx];
w = static_cast<FWidget*>(obj); w = static_cast<FWidget*>(obj);
if ( w->window_list && ! w->window_list->empty() ) if ( ! w->window_list || w->window_list->empty() )
{ return *cc;
FWidget::widgetList::const_iterator iter, end;
// Get the window layer of this object // Get the window layer of this object
int layer = FWindow::getWindowLayer(w); layer = FWindow::getWindowLayer(w);
iter = w->window_list->begin(); iter = w->window_list->begin();
end = w->window_list->end(); end = w->window_list->end();
@ -2028,55 +2011,21 @@ FVTerm::char_data FVTerm::getCharacter ( character_type char_type
{ {
term_area* win = (*iter)->getVWin(); term_area* win = (*iter)->getVWin();
if ( ! win ) if ( ! win || ! win->visible )
continue; continue;
if ( ! win->visible ) FRect geometry ( win->offset_left
continue; , win->offset_top
int win_x = win->offset_left;
int win_y = win->offset_top;
FRect geometry ( win_x
, win_y
, win->width + win->right_shadow , win->width + win->right_shadow
, win->height + win->bottom_shadow ); , win->height + win->bottom_shadow );
// Window visible and contains current character // Window visible and contains current character
if ( geometry.contains(x, y) ) if ( geometry.contains(x, y) )
{ getAreaCharacter (x, y, win, cc);
char_data* tmp;
int line_len = win->width + win->right_shadow;
tmp = &win->text[(y - win_y) * line_len + (x - win_x)];
// Current character not transparent
if ( ! tmp->attr.bit.transparent )
{
if ( tmp->attr.bit.trans_shadow ) // transparent shadow
{
// Keep the current vterm character
std::memcpy (&s_ch, cc, sizeof(char_data));
s_ch.fg_color = tmp->fg_color;
s_ch.bg_color = tmp->bg_color;
s_ch.attr.bit.reverse = false;
s_ch.attr.bit.standout = false;
cc = &s_ch;
}
else if ( tmp->attr.bit.inherit_bg )
{
// Add the covered background to this character
std::memcpy (&i_ch, tmp, sizeof(char_data));
i_ch.bg_color = cc->bg_color; // last background color
cc = &i_ch;
}
else // default
cc = tmp;
}
}
} }
else if ( char_type == covered_character ) else if ( char_type == covered_character )
break; break;
} }
}
return *cc; return *cc;
} }
@ -2303,6 +2252,41 @@ void FVTerm::putAreaCharacter ( int x, int y, FVTerm* obj
} }
} }
//----------------------------------------------------------------------
void FVTerm::getAreaCharacter ( int x, int y, term_area* area
, char_data*& cc )
{
char_data* tmp;
int area_x = area->offset_left;
int area_y = area->offset_top;
int line_len = area->width + area->right_shadow;
tmp = &area->text[(y - area_y) * line_len + (x - area_x)];
// Current character not transparent
if ( ! tmp->attr.bit.transparent )
{
if ( tmp->attr.bit.trans_shadow ) // transparent shadow
{
// Keep the current vterm character
std::memcpy (&s_ch, cc, sizeof(char_data));
s_ch.fg_color = tmp->fg_color;
s_ch.bg_color = tmp->bg_color;
s_ch.attr.bit.reverse = false;
s_ch.attr.bit.standout = false;
cc = &s_ch;
}
else if ( tmp->attr.bit.inherit_bg )
{
// Add the covered background to this character
std::memcpy (&i_ch, tmp, sizeof(char_data));
i_ch.bg_color = cc->bg_color; // last background color
cc = &i_ch;
}
else // default
cc = tmp;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FVTerm::clearTerm (int fillchar) bool FVTerm::clearTerm (int fillchar)
{ {
@ -2735,6 +2719,32 @@ void FVTerm::cursorWrap()
} }
} }
//----------------------------------------------------------------------
bool FVTerm::printWrap (term_area* area)
{
bool end_of_area = false;
int width = area->width,
height = area->height,
rsh = area->right_shadow,
bsh = area->bottom_shadow;
// Line break at right margin
if ( area->cursor_x > width + rsh )
{
area->cursor_x = 1;
area->cursor_y++;
}
// Prevent up scrolling
if ( area->cursor_y > height + bsh )
{
area->cursor_y--;
end_of_area = true;
}
return end_of_area;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::updateTerminalLine (uInt y) void FVTerm::updateTerminalLine (uInt y)
{ {

View File

@ -1572,65 +1572,9 @@ void FWidget::drawBorder (int x1, int y1, int x2, int y2)
y2 = getHeight(); y2 = getHeight();
if ( isNewFont() ) if ( isNewFont() )
{ drawNewFontBox (x1, y1, x2, y2);
setPrintPos (x1, y1);
print (fc::NF_border_corner_middle_upper_left); // ┌
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::NF_border_corner_middle_upper_right); // ┐
for (int y = y1 + 1; y <= y2; y++)
{
setPrintPos (x1, y);
print (fc::NF_border_line_left); // border left ⎸
setPrintPos (x2, y);
print (fc::NF_rev_border_line_right); // border right⎹
}
setPrintPos (x1, y2);
print (fc::NF_border_corner_middle_lower_left); // └
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::NF_border_corner_middle_lower_right); // ┘
}
else else
{ drawBox (x1, y1, x2, y2);
setPrintPos (x1, y1);
print (fc::BoxDrawingsDownAndRight); // ┌
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::BoxDrawingsDownAndLeft); // ┐
for (int y = y1 + 1; y < y2; y++)
{
setPrintPos (x1, y);
print (fc::BoxDrawingsVertical); // │
setPrintPos (x2, y);
print (fc::BoxDrawingsVertical); // │
}
setPrintPos (x1, y2);
print (fc::BoxDrawingsUpAndRight); // └
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::BoxDrawingsUpAndLeft); // ┘
for (int x = x1 + 1; x < x2; x++)
{
setPrintPos (x, y1);
print (fc::BoxDrawingsHorizontal); // ─
setPrintPos (x, y2);
print (fc::BoxDrawingsHorizontal); // ─
}
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -2492,9 +2436,79 @@ void FWidget::drawBlockShadow (int x1, int y1, int x2, int y2)
unsetInheritBackground(); unsetInheritBackground();
} }
//----------------------------------------------------------------------
inline void FWidget::drawBox (int x1, int y1, int x2, int y2)
{
// Use box-drawing characters to draw a border
setPrintPos (x1, y1);
print (fc::BoxDrawingsDownAndRight); // ┌
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::BoxDrawingsDownAndLeft); // ┐
for (int y = y1 + 1; y < y2; y++)
{
setPrintPos (x1, y);
print (fc::BoxDrawingsVertical); // │
setPrintPos (x2, y);
print (fc::BoxDrawingsVertical); // │
}
setPrintPos (x1, y2);
print (fc::BoxDrawingsUpAndRight); // └
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::BoxDrawingsUpAndLeft); // ┘
for (int x = x1 + 1; x < x2; x++)
{
setPrintPos (x, y1);
print (fc::BoxDrawingsHorizontal); // ─
setPrintPos (x, y2);
print (fc::BoxDrawingsHorizontal); // ─
}
}
//----------------------------------------------------------------------
inline void FWidget::drawNewFontBox (int x1, int y1, int x2, int y2)
{
// Use new graphical font characters to draw a border
setPrintPos (x1, y1);
print (fc::NF_border_corner_middle_upper_left); // ┌
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::NF_border_corner_middle_upper_right); // ┐
for (int y = y1 + 1; y <= y2; y++)
{
setPrintPos (x1, y);
print (fc::NF_border_line_left); // border left ⎸
setPrintPos (x2, y);
print (fc::NF_rev_border_line_right); // border right⎹
}
setPrintPos (x1, y2);
print (fc::NF_border_corner_middle_lower_left); // └
for (int x = x1 + 1; x < x2; x++)
print (fc::BoxDrawingsHorizontal); // ─
print (fc::NF_border_corner_middle_lower_right); // ┘
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FWidget::setColorTheme() void FWidget::setColorTheme()
{ {
// Sets the default color theme
if ( getMaxColor() < 16 ) // for 8 color mode if ( getMaxColor() < 16 ) // for 8 color mode
{ {
wc.set8ColorTheme(); wc.set8ColorTheme();