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>
* Avoids flickering when redrawing a focused widget

View File

@ -139,7 +139,12 @@ class FOptiMove
int repeatedAppend (const capability&, volatile int, char*);
int relativeMove (char[], int, int, int, int);
int verticalMove (char[], int, int);
void downMove (char[], int&, int, int);
void upMove (char[], int&, 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 isMethod0Faster (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 putAreaCharacter ( int, int, FVTerm*
, char_data*, char_data* );
static void getAreaCharacter ( int, int, term_area*
, char_data*& );
static bool clearTerm (int = ' ');
static bool clearFullArea (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 repeatCharacter (uInt&, uInt, uInt);
static void cursorWrap();
bool printWrap (term_area*);
static void updateTerminalLine (uInt);
static bool updateTerminalCursor();
static bool isInsideTerminal (int, int);
@ -436,6 +439,8 @@ class FVTerm : public FTerm
static std::queue<int>* output_buffer;
static char_data term_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 termcap_map* tcap;
static bool hidden_cursor;
@ -570,24 +575,9 @@ inline void FVTerm::setColor (register short fg, register short bg)
inline void FVTerm::setNormal()
{
// reset all character attributes
next_attribute.attr.bit.bold = \
next_attribute.attr.bit.dim = \
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.byte[0] = 0;
next_attribute.attr.byte[1] = 0;
next_attribute.attr.bit.no_changes = false;
next_attribute.fg_color = fc::Default;
next_attribute.bg_color = fc::Default;
}

View File

@ -394,9 +394,9 @@ class FWidget : public FVTerm, public FObject
void drawChildren();
void drawTransparentShadow (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 set8ColorTheme();
static void set16ColorTheme();
// Data Members
bool enable;
@ -598,6 +598,7 @@ inline const FRect& FWidget::getGeometryWithShadow()
adjust_wsize.x2_ref() + wshadow.x_ref(),
adjust_wsize.y2_ref() + wshadow.y_ref()
);
return adjust_wsize_shadow;
}
@ -611,6 +612,7 @@ inline const FRect& FWidget::getTermGeometry()
adjust_wsize.x2_ref() + offset.x1_ref(),
adjust_wsize.y2_ref() + offset.y1_ref()
);
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.y2_ref() + offset.y1_ref() + wshadow.y_ref()
);
return adjust_wsize_term_shadow;
}

View File

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

View File

@ -727,7 +727,17 @@ inline int FOptiMove::verticalMove (char move[], int from_y, int to_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;
if ( F_parm_down_cursor.cap && F_parm_down_cursor.duration < vtime )
@ -747,9 +757,12 @@ inline int FOptiMove::verticalMove (char move[], int from_y, int to_y)
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;
if ( F_parm_up_cursor.cap && F_parm_up_cursor.duration < vtime )
@ -769,19 +782,16 @@ inline int FOptiMove::verticalMove (char move[], int from_y, int to_y)
vtime = repeatedAppend (F_cursor_up, num, move);
}
}
return vtime;
}
//----------------------------------------------------------------------
inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
{
char str[BUF_SIZE] = {};
int htime = LONG_DURATION;
if ( F_column_address.cap )
{
// Move to fixed column position1
std::strncat ( hmove
, tparm(F_column_address.cap, to_x, 0, 0, 0, 0, 0, 0, 0, 0)
, 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 )
{
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;
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)
, BUF_SIZE - std::strlen(hmove) - 1 );
, BUF_SIZE - 1 );
htime = F_parm_right_cursor.duration;
}
@ -836,16 +857,20 @@ inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
htime = htime_r;
}
}
}
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;
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)
, BUF_SIZE - std::strlen(hmove) - 1 );
, BUF_SIZE - 1 );
htime = F_parm_left_cursor.duration;
}
@ -885,9 +910,6 @@ inline int FOptiMove::horizontalMove (char hmove[], int from_x, int to_x)
htime = htime_l;
}
}
}
return htime;
}
//----------------------------------------------------------------------

View File

@ -48,6 +48,8 @@ FVTerm::termcap_map* FVTerm::tcap = 0;
FTermcap::tcap_map* FTermcap::tcap = 0;
FVTerm::char_data FVTerm::term_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() )
{
int width = area->width,
height = area->height,
rsh = area->right_shadow,
bsh = area->bottom_shadow;
bool printable_character = false;
switch ( (*iter).code )
@ -556,26 +554,12 @@ int FVTerm::print (term_area* area, const std::vector<char_data>& term_string)
}
}
if ( ! printable_character )
{
// 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;
}
}
if ( ! printable_character && printWrap(area) )
break; // end of area reached
len++;
++iter;
} // end of while
}
return len;
}
@ -1979,11 +1963,10 @@ FVTerm::char_data FVTerm::getCharacter ( character_type char_type
, FVTerm* obj )
{
// 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 s_ch; // shadow character
char_data i_ch; // inherit background character
FWidget* w;
FWidget::widgetList::const_iterator iter, end;
x--;
y--;
@ -2005,11 +1988,11 @@ FVTerm::char_data FVTerm::getCharacter ( character_type char_type
cc = &vdesktop->text[yy * vdesktop->width + xx];
w = static_cast<FWidget*>(obj);
if ( w->window_list && ! w->window_list->empty() )
{
FWidget::widgetList::const_iterator iter, end;
if ( ! w->window_list || w->window_list->empty() )
return *cc;
// Get the window layer of this object
int layer = FWindow::getWindowLayer(w);
layer = FWindow::getWindowLayer(w);
iter = w->window_list->begin();
end = w->window_list->end();
@ -2028,55 +2011,21 @@ FVTerm::char_data FVTerm::getCharacter ( character_type char_type
{
term_area* win = (*iter)->getVWin();
if ( ! win )
if ( ! win || ! win->visible )
continue;
if ( ! win->visible )
continue;
int win_x = win->offset_left;
int win_y = win->offset_top;
FRect geometry ( win_x
, win_y
FRect geometry ( win->offset_left
, win->offset_top
, win->width + win->right_shadow
, win->height + win->bottom_shadow );
// Window visible and contains current character
if ( geometry.contains(x, y) )
{
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;
}
}
getAreaCharacter (x, y, win, cc);
}
else if ( char_type == covered_character )
break;
}
}
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)
{
@ -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)
{

View File

@ -1572,65 +1572,9 @@ void FWidget::drawBorder (int x1, int y1, int x2, int y2)
y2 = getHeight();
if ( isNewFont() )
{
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); // ┘
}
drawNewFontBox (x1, y1, x2, y2);
else
{
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); // ─
}
}
drawBox (x1, y1, x2, y2);
}
//----------------------------------------------------------------------
@ -2492,9 +2436,79 @@ void FWidget::drawBlockShadow (int x1, int y1, int x2, int y2)
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()
{
// Sets the default color theme
if ( getMaxColor() < 16 ) // for 8 color mode
{
wc.set8ColorTheme();