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>
* Improved transparent shadow background
* Add "transparent" example to demonstrate transparency

View File

@ -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();
}

View File

@ -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();

View File

@ -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

View File

@ -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); // ▀
}
}
}

View File

@ -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');