Refactoring of some functions

This commit is contained in:
Markus Gans 2018-02-08 00:25:51 +01:00
parent d1083b6a95
commit c2d7f8b8ee
4 changed files with 208 additions and 161 deletions

View File

@ -3,7 +3,7 @@
* * * *
* This file is part of the Final Cut widget toolkit * * This file is part of the Final Cut widget toolkit *
* * * *
* Copyright 2012-2017 Markus Gans * * Copyright 2012-2018 Markus Gans *
* * * *
* The Final Cut is free software; you can redistribute it and/or * * The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License * * modify it under the terms of the GNU Lesser General Public License *
@ -130,6 +130,8 @@ class FScrollbar : public FWidget
void draw(); void draw();
void drawButtons(); void drawButtons();
sType getClickedScrollType (int, int); sType getClickedScrollType (int, int);
sType getVerticalClickedScrollType (int);
sType getHorizontalClickedScrollType (int);
void processMiddleButton (int, int); void processMiddleButton (int, int);
void processScroll(); void processScroll();

View File

@ -398,7 +398,12 @@ class FVTerm : public FTerm
// Methods // Methods
void init(); void init();
void finish(); void finish();
static void putAreaLine (char_data*, char_data*, int);
static void putAreaCharacter ( int, int, FVTerm*
, char_data*, char_data* );
static bool clearTerm (int = ' '); static bool clearTerm (int = ' ');
static bool clearFullArea (term_area*, char_data&);
static void clearAreaWithShadow (term_area*, char_data&);
static bool canClearToEOL (uInt, uInt); static bool canClearToEOL (uInt, uInt);
static bool canClearLeadingWS (uInt&, uInt); static bool canClearLeadingWS (uInt&, uInt);
static bool canClearTrailingWS (uInt&, uInt); static bool canClearTrailingWS (uInt&, uInt);

View File

@ -3,7 +3,7 @@
* * * *
* This file is part of the Final Cut widget toolkit * * This file is part of the Final Cut widget toolkit *
* * * *
* Copyright 2012-2017 Markus Gans * * Copyright 2012-2018 Markus Gans *
* * * *
* The Final Cut is free software; you can redistribute it and/or * * The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License * * modify it under the terms of the GNU Lesser General Public License *
@ -651,76 +651,84 @@ void FScrollbar::drawButtons()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y) FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y)
{ {
FScrollbar::sType stype;
if ( bar_orientation == fc::vertical ) if ( bar_orientation == fc::vertical )
{ {
if ( y == 1 ) return getVerticalClickedScrollType(y);
{
stype = FScrollbar::scrollStepBackward; // decrement button
}
else if ( y > 1 && y <= slider_pos + 1 )
{
stype = FScrollbar::scrollPageBackward; // before slider
}
else if ( y > slider_pos + slider_length + 1 && y < getHeight() )
{
stype = FScrollbar::scrollPageForward; // after slider
}
else if ( y == getHeight() )
{
stype = FScrollbar::scrollStepForward; // increment button
}
else
stype = FScrollbar::noScroll;
} }
else // horizontal else // horizontal
{ {
if ( isNewFont() ) return getHorizontalClickedScrollType(x);
{ }
if ( x == 1 || x == 2 ) }
{
stype = FScrollbar::scrollStepBackward; // decrement button //----------------------------------------------------------------------
} FScrollbar::sType FScrollbar::getVerticalClickedScrollType (int y)
else if ( x > 2 && x <= slider_pos + 2 ) {
{ if ( y == 1 )
stype = FScrollbar::scrollPageBackward; // before slider {
} return FScrollbar::scrollStepBackward; // decrement button
else if ( x > slider_pos + slider_length + 2 && x < getWidth() - 1 ) }
{ else if ( y > 1 && y <= slider_pos + 1 )
stype = FScrollbar::scrollPageForward; // after slider {
} return FScrollbar::scrollPageBackward; // before slider
else if ( x == getWidth() - 1 || x == getWidth() ) }
{ else if ( y > slider_pos + slider_length + 1 && y < getHeight() )
stype = FScrollbar::scrollStepForward; // increment button {
} return FScrollbar::scrollPageForward; // after slider
else }
stype = FScrollbar::noScroll; else if ( y == getHeight() )
} {
else return FScrollbar::scrollStepForward; // increment button
{
if ( x == 1 )
{
stype = FScrollbar::scrollStepBackward; // decrement button
}
else if ( x > 1 && x <= slider_pos + 1 )
{
stype = FScrollbar::scrollPageBackward; // before slider
}
else if ( x > slider_pos + slider_length + 1 && x < getWidth() )
{
stype = FScrollbar::scrollPageForward; // after slider
}
else if ( x == getWidth() )
{
stype = FScrollbar::scrollStepForward; // increment button
}
else
stype = FScrollbar::noScroll;
}
} }
return stype; return FScrollbar::noScroll;
}
//----------------------------------------------------------------------
FScrollbar::sType FScrollbar::getHorizontalClickedScrollType (int x)
{
if ( isNewFont() )
{
if ( x == 1 || x == 2 )
{
return FScrollbar::scrollStepBackward; // decrement button
}
else if ( x > 2 && x <= slider_pos + 2 )
{
return FScrollbar::scrollPageBackward; // before slider
}
else if ( x > slider_pos + slider_length + 2 && x < getWidth() - 1 )
{
return FScrollbar::scrollPageForward; // after slider
}
else if ( x == getWidth() - 1 || x == getWidth() )
{
return FScrollbar::scrollStepForward; // increment button
}
return FScrollbar::noScroll;
}
else
{
if ( x == 1 )
{
return FScrollbar::scrollStepBackward; // decrement button
}
else if ( x > 1 && x <= slider_pos + 1 )
{
return FScrollbar::scrollPageBackward; // before slider
}
else if ( x > slider_pos + slider_length + 1 && x < getWidth() )
{
return FScrollbar::scrollPageForward; // after slider
}
else if ( x == getWidth() )
{
return FScrollbar::scrollStepForward; // increment button
}
return FScrollbar::noScroll;
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -1620,6 +1620,7 @@ void FVTerm::getArea (int x, int y, int w, int h, term_area* area)
void FVTerm::putArea (const FPoint& pos, term_area* area) void FVTerm::putArea (const FPoint& pos, term_area* area)
{ {
// Copies the given area block to the virtual terminal position // Copies the given area block to the virtual terminal position
if ( ! area ) if ( ! area )
return; return;
@ -1680,59 +1681,20 @@ void FVTerm::putArea (int ax, int ay, term_area* area)
if ( area->changes[y].trans_count == 0 ) if ( area->changes[y].trans_count == 0 )
{ {
// Line has only covered characters // Line has only covered characters
tc = &vterm->text[(ay + y) * vterm->width + ax];
ac = &area->text[y * line_len + ol]; ac = &area->text[y * line_len + ol];
std::memcpy (tc, ac, sizeof(char_data) * unsigned(length)); tc = &vterm->text[(ay + y) * vterm->width + ax];
putAreaLine (ac, tc, length);
} }
else else
{ {
// Line has one or more transparent characters // Line has one or more transparent characters
for (register int x = 0; x < length; x++) // column loop for (register int x = 0; x < length; x++) // column loop
{ {
tc = &vterm->text[(ay + y) * vterm->width + (ax + x)]; int cx = ax + x;
int cy = ay + y;
ac = &area->text[y * line_len + ol + x]; ac = &area->text[y * line_len + ol + x];
tc = &vterm->text[cy * vterm->width + cx];
if ( ac->attr.bit.transparent ) // transparent putAreaCharacter (cx + 1, cy + 1, area->widget, ac, tc);
{
// restore one character on vterm
char_data ch;
ch = getCoveredCharacter (ax + x + 1, ay + y + 1, area->widget);
std::memcpy (tc, &ch, sizeof(char_data));
}
else // not transparent
{
if ( ac->attr.bit.trans_shadow ) // transparent shadow
{
// get covered character + add the current color
char_data ch;
ch = getCoveredCharacter (ax + x + 1, ay + y + 1, area->widget);
ch.fg_color = ac->fg_color;
ch.bg_color = ac->bg_color;
ch.attr.bit.reverse = false;
ch.attr.bit.standout = false;
if ( ch.code == fc::LowerHalfBlock
|| ch.code == fc::UpperHalfBlock
|| ch.code == fc::LeftHalfBlock
|| ch.code == fc::RightHalfBlock
|| ch.code == fc::MediumShade
|| ch.code == fc::FullBlock )
ch.code = ' ';
std::memcpy (tc, &ch, sizeof(char_data));
}
else if ( ac->attr.bit.inherit_bg )
{
// add the covered background to this character
char_data ch, cc;
std::memcpy (&ch, ac, sizeof(char_data));
cc = getCoveredCharacter (ax + x + 1, ay + y + 1, area->widget);
ch.bg_color = cc.bg_color;
std::memcpy (tc, &ch, sizeof(char_data));
}
else // default
std::memcpy (tc, ac, sizeof(char_data));
}
} }
} }
@ -1869,69 +1831,27 @@ void FVTerm::scrollAreaReverse (term_area* area)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FVTerm::clearArea (term_area* area, int fillchar) void FVTerm::clearArea (term_area* area, int fillchar)
{ {
// clear the area with the current attributes // Clear the area with the current attributes
char_data nc; // next character char_data nc; // next character
int total_width;
uInt w; uInt w;
// current attributes with a space character // Current attributes with a space character
std::memcpy (&nc, &next_attribute, sizeof(char_data)); std::memcpy (&nc, &next_attribute, sizeof(char_data));
nc.code = fillchar; nc.code = fillchar;
if ( ! (area && area->text) ) if ( ! (area && area->text) )
return; return;
total_width = area->width + area->right_shadow; w = uInt(area->width + area->right_shadow);
w = uInt(total_width);
if ( area->right_shadow == 0 ) if ( area->right_shadow == 0 )
{ {
int area_size = area->width * area->height; if ( clearFullArea(area, nc) )
std::fill_n (area->text, area_size, nc);
if ( area == vdesktop )
{
if ( clearTerm (fillchar) )
{
nc.attr.bit.printed = true;
std::fill_n (vterm->text, area_size, nc);
}
else
{
for (int i = 0; i < vdesktop->height; i++)
{
vdesktop->changes[i].xmin = 0;
vdesktop->changes[i].xmax = uInt(vdesktop->width) - 1;
vdesktop->changes[i].trans_count = 0;
}
vdesktop->has_changes = true;
}
return; return;
}
} }
else else
{ clearAreaWithShadow(area, nc);
char_data t_char = nc;
t_char.attr.bit.transparent = true;
for (int y = 0; y < area->height; y++)
{
int pos = y * total_width;
// area
std::fill_n (&area->text[pos], total_width, nc);
// right shadow
std::fill_n (&area->text[pos + area->width], area->right_shadow, t_char);
}
// bottom shadow
for (int y = 0; y < area->bottom_shadow; y++)
{
int pos = total_width * (y + area->height);
std::fill_n (&area->text[pos], total_width, t_char);
}
}
for (int i = 0; i < area->height; i++) for (int i = 0; i < area->height; i++)
{ {
@ -2327,10 +2247,67 @@ void FVTerm::finish()
delete term_pos; delete term_pos;
} }
//----------------------------------------------------------------------
void FVTerm::putAreaLine (char_data* ac, char_data* tc, int length)
{
// copy "length" characters from area to terminal
std::memcpy (tc, ac, sizeof(char_data) * unsigned(length));
}
//----------------------------------------------------------------------
void FVTerm::putAreaCharacter ( int x, int y, FVTerm* obj
, char_data* ac
, char_data* tc )
{
if ( ac->attr.bit.transparent ) // Transparent
{
// Restore one character on vterm
char_data ch;
ch = getCoveredCharacter (x, y, obj);
std::memcpy (tc, &ch, sizeof(char_data));
}
else // Mot transparent
{
if ( ac->attr.bit.trans_shadow ) // Transparent shadow
{
// Get covered character + add the current color
char_data ch;
ch = getCoveredCharacter (x, y, obj);
ch.fg_color = ac->fg_color;
ch.bg_color = ac->bg_color;
ch.attr.bit.reverse = false;
ch.attr.bit.standout = false;
if ( ch.code == fc::LowerHalfBlock
|| ch.code == fc::UpperHalfBlock
|| ch.code == fc::LeftHalfBlock
|| ch.code == fc::RightHalfBlock
|| ch.code == fc::MediumShade
|| ch.code == fc::FullBlock )
ch.code = ' ';
std::memcpy (tc, &ch, sizeof(char_data));
}
else if ( ac->attr.bit.inherit_bg )
{
// Add the covered background to this character
char_data ch, cc;
std::memcpy (&ch, ac, sizeof(char_data));
cc = getCoveredCharacter (x, y, obj);
ch.bg_color = cc.bg_color;
std::memcpy (tc, &ch, sizeof(char_data));
}
else // Default
std::memcpy (tc, ac, sizeof(char_data));
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FVTerm::clearTerm (int fillchar) bool FVTerm::clearTerm (int fillchar)
{ {
// Clear the real terminal and put cursor at home // Clear the real terminal and put cursor at home
char*& cl = TCAP(fc::t_clear_screen); char*& cl = TCAP(fc::t_clear_screen);
char*& cd = TCAP(fc::t_clr_eos); char*& cd = TCAP(fc::t_clr_eos);
char*& cb = TCAP(fc::t_clr_eol); char*& cb = TCAP(fc::t_clr_eol);
@ -2345,18 +2322,18 @@ bool FVTerm::clearTerm (int fillchar)
return false; return false;
} }
if ( cl ) if ( cl ) // Clear screen
{ {
appendOutputBuffer (cl); appendOutputBuffer (cl);
term_pos->setPoint(0,0); term_pos->setPoint(0,0);
} }
else if ( cd ) else if ( cd ) // Clear to end of screen
{ {
setTermXY (0, 0); setTermXY (0, 0);
appendOutputBuffer (cd); appendOutputBuffer (cd);
term_pos->setPoint(-1, -1); term_pos->setPoint(-1, -1);
} }
else if ( cb ) else if ( cb ) // Clear to end of line
{ {
term_pos->setPoint(-1, -1); term_pos->setPoint(-1, -1);
@ -2373,6 +2350,61 @@ bool FVTerm::clearTerm (int fillchar)
return true; return true;
} }
//----------------------------------------------------------------------
bool FVTerm::clearFullArea (term_area* area, char_data& nc)
{
// Clear area
int area_size = area->width * area->height;
std::fill_n (area->text, area_size, nc);
if ( area != vdesktop ) // Is the area identical to the desktop?
return false;
// Try to clear the terminal rapidly with a control sequence
if ( clearTerm (nc.code) )
{
nc.attr.bit.printed = true;
std::fill_n (vterm->text, area_size, nc);
}
else
{
for (int i = 0; i < vdesktop->height; i++)
{
vdesktop->changes[i].xmin = 0;
vdesktop->changes[i].xmax = uInt(vdesktop->width) - 1;
vdesktop->changes[i].trans_count = 0;
}
vdesktop->has_changes = true;
}
return true;
}
//----------------------------------------------------------------------
void FVTerm::clearAreaWithShadow (term_area* area, char_data& nc)
{
char_data t_char = nc;
int total_width = area->width + area->right_shadow;
t_char.attr.bit.transparent = true;
for (int y = 0; y < area->height; y++)
{
int pos = y * total_width;
// Clear area
std::fill_n (&area->text[pos], total_width, nc);
// Make right shadow transparent
std::fill_n (&area->text[pos + area->width], area->right_shadow, t_char);
}
// Make bottom shadow transparent
for (int y = 0; y < area->bottom_shadow; y++)
{
int pos = total_width * (y + area->height);
std::fill_n (&area->text[pos], total_width, t_char);
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FVTerm::canClearToEOL (uInt xmin, uInt y) bool FVTerm::canClearToEOL (uInt xmin, uInt y)
{ {