new inherit background option for characters

This commit is contained in:
Markus Gans 2016-08-27 23:23:42 +02:00
parent 98fbce5de6
commit 2904ed31b9
7 changed files with 181 additions and 96 deletions

View File

@ -1,3 +1,8 @@
2016-08-25 Markus Gans <guru.mail@muenster.de>
* A new inherit background option for characters
* Use inherit background for the simple shadows
* Updating the transparent example program
2016-08-25 Markus Gans <guru.mail@muenster.de>
* Use the new transparent shadow option in drawShadow()

View File

@ -378,82 +378,40 @@ void FDialog::drawDialogShadow()
if ( isNewFont() && ((flags & fc::scrollable) == 0) )
{
FOptiAttr::char_data ch;
// left of the shadow ▀▀
gotoxy (xpos+xmin-1, ypos+ymin-1+height);
setColor (wc.shadow_fg, wc.shadow_bg);
// current background color will be ignored
setInheritBackground();
for (int x=0; x <= 1; x++)
{
ch = getCoveredCharacter (xpos+xmin-1+x, ypos+ymin-1+height, this);
setColor (wc.shadow_fg, ch.bg_color);
// high line ⎺
print (fc::NF_border_line_upper);
}
print (fc::NF_border_line_upper); // high line ⎺
unsetInheritBackground();
}
}
else
{
FOptiAttr::char_data ch;
if ( isMonochron() )
return;
drawShadow();
ch = getCoveredCharacter (xpos+xmin-1, ypos+ymin-1+height, this);
// left of the shadow ▀▀
gotoxy (xpos+xmin-1, ypos+ymin-1+height);
if ( isNewFont() && ((flags & fc::scrollable) == 0) )
{
setColor (wc.shadow_fg, ch.bg_color);
// high line ⎺
print (fc::NF_border_line_upper);
setColor (wc.shadow_fg, wc.shadow_bg);
// current background color will be ignored
setInheritBackground();
print (fc::NF_border_line_upper); // high line ⎺
unsetInheritBackground();
}
else
{
setColor(ch.fg_color, ch.bg_color);
if ( ch.bold )
setBold();
if ( ch.dim )
setDim();
if ( ch.italic )
setItalic();
if ( ch.underline )
setUnderline();
if ( ch.blink )
setBlink();
if ( ch.reverse )
setReverse();
if ( ch.standout )
setStandout();
if ( ch.invisible )
setInvisible();
if ( ch.protect )
setProtected();
if ( ch.crossed_out )
setCrossedOut();
if ( ch.dbl_underline )
setDoubleUnderline();
if ( ch.alt_charset )
setAltCharset (true);
if ( ch.pc_charset )
setPCcharset (true);
print (ch.code);
setNormal();
setTransparent();
print(' ');
unsetTransparent();
}
}
}
@ -1031,6 +989,7 @@ void FDialog::activateDialog()
FWidget* win_focus = getWindowFocusWidget();
setActiveWindow(this);
setFocus();
setFocusWidget(this);
if ( win_focus && numOfFocusableChildren() > 1 )
{

View File

@ -123,7 +123,7 @@ class FOptiAttr
uChar pc_charset : 1; // pc character set (CP437)
uChar transparent : 1; // transparent
uChar trans_shadow : 1; // transparent shadow
uChar : 1; // padding bits
uChar inherit_bg : 1; // inherit background
} char_data;
private:
@ -279,7 +279,8 @@ inline bool operator == ( const FOptiAttr::char_data& lhs,
&& lhs.alt_charset == rhs.alt_charset
&& lhs.pc_charset == rhs.pc_charset
&& lhs.transparent == rhs.transparent
&& lhs.trans_shadow == rhs.trans_shadow;
&& lhs.trans_shadow == rhs.trans_shadow
&& lhs.inherit_bg == rhs.inherit_bg;
}
//----------------------------------------------------------------------

View File

@ -1697,7 +1697,8 @@ void FTerm::init()
term_attribute.alt_charset = \
term_attribute.pc_charset = \
term_attribute.transparent = \
term_attribute.trans_shadow = false;
term_attribute.trans_shadow = \
term_attribute.inherit_bg = false;
// next_attribute contains the state of the next printed character
next_attribute.code = '\0';
@ -1717,7 +1718,8 @@ void FTerm::init()
next_attribute.alt_charset = \
next_attribute.pc_charset = \
next_attribute.transparent = \
next_attribute.trans_shadow = false;
next_attribute.trans_shadow = \
next_attribute.inherit_bg = false;
// Preset to true
cursor_optimisation = true;
@ -2289,6 +2291,7 @@ void FTerm::resizeArea (term_area* area)
default_char.pc_charset = 0;
default_char.transparent = 0;
default_char.trans_shadow = 0;
default_char.inherit_bg = 0;
std::fill_n (area->text, area_size, default_char);
@ -2314,6 +2317,7 @@ void FTerm::restoreVTerm (int x, int y, int w, int h)
FOptiAttr::char_data* tc; // terminal character
FOptiAttr::char_data* sc; // shown character
FOptiAttr::char_data s_ch; // shadow character
FOptiAttr::char_data i_ch; // inherit background character
FWidget* widget;
x--;
@ -2389,6 +2393,13 @@ void FTerm::restoreVTerm (int x, int y, int w, int h)
sc = &s_ch;
}
else if ( tmp->inherit_bg )
{
// add the covered background to this character
memcpy (&i_ch, tmp, sizeof(FOptiAttr::char_data));
i_ch.bg_color = sc->bg_color; // last background color;
sc = &i_ch;
}
else // default
sc = tmp;
}
@ -2647,6 +2658,15 @@ void FTerm::updateVTerm (FTerm::term_area* area)
memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
}
else if ( ac->inherit_bg )
{
// add the covered background to this character
FOptiAttr::char_data ch, cc;
memcpy (&ch, ac, sizeof(FOptiAttr::char_data));
cc = getCoveredCharacter (gx+1, gy+1, area->widget);
ch.bg_color = cc.bg_color;
memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
}
else // default
memcpy (tc, ac, sizeof(FOptiAttr::char_data));
}
@ -2866,6 +2886,15 @@ void FTerm::putArea (int ax, int ay, FTerm::term_area* area)
memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
}
else if ( ac->inherit_bg )
{
// add the covered background to this character
FOptiAttr::char_data ch, cc;
memcpy (&ch, ac, sizeof(FOptiAttr::char_data));
cc = getCoveredCharacter (ax+x+1, ay+y+1, area->widget);
ch.bg_color = cc.bg_color;
memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
}
else // default
memcpy (tc, ac, sizeof(FOptiAttr::char_data));
}
@ -2890,6 +2919,7 @@ FOptiAttr::char_data FTerm::getCharacter ( int char_type
int xx,yy;
FOptiAttr::char_data* cc; // covered character
FOptiAttr::char_data s_ch; // shadow character
FOptiAttr::char_data i_ch; // inherit background character
FWidget* w;
x--;
@ -2915,6 +2945,7 @@ FOptiAttr::char_data FTerm::getCharacter ( int char_type
if ( w->window_list && ! w->window_list->empty() )
{
FWidget::widgetList::const_iterator iter, end;
// get the window layer of this object
int layer = FWindow::getWindowLayer(w);
iter = w->window_list->begin();
end = w->window_list->end();
@ -2923,6 +2954,8 @@ FOptiAttr::char_data FTerm::getCharacter ( int char_type
{
bool significant_char;
// char_type can be "overlapped_character"
// or "covered_character"
if ( char_type == covered_character )
significant_char = bool(layer >= FWindow::getWindowLayer(*iter));
else
@ -2955,6 +2988,13 @@ FOptiAttr::char_data FTerm::getCharacter ( int char_type
s_ch.standout = false;
cc = &s_ch;
}
else if ( tmp->inherit_bg )
{
// add the covered background to this character
memcpy (&i_ch, tmp, sizeof(FOptiAttr::char_data));
i_ch.bg_color = cc->bg_color; // last background color
cc = &i_ch;
}
else // default
cc = tmp;
}
@ -4408,6 +4448,7 @@ int FTerm::print (FTerm::term_area* area, FString& s)
nc.pc_charset = next_attribute.pc_charset;
nc.transparent = next_attribute.transparent;
nc.trans_shadow = next_attribute.trans_shadow;
nc.inherit_bg = next_attribute.inherit_bg;
int ax = x - area_widget->getGlobalX();
int ay = y - area_widget->getGlobalY();
@ -4424,13 +4465,15 @@ int FTerm::print (FTerm::term_area* area, FString& s)
if ( *ac != nc ) // compare with an overloaded operator
{
if ( ( ! ac->transparent && nc.transparent )
|| ( ! ac->trans_shadow && nc.trans_shadow ) )
|| ( ! ac->trans_shadow && nc.trans_shadow )
|| ( ! ac->inherit_bg && nc.inherit_bg ) )
{
// add one transparent character form line
area->changes[ay].trans_count++;
}
else if ( ( ac->transparent && ! nc.transparent )
|| ( ac->trans_shadow && ! nc.trans_shadow ) )
|| ( ac->trans_shadow && ! nc.trans_shadow )
|| ( ac->inherit_bg && ! nc.inherit_bg ) )
{
// remove one transparent character from line
area->changes[ay].trans_count--;
@ -4526,6 +4569,7 @@ int FTerm::print (FTerm::term_area* area, register int c)
nc.pc_charset = next_attribute.pc_charset;
nc.transparent = next_attribute.transparent;
nc.trans_shadow = next_attribute.trans_shadow;
nc.inherit_bg = next_attribute.inherit_bg;
x = short(cursor->getX());
y = short(cursor->getY());
@ -4548,14 +4592,16 @@ int FTerm::print (FTerm::term_area* area, register int c)
if ( *ac != nc ) // compare with an overloaded operator
{
if ( ( ! ac->transparent && nc.transparent )
|| ( ! ac->trans_shadow && nc.trans_shadow ) )
|| ( ! ac->trans_shadow && nc.trans_shadow )
|| ( ! ac->inherit_bg && nc.inherit_bg ) )
{
// add one transparent character form line
area->changes[ay].trans_count++;
}
if ( ( ac->transparent && ! nc.transparent )
|| ( ac->trans_shadow && ! nc.trans_shadow ) )
|| ( ac->trans_shadow && ! nc.trans_shadow )
|| ( ac->inherit_bg && ! nc.inherit_bg ) )
{
// remove one transparent character from line
area->changes[ay].trans_count--;

View File

@ -1269,6 +1269,7 @@ void FWidget::redraw()
default_char.pc_charset = 0;
default_char.transparent = 0;
default_char.trans_shadow = 0;
default_char.inherit_bg = 0;
if ( window_list && ! window_list->empty() )
{
@ -1963,6 +1964,7 @@ void FWidget::clearArea()
default_char.pc_charset = next_attribute.pc_charset;
default_char.transparent = next_attribute.transparent;
default_char.trans_shadow = next_attribute.trans_shadow;
default_char.inherit_bg = next_attribute.inherit_bg;
area_widget = FWindow::getWindowWidget(this);
@ -2007,10 +2009,12 @@ void FWidget::clearArea()
area->changes[i].xmin = 0;
area->changes[i].xmax = w - 1;
if ( default_char.transparent || default_char.trans_shadow )
if ( default_char.transparent
|| default_char.trans_shadow
|| default_char.inherit_bg )
area->changes[i].trans_count = w;
else if ( area->right_shadow != 0 )
area->changes[i].trans_count = area->right_shadow;
area->changes[i].trans_count = uInt(area->right_shadow);
else
area->changes[i].trans_count = 0;
}
@ -2029,7 +2033,6 @@ void FWidget::clearArea()
//----------------------------------------------------------------------
void FWidget::drawShadow()
{
FOptiAttr::char_data ch;
int x1, x2, y1, y2;
bool trans_shadow = ((flags & fc::trans_shadow) != 0);
@ -2087,8 +2090,15 @@ void FWidget::drawShadow()
// non-transparent shadow
int block;
gotoxy (x2+1, y1);
ch = getCoveredCharacter (x2+1, y1, this);
setColor (wc.shadow_fg, ch.bg_color);
if ( isWindow() )
{
setColor (wc.shadow_fg, wc.shadow_bg);
setInheritBackground(); // current background color will be ignored
}
else if ( FWidget* p = getParentWidget() )
setColor (wc.shadow_fg, p->getBackgroundColor());
if ( isTeraTerm() )
{
@ -2101,6 +2111,9 @@ void FWidget::drawShadow()
print (fc::LowerHalfBlock); // ▄
}
if ( isWindow() )
unsetInheritBackground();
for (int i=1; i < height; i++)
{
gotoxy (x2+1, y1+i);
@ -2109,23 +2122,25 @@ void FWidget::drawShadow()
gotoxy (x1+1, y2+1);
if ( isWindow() )
setInheritBackground();
for (int i=1; i <= width; i++)
{
ch = getCoveredCharacter (x1+i, y2+1, this);
setColor (wc.shadow_fg, ch.bg_color);
if ( isTeraTerm() )
print (0xdf); // ▀
else
print (fc::UpperHalfBlock); // ▀
}
if ( isWindow() )
unsetInheritBackground();
}
}
//----------------------------------------------------------------------
void FWidget::clearShadow()
{
FOptiAttr::char_data ch;
int x1, x2, y1, y2;
if ( isMonochron() )
@ -2136,13 +2151,19 @@ void FWidget::clearShadow()
y1 = ypos+ymin-1;
y2 = ypos+ymin-2+height;
if ( isWindow() )
{
setColor (wc.shadow_fg, wc.shadow_bg);
setInheritBackground(); // current background color will be ignored
}
else if ( FWidget* p = getParentWidget() )
setColor (wc.shadow_fg, p->getBackgroundColor());
if ( x2 < xmax )
{
for (int i=0; i < height && y1+i <= ymax; i++)
for (int i=0; i < height; i++)
{
gotoxy (x2+1, y1+i);
ch = getCoveredCharacter (x2+1, y1+i, this);
setColor (wc.shadow_fg, ch.bg_color);
print (' '); // clear █
}
}
@ -2151,13 +2172,12 @@ void FWidget::clearShadow()
{
gotoxy (x1+1, y2+1);
for (int i=1; i <= width && x1+i <= xmax; i++)
{
ch = getCoveredCharacter (x1+i, y2+1, this);
setColor (wc.shadow_fg, ch.bg_color);
for (int i=1; i <= width; i++)
print (' '); // clear ▀
}
}
if ( isWindow() )
unsetInheritBackground();
}
//----------------------------------------------------------------------
@ -2173,7 +2193,10 @@ void FWidget::drawFlatBorder()
y1 = ypos+ymin-2;
y2 = ypos+ymin-1+height;
setColor (wc.dialog_fg, wc.dialog_bg);
if ( FWidget* p = getParentWidget() )
setColor (wc.dialog_fg, p->getBackgroundColor());
else
setColor (wc.dialog_fg, wc.dialog_bg);
for (int y=0; y < height; y++)
{
@ -2231,7 +2254,11 @@ void FWidget::clearFlatBorder()
y1 = ypos+ymin-2;
y2 = ypos+ymin-1+height;
setColor (wc.dialog_fg, wc.dialog_bg);
if ( FWidget* p = getParentWidget() )
setColor (wc.dialog_fg, p->getBackgroundColor());
else
setColor (wc.dialog_fg, wc.dialog_bg);
for (register int y=0; y < height; y++)
{
gotoxy (x1-1, y1+y+1);
@ -2338,9 +2365,13 @@ void FWidget::drawBorder()
if ( y2 > ymax )
y2 = ymax;
if ( FWidget* p = getParentWidget() )
setColor (wc.dialog_fg, p->getBackgroundColor());
else
setColor (wc.dialog_fg, wc.dialog_bg);
if ( isNewFont() )
{
setColor (wc.dialog_fg, wc.dialog_bg);
gotoxy (x1, y1);
print (fc::NF_border_corner_middle_upper_left); // ┌

View File

@ -523,6 +523,11 @@ class FWidget : public FObject, public FTerm
static bool unsetTransShadow();
static bool isTransShadow();
static bool setInheritBackground (register bool);
static bool setInheritBackground();
static bool unsetInheritBackground();
static bool isInheritBackground();
void drawShadow();
void clearShadow();
void drawFlatBorder();
@ -824,7 +829,8 @@ inline void FWidget::setNormal()
next_attribute.alt_charset = \
next_attribute.pc_charset = \
next_attribute.transparent = \
next_attribute.trans_shadow = false;
next_attribute.trans_shadow = \
next_attribute.inherit_bg = false;
next_attribute.fg_color = fc::Default;
next_attribute.bg_color = fc::Default;
@ -1070,6 +1076,22 @@ inline bool FWidget::unsetTransShadow()
inline bool FWidget::isTransShadow()
{ return next_attribute.trans_shadow; }
//----------------------------------------------------------------------
inline bool FWidget::setInheritBackground (register bool on)
{ return (next_attribute.inherit_bg = on); }
//----------------------------------------------------------------------
inline bool FWidget::setInheritBackground()
{ return setInheritBackground(true); }
//----------------------------------------------------------------------
inline bool FWidget::unsetInheritBackground()
{ return setInheritBackground(false); }
//----------------------------------------------------------------------
inline bool FWidget::isInheritBackground()
{ return next_attribute.inherit_bg; }
//----------------------------------------------------------------------
inline void FWidget::unsetDoubleFlatLine(int side)
{ setDoubleFlatLine(side, false); }

View File

@ -17,8 +17,16 @@
class Transparent : public FDialog
{
public:
typedef enum ttype
{
transparent = 0,
shadow = 1,
inherit_background = 2
} trans_type;
private:
bool shadow_win;
trans_type type;
private:
Transparent (const Transparent&); // Disabled copy constructor
@ -36,15 +44,15 @@ class Transparent : public FDialog
}
public:
explicit Transparent (FWidget* = 0, bool = false); // constructor
explicit Transparent (FWidget* = 0, trans_type = transparent); // constructor
~Transparent(); // destructor
};
#pragma pack(pop)
//----------------------------------------------------------------------
Transparent::Transparent (FWidget* parent, bool s)
Transparent::Transparent (FWidget* parent, Transparent::trans_type tt)
: FDialog(parent)
, shadow_win(s)
, type(tt)
{
setStatusbarMessage("Press Q to quit");
addAccelerator('q');
@ -63,15 +71,20 @@ void Transparent::draw()
if ( isMonochron() )
setReverse(true);
if ( shadow_win )
if ( type == shadow )
{
setColor(wc.shadow_bg, wc.shadow_fg);
setTransShadow();
}
else if ( type == inherit_background )
{
setColor(fc::Blue, fc::Black);
setInheritBackground();
}
else
setTransparent();
FString line(getClientWidth(), wchar_t(' '));
FString line(getClientWidth(), wchar_t('.'));
for (int n=1; n <= getClientHeight(); n++)
{
@ -79,8 +92,10 @@ void Transparent::draw()
print(line);
}
if ( shadow_win )
if ( type == shadow )
unsetTransShadow();
else if ( type == inherit_background )
unsetInheritBackground();
else
unsetTransparent();
@ -134,19 +149,25 @@ MainWindow::MainWindow (FWidget* parent)
Transparent* transpwin = new Transparent(this);
transpwin->setText("transparent");
transpwin->setGeometry (6, 11, 29, 12);
transpwin->setGeometry (6, 3, 29, 12);
transpwin->show();
Transparent* shadowwin = new Transparent(this, true);
Transparent* shadowwin = new Transparent(this, Transparent::shadow);
shadowwin->setText("shadow");
shadowwin->setGeometry (47, 11, 29, 12);
shadowwin->setGeometry (46, 11, 29, 12);
shadowwin->show();
Transparent* ibg = new Transparent(this, Transparent::inherit_background);
ibg->setText("inherit background");
ibg->setGeometry (42, 3, 29, 7);
ibg->show();
// Statusbar at the bottom
FStatusBar* statusbar = new FStatusBar (this);
statusbar->setMessage("Press Q to quit");
addAccelerator('q');
activateDialog();
}
//----------------------------------------------------------------------
@ -226,7 +247,7 @@ int main (int argc, char* argv[])
MainWindow main_dlg (&app);
main_dlg.setText ("non-transparent");
main_dlg.setGeometry (27, 3, 26, 7);
main_dlg.setGeometry (8, 16, 26, 7);
app.setMainWidget (&main_dlg);
main_dlg.show();