diff --git a/ChangeLog b/ChangeLog index 74737821..25aec7d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-08-25 Markus Gans + * A new inherit background option for characters + * Use inherit background for the simple shadows + * Updating the transparent example program + 2016-08-25 Markus Gans * Use the new transparent shadow option in drawShadow() diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 73185e76..0f50e29b 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -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 ) { diff --git a/src/foptiattr.h b/src/foptiattr.h index 6735f3ac..bbbe8c6d 100644 --- a/src/foptiattr.h +++ b/src/foptiattr.h @@ -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; } //---------------------------------------------------------------------- diff --git a/src/fterm.cpp b/src/fterm.cpp index 22853b1d..8a1566c6 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -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--; diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 6b737674..6571e210 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -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); // ┌ diff --git a/src/fwidget.h b/src/fwidget.h index 775ce3d6..62ce088d 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -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); } diff --git a/test/transparent.cpp b/test/transparent.cpp index b33a2802..74d45114 100644 --- a/test/transparent.cpp +++ b/test/transparent.cpp @@ -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();