diff --git a/ChangeLog b/ChangeLog index 4dbd190f..74737821 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2016-08-25 Markus Gans + * Use the new transparent shadow option in drawShadow() + 2016-08-21 Markus Gans * Improved transparent shadow background * Add "transparent" example to demonstrate transparency diff --git a/src/fapp.cpp b/src/fapp.cpp index 16f6af8f..2ea73341 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -1752,18 +1752,18 @@ void FApplication::setMainWidget (FWidget* widget) //---------------------------------------------------------------------- int FApplication::exec() // run { - FWidget* focus_widget; + FWidget* widget; quit_now = false; quit_code = 0; // set the cursor to the focus widget - focus_widget = getFocusWidget(); + widget = getFocusWidget(); - if ( focus_widget - && focus_widget->isVisible() - && focus_widget->hasVisibleCursor() ) + if ( widget + && widget->isVisible() + && widget->hasVisibleCursor() ) { - focus_widget->setCursor(); + widget->setCursor(); showCursor(); flush_out(); } diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 55011a1d..73185e76 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -775,14 +775,14 @@ void FDialog::onWindowActive (FEvent*) if ( ! FWidget::getFocusWidget() ) { - FWidget* win_focus_widget = getWindowFocusWidget(); + FWidget* win_focus = getWindowFocusWidget(); - if ( win_focus_widget - && win_focus_widget->isVisible() - && win_focus_widget->isShown() ) + if ( win_focus + && win_focus->isVisible() + && win_focus->isShown() ) { - win_focus_widget->setFocus(); - win_focus_widget->redraw(); + win_focus->setFocus(); + win_focus->redraw(); } else focusFirstChild(); @@ -943,7 +943,7 @@ void FDialog::move (int x, int y) FWidget::move(x,y); xpos = x; ypos = y; - putArea (getGlobalPos(), vwin); + putArea (getGlobalPos(), vwin);updateTerminal(); if ( getGeometry().overlap(oldGeometry) ) { @@ -978,8 +978,8 @@ void FDialog::move (int x, int y) restoreVTerm (old_x, old_y, width+rsw, height+bsh); } - if ( ! maximized && (flags & fc::shadow) != 0 ) - drawDialogShadow(); + // if ( ! maximized && (flags & fc::shadow) != 0 ) + // drawDialogShadow(); // handle overlaid windows if ( window_list && ! window_list->empty() ) @@ -1028,14 +1028,14 @@ void FDialog::move (int x, int y) void FDialog::activateDialog() { FWidget* old_focus = FWidget::getFocusWidget(); - FWidget* win_focus_widget = getWindowFocusWidget(); + FWidget* win_focus = getWindowFocusWidget(); setActiveWindow(this); setFocus(); - if ( win_focus_widget && numOfFocusableChildren() > 1 ) + if ( win_focus && numOfFocusableChildren() > 1 ) { - win_focus_widget->setFocus(); - win_focus_widget->redraw(); + win_focus->setFocus(); + win_focus->redraw(); if ( old_focus ) old_focus->redraw(); diff --git a/src/fterm.cpp b/src/fterm.cpp index 33747031..22853b1d 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -2361,16 +2361,15 @@ void FTerm::restoreVTerm (int x, int y, int w, int h) const FRect& geometry = (*iter)->getGeometryGlobalShadow(); // window visible and contains current character - if ( win && win->visible && geometry.contains(x+tx+1, y+ty+1) ) + if ( win && win->visible && geometry.contains(tx+x+1, ty+y+1) ) { FOptiAttr::char_data* tmp; int win_x = (*iter)->getGlobalX() - 1; int win_y = (*iter)->getGlobalY() - 1; int line_len = win->width + win->right_shadow; - tmp = &win->text[(y+ty-win_y) * line_len + (x+tx-win_x)]; + tmp = &win->text[(ty+y-win_y) * line_len + (tx+x-win_x)]; - // current character not transparent - if ( ! tmp->transparent ) + if ( ! tmp->transparent ) // current character not transparent { if ( tmp->trans_shadow ) // transparent shadow { @@ -2380,6 +2379,14 @@ void FTerm::restoreVTerm (int x, int y, int w, int h) s_ch.bg_color = tmp->bg_color; s_ch.reverse = false; s_ch.standout = false; + + if ( s_ch.code == fc::LowerHalfBlock + || s_ch.code == fc::UpperHalfBlock + || s_ch.code == fc::LeftHalfBlock + || s_ch.code == fc::RightHalfBlock + || s_ch.code == fc::FullBlock ) + s_ch.code = ' '; + sc = &s_ch; } else // default @@ -2600,6 +2607,16 @@ void FTerm::updateVTerm (FTerm::term_area* area) oc = getOverlappedCharacter (gx+1, gy+1, area->widget); ch.fg_color = oc.fg_color; ch.bg_color = oc.bg_color; + ch.reverse = false; + ch.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::FullBlock ) + ch.code = ' '; + memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); } else if ( ac->transparent ) // transparent @@ -2620,6 +2637,14 @@ void FTerm::updateVTerm (FTerm::term_area* area) ch.bg_color = ac->bg_color; ch.reverse = false; ch.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::FullBlock ) + ch.code = ' '; + memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); } else // default @@ -2800,14 +2825,14 @@ void FTerm::putArea (int ax, int ay, FTerm::term_area* area) if ( area->changes[y].trans_count == 0 ) { - // only covered character + // Line has only covered characters tc = &vterm->text[(ay+y) * vterm->width + ax]; ac = &area->text[y * line_len + ol]; memcpy (tc, ac, sizeof(FOptiAttr::char_data) * unsigned(length)); } else { - // Line has transparent character + // Line has one or more transparent characters for (register int x=0; x < length; x++) // column loop { tc = &vterm->text[(ay+y) * vterm->width + (ax+x)]; @@ -2831,6 +2856,14 @@ void FTerm::putArea (int ax, int ay, FTerm::term_area* area) ch.bg_color = ac->bg_color; ch.reverse = false; ch.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::FullBlock ) + ch.code = ' '; + memcpy (tc, &ch, sizeof(FOptiAttr::char_data)); } else // default diff --git a/src/fwidget.cpp b/src/fwidget.cpp index e575289c..6b737674 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -1942,6 +1942,8 @@ void FWidget::clearArea() term_area* area; FWindow* area_widget; FOptiAttr::char_data default_char; + int total_width; + uInt w; default_char.code = ' '; default_char.fg_color = next_attribute.fg_color; @@ -1972,6 +1974,9 @@ void FWidget::clearArea() if ( ! area ) return; + total_width = area->width + area->right_shadow; + w = uInt(total_width); + if ( area->right_shadow == 0 ) { int area_size = area->width * area->height; @@ -1979,25 +1984,45 @@ void FWidget::clearArea() } else { + FOptiAttr::char_data t_char = default_char; + t_char.transparent = true; + for (int y=0; y < area->height; y++) { - int pos = y * (area->width + area->right_shadow); - std::fill_n (&area->text[pos], area->width, default_char); + int pos = y * total_width; + std::fill_n (&area->text[pos], total_width, default_char); + std::fill_n (&area->text[pos+area->width], area->right_shadow, t_char); + } + + 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++) { - uInt w = uInt(area->width + area->right_shadow); + area->changes[i].xmin = 0; area->changes[i].xmax = w - 1; if ( default_char.transparent || default_char.trans_shadow ) area->changes[i].trans_count = w; + else if ( area->right_shadow != 0 ) + area->changes[i].trans_count = area->right_shadow; else area->changes[i].trans_count = 0; } + for (int i=0; i < area->bottom_shadow; i++) + { + int y = area->height + i; + area->changes[y].xmin = 0; + area->changes[y].xmax = w - 1; + area->changes[y].trans_count = w; + } + updateVTerm (area); } @@ -2026,149 +2051,33 @@ void FWidget::drawShadow() if ( trans_shadow ) { // transparent shadow - if ( x2 < xmax ) + gotoxy (x2+1, y1); + setTransparent(); + print (" "); + unsetTransparent(); + + setColor (wc.shadow_bg, wc.shadow_fg); + setTransShadow(); + + for (int i=1; i < height; i++) { - gotoxy (x2+1, y1); - - for (int x=1; x <= 2; x++) - { - ch = getCoveredCharacter (x2+x, y1, this); - setColor (ch.fg_color, ch.bg_color); - - if ( ch.bold ) - setBold (true); - - if ( ch.dim ) - setDim (true); - - if ( ch.italic ) - setItalic (true); - - if ( ch.underline ) - setUnderline (true); - - if ( ch.blink ) - setBlink (true); - - if ( ch.reverse ) - setReverse (true); - - if ( ch.standout ) - setStandout (true); - - if ( ch.invisible ) - setInvisible (true); - - if ( ch.protect ) - setProtected (true); - - if ( ch.crossed_out ) - setCrossedOut (true); - - if ( ch.dbl_underline ) - setDoubleUnderline (true); - - if ( ch.alt_charset ) - setAltCharset (true); - - if ( ch.pc_charset ) - setPCcharset (true); - - print (ch.code); - - setNormal(); - } - - setColor (wc.shadow_bg, wc.shadow_fg); - - for (int i=1; i < height && y1+i <= ymax; i++) - { - gotoxy (x2+1, y1+i); - - for (int x=1; x <= 2; x++) - { - ch = getCoveredCharacter (x2+x, y1+i, this); - - if ( ch.code == fc::LowerHalfBlock - || ch.code == fc::UpperHalfBlock - || ch.code == fc::LeftHalfBlock - || ch.code == fc::RightHalfBlock - || ch.code == fc::FullBlock ) - print (' '); - else - print (ch.code); - } - } + gotoxy (x2+1, y1+i); + print (" "); } - if ( y2 < ymax ) - { - gotoxy (x1, y2+1); + unsetTransShadow(); + gotoxy (x1, y2+1); + setTransparent(); + print (" "); + unsetTransparent(); - for (int x=0; x <= 1; x++) - { - ch = getCoveredCharacter (x1+x, y2+1, this); - setColor (ch.fg_color, ch.bg_color); + setColor (wc.shadow_bg, wc.shadow_fg); + setTransShadow(); - if ( ch.bold ) - setBold (true); + for (int i=2; i <= width+1; i++) + print (' '); - if ( ch.dim ) - setDim (true); - - if ( ch.italic ) - setItalic (true); - - if ( ch.underline ) - setUnderline (true); - - if ( ch.blink ) - setBlink (true); - - if ( ch.reverse ) - setReverse (true); - - if ( ch.standout ) - setStandout (true); - - if ( ch.invisible ) - setInvisible (true); - - if ( ch.protect ) - setProtected (true); - - if ( ch.crossed_out ) - setCrossedOut (true); - - if ( ch.dbl_underline ) - setDoubleUnderline (true); - - if ( ch.alt_charset ) - setAltCharset (true); - - if ( ch.pc_charset ) - setPCcharset (true); - - print (ch.code); - setNormal(); - } - - setColor (wc.shadow_bg, wc.shadow_fg); - - for (int i=2; i <= width+1 && x1+i <= xmax; i++) - { - ch = getCoveredCharacter (x1+i, y2+1, this); - - if ( ch.code == fc::LowerHalfBlock - || ch.code == fc::UpperHalfBlock - || ch.code == fc::LeftHalfBlock - || ch.code == fc::RightHalfBlock - || ch.code == fc::FullBlock ) - print (' '); - else - print (ch.code); - } - } + unsetTransShadow(); if ( isMonochron() ) setReverse(false); @@ -2176,45 +2085,39 @@ void FWidget::drawShadow() else { // non-transparent shadow - if ( x2 < xmax ) + int block; + gotoxy (x2+1, y1); + ch = getCoveredCharacter (x2+1, y1, this); + setColor (wc.shadow_fg, ch.bg_color); + + if ( isTeraTerm() ) { - int block; - gotoxy (x2+1, y1); - ch = getCoveredCharacter (x2+1, y1, this); + block = 0xdb; // █ + print (0xdc); // ▄ + } + else + { + block = fc::FullBlock; // █ + print (fc::LowerHalfBlock); // ▄ + } + + for (int i=1; i < height; i++) + { + gotoxy (x2+1, y1+i); + print (block); // █ + } + + gotoxy (x1+1, y2+1); + + for (int i=1; i <= width; i++) + { + ch = getCoveredCharacter (x1+i, y2+1, this); setColor (wc.shadow_fg, ch.bg_color); if ( isTeraTerm() ) - { - block = 0xdb; // █ - print (0xdc); // ▄ - } + print (0xdf); // ▀ else - { - block = fc::FullBlock; // █ - print (fc::LowerHalfBlock); // ▄ - } - - for (int i=1; i < height && y1+i <= ymax; i++) - { - gotoxy (x2+1, y1+i); - print (block); // █ - } - } - - if ( y2 < ymax ) - { - 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); - - if ( isTeraTerm() ) - print (0xdf); // ▀ - else - print (fc::UpperHalfBlock); // ▀ - } + print (fc::UpperHalfBlock); // ▀ } } } diff --git a/test/transparent.cpp b/test/transparent.cpp index 6db07960..b33a2802 100644 --- a/test/transparent.cpp +++ b/test/transparent.cpp @@ -42,9 +42,9 @@ class Transparent : public FDialog #pragma pack(pop) //---------------------------------------------------------------------- -Transparent::Transparent (FWidget* parent, bool shadow) +Transparent::Transparent (FWidget* parent, bool s) : FDialog(parent) - , shadow_win(shadow) + , shadow_win(s) { setStatusbarMessage("Press Q to quit"); addAccelerator('q');