Use the new transparent shadow option in drawShadow()

This commit is contained in:
Markus Gans 2016-08-25 01:54:10 +02:00
parent f493f7d480
commit 98fbce5de6
6 changed files with 140 additions and 201 deletions

View File

@ -1,3 +1,6 @@
2016-08-25 Markus Gans <guru.mail@muenster.de>
* Use the new transparent shadow option in drawShadow()
2016-08-21 Markus Gans <guru.mail@muenster.de> 2016-08-21 Markus Gans <guru.mail@muenster.de>
* Improved transparent shadow background * Improved transparent shadow background
* Add "transparent" example to demonstrate transparency * Add "transparent" example to demonstrate transparency

View File

@ -1752,18 +1752,18 @@ void FApplication::setMainWidget (FWidget* widget)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int FApplication::exec() // run int FApplication::exec() // run
{ {
FWidget* focus_widget; FWidget* widget;
quit_now = false; quit_now = false;
quit_code = 0; quit_code = 0;
// set the cursor to the focus widget // set the cursor to the focus widget
focus_widget = getFocusWidget(); widget = getFocusWidget();
if ( focus_widget if ( widget
&& focus_widget->isVisible() && widget->isVisible()
&& focus_widget->hasVisibleCursor() ) && widget->hasVisibleCursor() )
{ {
focus_widget->setCursor(); widget->setCursor();
showCursor(); showCursor();
flush_out(); flush_out();
} }

View File

@ -775,14 +775,14 @@ void FDialog::onWindowActive (FEvent*)
if ( ! FWidget::getFocusWidget() ) if ( ! FWidget::getFocusWidget() )
{ {
FWidget* win_focus_widget = getWindowFocusWidget(); FWidget* win_focus = getWindowFocusWidget();
if ( win_focus_widget if ( win_focus
&& win_focus_widget->isVisible() && win_focus->isVisible()
&& win_focus_widget->isShown() ) && win_focus->isShown() )
{ {
win_focus_widget->setFocus(); win_focus->setFocus();
win_focus_widget->redraw(); win_focus->redraw();
} }
else else
focusFirstChild(); focusFirstChild();
@ -943,7 +943,7 @@ void FDialog::move (int x, int y)
FWidget::move(x,y); FWidget::move(x,y);
xpos = x; xpos = x;
ypos = y; ypos = y;
putArea (getGlobalPos(), vwin); putArea (getGlobalPos(), vwin);updateTerminal();
if ( getGeometry().overlap(oldGeometry) ) if ( getGeometry().overlap(oldGeometry) )
{ {
@ -978,8 +978,8 @@ void FDialog::move (int x, int y)
restoreVTerm (old_x, old_y, width+rsw, height+bsh); restoreVTerm (old_x, old_y, width+rsw, height+bsh);
} }
if ( ! maximized && (flags & fc::shadow) != 0 ) // if ( ! maximized && (flags & fc::shadow) != 0 )
drawDialogShadow(); // drawDialogShadow();
// handle overlaid windows // handle overlaid windows
if ( window_list && ! window_list->empty() ) if ( window_list && ! window_list->empty() )
@ -1028,14 +1028,14 @@ void FDialog::move (int x, int y)
void FDialog::activateDialog() void FDialog::activateDialog()
{ {
FWidget* old_focus = FWidget::getFocusWidget(); FWidget* old_focus = FWidget::getFocusWidget();
FWidget* win_focus_widget = getWindowFocusWidget(); FWidget* win_focus = getWindowFocusWidget();
setActiveWindow(this); setActiveWindow(this);
setFocus(); setFocus();
if ( win_focus_widget && numOfFocusableChildren() > 1 ) if ( win_focus && numOfFocusableChildren() > 1 )
{ {
win_focus_widget->setFocus(); win_focus->setFocus();
win_focus_widget->redraw(); win_focus->redraw();
if ( old_focus ) if ( old_focus )
old_focus->redraw(); old_focus->redraw();

View File

@ -2361,16 +2361,15 @@ void FTerm::restoreVTerm (int x, int y, int w, int h)
const FRect& geometry = (*iter)->getGeometryGlobalShadow(); const FRect& geometry = (*iter)->getGeometryGlobalShadow();
// window visible and contains current character // 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; FOptiAttr::char_data* tmp;
int win_x = (*iter)->getGlobalX() - 1; int win_x = (*iter)->getGlobalX() - 1;
int win_y = (*iter)->getGlobalY() - 1; int win_y = (*iter)->getGlobalY() - 1;
int line_len = win->width + win->right_shadow; 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 ) // current character not transparent
if ( ! tmp->transparent )
{ {
if ( tmp->trans_shadow ) // transparent shadow 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.bg_color = tmp->bg_color;
s_ch.reverse = false; s_ch.reverse = false;
s_ch.standout = 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; sc = &s_ch;
} }
else // default else // default
@ -2600,6 +2607,16 @@ void FTerm::updateVTerm (FTerm::term_area* area)
oc = getOverlappedCharacter (gx+1, gy+1, area->widget); oc = getOverlappedCharacter (gx+1, gy+1, area->widget);
ch.fg_color = oc.fg_color; ch.fg_color = oc.fg_color;
ch.bg_color = oc.bg_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)); memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
} }
else if ( ac->transparent ) // transparent else if ( ac->transparent ) // transparent
@ -2620,6 +2637,14 @@ void FTerm::updateVTerm (FTerm::term_area* area)
ch.bg_color = ac->bg_color; ch.bg_color = ac->bg_color;
ch.reverse = false; ch.reverse = false;
ch.standout = 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)); memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
} }
else // default else // default
@ -2800,14 +2825,14 @@ void FTerm::putArea (int ax, int ay, FTerm::term_area* area)
if ( area->changes[y].trans_count == 0 ) if ( area->changes[y].trans_count == 0 )
{ {
// only covered character // Line has only covered characters
tc = &vterm->text[(ay+y) * vterm->width + ax]; tc = &vterm->text[(ay+y) * vterm->width + ax];
ac = &area->text[y * line_len + ol]; ac = &area->text[y * line_len + ol];
memcpy (tc, ac, sizeof(FOptiAttr::char_data) * unsigned(length)); memcpy (tc, ac, sizeof(FOptiAttr::char_data) * unsigned(length));
} }
else else
{ {
// Line has transparent character // 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)]; 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.bg_color = ac->bg_color;
ch.reverse = false; ch.reverse = false;
ch.standout = 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)); memcpy (tc, &ch, sizeof(FOptiAttr::char_data));
} }
else // default else // default

View File

@ -1942,6 +1942,8 @@ void FWidget::clearArea()
term_area* area; term_area* area;
FWindow* area_widget; FWindow* area_widget;
FOptiAttr::char_data default_char; FOptiAttr::char_data default_char;
int total_width;
uInt w;
default_char.code = ' '; default_char.code = ' ';
default_char.fg_color = next_attribute.fg_color; default_char.fg_color = next_attribute.fg_color;
@ -1972,6 +1974,9 @@ void FWidget::clearArea()
if ( ! area ) if ( ! area )
return; return;
total_width = 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; int area_size = area->width * area->height;
@ -1979,25 +1984,45 @@ void FWidget::clearArea()
} }
else else
{ {
FOptiAttr::char_data t_char = default_char;
t_char.transparent = true;
for (int y=0; y < area->height; y++) for (int y=0; y < area->height; y++)
{ {
int pos = y * (area->width + area->right_shadow); int pos = y * total_width;
std::fill_n (&area->text[pos], area->width, default_char); 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++) for (int i=0; i < area->height; i++)
{ {
uInt w = uInt(area->width + area->right_shadow);
area->changes[i].xmin = 0; area->changes[i].xmin = 0;
area->changes[i].xmax = w - 1; area->changes[i].xmax = w - 1;
if ( default_char.transparent || default_char.trans_shadow ) if ( default_char.transparent || default_char.trans_shadow )
area->changes[i].trans_count = w; area->changes[i].trans_count = w;
else if ( area->right_shadow != 0 )
area->changes[i].trans_count = area->right_shadow;
else else
area->changes[i].trans_count = 0; 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); updateVTerm (area);
} }
@ -2026,149 +2051,33 @@ void FWidget::drawShadow()
if ( trans_shadow ) if ( trans_shadow )
{ {
// transparent 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); gotoxy (x2+1, y1+i);
print (" ");
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);
}
}
} }
if ( y2 < ymax ) unsetTransShadow();
{ gotoxy (x1, y2+1);
gotoxy (x1, y2+1); setTransparent();
print (" ");
unsetTransparent();
for (int x=0; x <= 1; x++) setColor (wc.shadow_bg, wc.shadow_fg);
{ setTransShadow();
ch = getCoveredCharacter (x1+x, y2+1, this);
setColor (ch.fg_color, ch.bg_color);
if ( ch.bold ) for (int i=2; i <= width+1; i++)
setBold (true); print (' ');
if ( ch.dim ) unsetTransShadow();
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);
}
}
if ( isMonochron() ) if ( isMonochron() )
setReverse(false); setReverse(false);
@ -2176,45 +2085,39 @@ void FWidget::drawShadow()
else else
{ {
// non-transparent shadow // 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; block = 0xdb; // █
gotoxy (x2+1, y1); print (0xdc); // ▄
ch = getCoveredCharacter (x2+1, y1, this); }
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); setColor (wc.shadow_fg, ch.bg_color);
if ( isTeraTerm() ) if ( isTeraTerm() )
{ print (0xdf); // ▀
block = 0xdb; // █
print (0xdc); // ▄
}
else else
{ print (fc::UpperHalfBlock); // ▀
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); // ▀
}
} }
} }
} }

View File

@ -42,9 +42,9 @@ class Transparent : public FDialog
#pragma pack(pop) #pragma pack(pop)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
Transparent::Transparent (FWidget* parent, bool shadow) Transparent::Transparent (FWidget* parent, bool s)
: FDialog(parent) : FDialog(parent)
, shadow_win(shadow) , shadow_win(s)
{ {
setStatusbarMessage("Press Q to quit"); setStatusbarMessage("Press Q to quit");
addAccelerator('q'); addAccelerator('q');