revert svn 4684, transparency in window buttons

This commit is contained in:
markt 2007-02-02 19:10:58 +00:00
parent 2b25b05b27
commit 2f4d0f6cde
4 changed files with 206 additions and 180 deletions

View file

@ -1,6 +1,10 @@
(Format: Year/Month/Day) (Format: Year/Month/Day)
Changes for 1.0rc3: Changes for 1.0rc3:
*07/02/02: *07/02/02:
* Reverted patch from svn 4684, allowing transparency in window buttons,
until we get it working with titlebar transparency, since the old buggy
behavior at least didn't break settings already in use (Mark)
FbWinFrame.cc WinButton.cc/hh
* Update window transparency immediately when using pseudotransparency, * Update window transparency immediately when using pseudotransparency,
also introduced new key command: SetAlpha [[+-]<int> [[+-]<int>]] (Mark) also introduced new key command: SetAlpha [[+-]<int> [[+-]<int>]] (Mark)
- with no arguments, returns the focused window to default settings - with no arguments, returns the focused window to default settings
@ -25,9 +29,6 @@ Changes for 1.0rc3:
* Detect user's shell from environment rather than assuming /bin/sh (Mark) * Detect user's shell from environment rather than assuming /bin/sh (Mark)
FbCommands.cc FbCommands.cc
*07/01/21: *07/01/21:
* Allow transparency in window buttons, so they show the titlebar underneath
instead of black (Mark)
WinButton.cc/hh FbWinFrame.cc
* Little fix for closing tabs with non-default gravity (Mark) * Little fix for closing tabs with non-default gravity (Mark)
Window.cc Window.cc
* Several fixes for menu behavior (Mark) * Several fixes for menu behavior (Mark)

View file

@ -34,7 +34,6 @@
#include "Screen.hh" #include "Screen.hh"
#include "Container.hh" #include "Container.hh"
#include "WinButton.hh"
#ifdef SHAPE #ifdef SHAPE
#include "Shape.hh" #include "Shape.hh"
@ -1504,12 +1503,6 @@ void FbWinFrame::init() {
Setups upp background, pressed pixmap/color of the button to current theme Setups upp background, pressed pixmap/color of the button to current theme
*/ */
void FbWinFrame::applyButton(FbTk::Button &btn) { void FbWinFrame::applyButton(FbTk::Button &btn) {
// need to update button first, or it might override this on theme change
if (typeid(btn) == typeid(WinButton)) {
WinButton *tmp = static_cast<WinButton *>(&btn);
tmp->update(0);
}
if (m_button_pressed_pm) if (m_button_pressed_pm)
btn.setPressedPixmap(m_button_pressed_pm); btn.setPressedPixmap(m_button_pressed_pm);
else else

View file

@ -44,10 +44,11 @@ WinButton::WinButton(const FluxboxWindow &listen_to,
FbTk::Button(parent, x, y, width, height), FbTk::Button(parent, x, y, width, height),
m_type(buttontype), m_listen_to(listen_to), m_theme(theme), m_type(buttontype), m_listen_to(listen_to), m_theme(theme),
m_icon_pixmap(0), m_icon_mask(0), m_icon_pixmap(0), m_icon_mask(0),
m_override_bg(false) { overrode_bg(false), overrode_pressed(false) {
theme.reconfigSig().attach(this); theme.reconfigSig().attach(this);
update(0); if (buttontype == MENUICON)
update(0);
} }
void WinButton::exposeEvent(XExposeEvent &event) { void WinButton::exposeEvent(XExposeEvent &event) {
@ -55,39 +56,150 @@ void WinButton::exposeEvent(XExposeEvent &event) {
drawType(); drawType();
} }
void WinButton::buttonPressEvent(XButtonEvent &event) {
FbTk::Button::buttonPressEvent(event);
drawType();
}
void WinButton::buttonReleaseEvent(XButtonEvent &event) { void WinButton::buttonReleaseEvent(XButtonEvent &event) {
FbTk::Button::buttonReleaseEvent(event); FbTk::Button::buttonReleaseEvent(event);
drawType();
} }
// when someone else tries to set the background, we may override it // when someone else tries to set the background, we may override it
void WinButton::setBackgroundPixmap(Pixmap pm) { void WinButton::setBackgroundPixmap(Pixmap pm) {
if (m_override_bg) Pixmap my_pm = getBackgroundPixmap();
return;
if (my_pm != 0) {
overrode_bg = true;
pm = my_pm;
} else {
overrode_bg = false;
}
FbTk::Button::setBackgroundPixmap(pm); FbTk::Button::setBackgroundPixmap(pm);
} }
void WinButton::setBackgroundColor(const FbTk::Color &color) { void WinButton::setBackgroundColor(const FbTk::Color &color) {
if (m_override_bg) Pixmap my_pm = getBackgroundPixmap();
return;
FbTk::Button::setBackgroundColor(color); if (my_pm != 0) {
overrode_bg = true;
FbTk::Button::setBackgroundPixmap(my_pm);
} else {
overrode_bg = false;
FbTk::Button::setBackgroundColor(color);
}
} }
void WinButton::setPressedPixmap(Pixmap pm) { void WinButton::setPressedPixmap(Pixmap pm) {
if (m_override_bg) Pixmap my_pm = getPressedPixmap();
return;
if (my_pm != 0) {
overrode_pressed = true;
pm = my_pm;
} else {
overrode_pressed = false;
}
FbTk::Button::setPressedPixmap(pm); FbTk::Button::setPressedPixmap(pm);
} }
void WinButton::setPressedColor(const FbTk::Color &color) { void WinButton::setPressedColor(const FbTk::Color &color) {
if (m_override_bg) Pixmap my_pm = getPressedPixmap();
return;
FbTk::Button::setPressedColor(color); if (my_pm != 0) {
overrode_pressed = true;
FbTk::Button::setPressedPixmap(my_pm);
} else {
overrode_pressed = false;
FbTk::Button::setPressedColor(color);
}
}
Pixmap WinButton::getBackgroundPixmap() const {
bool focused = m_listen_to.isFocused();
switch(m_type) {
case MAXIMIZE:
if (focused)
return m_theme.maximizePixmap().pixmap().drawable();
else
return m_theme.maximizeUnfocusPixmap().pixmap().drawable();
break;
case MINIMIZE:
if (focused)
return m_theme.iconifyPixmap().pixmap().drawable();
else
return m_theme.iconifyUnfocusPixmap().pixmap().drawable();
break;
case STICK:
if (m_listen_to.isStuck()) {
if (focused)
return m_theme.stuckPixmap().pixmap().drawable();
else
return m_theme.stuckUnfocusPixmap().pixmap().drawable();
} else {
if (focused)
return m_theme.stickPixmap().pixmap().drawable();
else
return m_theme.stickUnfocusPixmap().pixmap().drawable();
}
break;
case CLOSE:
if (focused)
return m_theme.closePixmap().pixmap().drawable();
else
return m_theme.closeUnfocusPixmap().pixmap().drawable();
break;
case SHADE:
if (m_listen_to.isShaded()) {
if (focused)
return m_theme.unshadePixmap().pixmap().drawable();
else
return m_theme.unshadeUnfocusPixmap().pixmap().drawable();
} else {
if (focused)
return m_theme.shadePixmap().pixmap().drawable();
else
return m_theme.shadeUnfocusPixmap().pixmap().drawable();
}
break;
case MENUICON:
if (m_icon_pixmap.drawable()) {
if (focused)
return m_theme.titleFocusPixmap().pixmap().drawable();
else
return m_theme.titleUnfocusPixmap().pixmap().drawable();
} else {
if (focused)
return m_theme.menuiconPixmap().pixmap().drawable();
else
return m_theme.menuiconUnfocusPixmap().pixmap().drawable();
}
break;
}
return None;
}
Pixmap WinButton::getPressedPixmap() const {
switch(m_type) {
case MAXIMIZE:
return m_theme.maximizePressedPixmap().pixmap().drawable();
case MINIMIZE:
return m_theme.iconifyPressedPixmap().pixmap().drawable();
case STICK:
return m_theme.stickPressedPixmap().pixmap().drawable();
case CLOSE:
return m_theme.closePressedPixmap().pixmap().drawable();
case SHADE:
if (m_listen_to.isShaded())
return m_theme.unshadePressedPixmap().pixmap().drawable();
else
return m_theme.shadePressedPixmap().pixmap().drawable();
case MENUICON:
if (m_icon_pixmap.drawable())
if (m_listen_to.isFocused())
return m_theme.titleFocusPixmap().pixmap().drawable();
else
return m_theme.titleUnfocusPixmap().pixmap().drawable();
else
return m_theme.menuiconPressedPixmap().pixmap().drawable();
}
return None;
} }
// clear is used to force this to clear the window (e.g. called from clear()) // clear is used to force this to clear the window (e.g. called from clear())
@ -98,88 +210,44 @@ void WinButton::drawType() {
int oddH = height()%2; int oddH = height()%2;
bool is_pressed = pressed(); bool is_pressed = pressed();
bool focused = m_listen_to.isFocused(); if (is_pressed && overrode_pressed && !m_icon_pixmap.drawable())
return;
if (!is_pressed && overrode_bg && !m_icon_pixmap.drawable())
return;
if (gc() == 0) if (gc() == 0)
return; return;
// check for pixmap in style, otherwise draw old style imagery // otherwise draw old style imagery
FbTk::PixmapWithMask style_pixmap;
switch (m_type) { switch (m_type) {
case MAXIMIZE: case MAXIMIZE:
if (is_pressed) // if no pixmap was used, use old style
style_pixmap = m_theme.maximizePressedPixmap(); if (gc() == 0) // must have valid graphic context
else if (focused) return;
style_pixmap = m_theme.maximizePixmap();
else
style_pixmap = m_theme.maximizeUnfocusPixmap();
if (style_pixmap.pixmap().drawable()) drawRectangle(gc(),
drawIcon(style_pixmap.pixmap(), style_pixmap.mask()); 2, 2, width() - 5, height() - 5);
else { drawLine(gc(),
// if no pixmap was used, use old style 2, 3, width() - 3, 3);
drawRectangle(gc(),
2, 2, width() - 5, height() - 5);
drawLine(gc(),
2, 3, width() - 3, 3);
}
break; break;
case MINIMIZE: case MINIMIZE:
if (is_pressed) drawRectangle(gc(), 2, height() - 5, width() - 5, 2);
style_pixmap = m_theme.iconifyPressedPixmap();
else if (focused)
style_pixmap = m_theme.iconifyPixmap();
else
style_pixmap = m_theme.iconifyUnfocusPixmap();
if (style_pixmap.pixmap().drawable())
drawIcon(style_pixmap.pixmap(), style_pixmap.mask());
else
drawRectangle(gc(), 2, height() - 5, width() - 5, 2);
break; break;
case STICK: case STICK:
if (is_pressed) // width/4 != width/2, so we use /4*2 so that it's properly centred
style_pixmap = m_theme.stickPressedPixmap(); if (m_listen_to.isStuck()) {
else if (m_listen_to.isStuck()) { fillRectangle(gc(),
if (focused) width()/2 - width()/4, height()/2 - height()/4,
style_pixmap = m_theme.stuckPixmap(); width()/4*2 + oddW, height()/4*2 + oddH);
else
style_pixmap = m_theme.stuckUnfocusPixmap();
} else { } else {
if (focused) fillRectangle(gc(),
style_pixmap = m_theme.stickPixmap(); width()/2 - width()/10, height()/2 - height()/10,
else width()/10*2 + oddW, height()/10*2 + oddH);
style_pixmap = m_theme.stickUnfocusPixmap();
}
if (style_pixmap.pixmap().drawable())
drawIcon(style_pixmap.pixmap(), style_pixmap.mask());
else {
// width/4 != width/2, so we use /4*2 so that it's properly centred
if (m_listen_to.isStuck()) {
fillRectangle(gc(),
width()/2 - width()/4, height()/2 - height()/4,
width()/4*2 + oddW, height()/4*2 + oddH);
} else {
fillRectangle(gc(),
width()/2 - width()/10, height()/2 - height()/10,
width()/10*2 + oddW, height()/10*2 + oddH);
}
} }
break; break;
case CLOSE: case CLOSE:
if (is_pressed) drawLine(gc(),
style_pixmap = m_theme.closePressedPixmap(); 2, 2,
else if (focused) width() - 3, height() - 3);
style_pixmap = m_theme.closePixmap();
else
style_pixmap = m_theme.closeUnfocusPixmap();
if (style_pixmap.pixmap().drawable())
drawIcon(style_pixmap.pixmap(), style_pixmap.mask());
else {
drawLine(gc(),
2, 2,
width() - 3, height() - 3);
// I can't figure out why this second one needs a y offset of 1????? // I can't figure out why this second one needs a y offset of 1?????
// but it does - at least on my box: // but it does - at least on my box:
// XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825) // XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825)
@ -191,62 +259,46 @@ void WinButton::drawType() {
// XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728) // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728)
// (X Protocol Version 11, Revision 0, Release 6.6) // (X Protocol Version 11, Revision 0, Release 6.6)
drawLine(gc(), drawLine(gc(),
2, height() - 3, 2, height() - 3,
width() - 3, 2); width() - 3, 2);
}
break; break;
case SHADE: case SHADE:
if (is_pressed) {
if (m_listen_to.isShaded())
style_pixmap = m_theme.unshadePressedPixmap();
else
style_pixmap = m_theme.shadePressedPixmap();
} else if (m_listen_to.isShaded()) {
if (focused)
style_pixmap = m_theme.unshadePixmap();
else
style_pixmap = m_theme.unshadeUnfocusPixmap();
} else {
if (focused)
style_pixmap = m_theme.shadePixmap();
else
style_pixmap = m_theme.shadeUnfocusPixmap();
}
if (style_pixmap.pixmap().drawable()) {
drawIcon(style_pixmap.pixmap(), style_pixmap.mask()); int size = width() - 5 - oddW;
else {
int size = width() - 5 - oddW;
drawRectangle(gc(), 2, 2, size, 2); drawRectangle(gc(), 2, 2, size, 2);
// draw a one-quarter triangle below the rectangle
drawTriangle(gc(), (m_listen_to.isShaded() ?
FbTk::FbDrawable::DOWN:
FbTk::FbDrawable::UP),
4, 6,
size-2, size/2 - 1,
100);
// draw a one-quarter triangle below the rectangle
drawTriangle(gc(), (m_listen_to.isShaded() ?
FbTk::FbDrawable::DOWN:
FbTk::FbDrawable::UP),
4, 6,
size-2, size/2 - 1,
100);
}
break; break;
}
case MENUICON: case MENUICON:
// if we got an icon from the window, use it instead
if (m_icon_pixmap.drawable()) { if (m_icon_pixmap.drawable()) {
drawIcon(m_icon_pixmap, m_icon_mask);
return;
}
if (is_pressed) if (m_icon_mask.drawable()) {
style_pixmap = m_theme.menuiconPressedPixmap(); XSetClipMask(m_listen_to.fbWindow().display(),
else if (focused) gc(), m_icon_mask.drawable());
style_pixmap = m_theme.menuiconPixmap(); XSetClipOrigin(m_listen_to.fbWindow().display(),
else gc(), 2, 2);
style_pixmap = m_theme.menuiconUnfocusPixmap(); }
copyArea(m_icon_pixmap.drawable(),
gc(),
0, 0,
2, 2,
m_icon_pixmap.width(), m_icon_pixmap.height());
if (style_pixmap.pixmap().drawable()) if (m_icon_mask.drawable())
drawIcon(style_pixmap.pixmap(), style_pixmap.mask()); XSetClipMask(m_listen_to.fbWindow().display(), gc(), None);
else { } else {
for (unsigned int y = height()/3; y <= height() - height()/3; y+=3) { for (unsigned int y = height()/3; y <= height() - height()/3; y+=3) {
drawLine(gc(), width()/4, y, width() - width()/4 - oddW - 1, y); drawLine(gc(), width()/4, y, width() - width()/4 - oddW - 1, y);
} }
@ -257,24 +309,6 @@ void WinButton::drawType() {
} }
} }
void WinButton::drawIcon(FbTk::FbPixmap icon, FbTk::FbPixmap mask) {
if (mask.drawable()) {
XSetClipMask(m_listen_to.fbWindow().display(),
gc(), mask.drawable());
XSetClipOrigin(m_listen_to.fbWindow().display(),
gc(), 0, 0);
}
copyArea(icon.drawable(),
gc(),
0, 0,
0, 0,
icon.width(), icon.height());
if (mask.drawable())
XSetClipMask(m_listen_to.fbWindow().display(), gc(), None);
}
void WinButton::clear() { void WinButton::clear() {
FbTk::Button::clear(); FbTk::Button::clear();
drawType(); drawType();
@ -290,13 +324,13 @@ void WinButton::update(FbTk::Subject *subj) {
if (m_listen_to.usePixmap()) { if (m_listen_to.usePixmap()) {
m_icon_pixmap.copy(m_listen_to.iconPixmap().drawable(), m_icon_pixmap.copy(m_listen_to.iconPixmap().drawable(),
DefaultDepth(display, screen), screen); DefaultDepth(display, screen), screen);
m_icon_pixmap.scale(width(), height()); m_icon_pixmap.scale(width() - 4, height() - 4);
} else } else
m_icon_pixmap.release(); m_icon_pixmap.release();
if (m_listen_to.useMask()) { if (m_listen_to.useMask()) {
m_icon_mask.copy(m_listen_to.iconMask().drawable(), 0, 0); m_icon_mask.copy(m_listen_to.iconMask().drawable(), 0, 0);
m_icon_mask.scale(width(), height()); m_icon_mask.scale(width() - 4, height() - 4);
} else } else
m_icon_mask.release(); m_icon_mask.release();
@ -304,19 +338,17 @@ void WinButton::update(FbTk::Subject *subj) {
// pressed_pixmap isn't stateful in any current buttons, so no need // pressed_pixmap isn't stateful in any current buttons, so no need
// to potentially override that. Just make sure background pm is ok // to potentially override that. Just make sure background pm is ok
Pixmap my_pm; Pixmap my_pm = getBackgroundPixmap();
if (m_listen_to.isFocused()) if (my_pm != None)
my_pm = m_theme.titleFocusPixmap().pixmap().drawable(); setBackgroundPixmap(my_pm);
else
my_pm = m_theme.titleUnfocusPixmap().pixmap().drawable();
if (my_pm == None) // incorrect, pressed_pixmap is stateful in shade, so we'll do oneoff for now
m_override_bg = false; if (m_type == SHADE) {
else { Pixmap p_pm = getPressedPixmap();
FbTk::Button::setPressedPixmap(my_pm); if (p_pm != None)
FbTk::Button::setBackgroundPixmap(my_pm); setPressedPixmap(p_pm);
m_override_bg = true;
} }
clear(); clear();
} }

View file

@ -44,17 +44,17 @@ public:
/// override for drawing /// override for drawing
void exposeEvent(XExposeEvent &event); void exposeEvent(XExposeEvent &event);
void buttonReleaseEvent(XButtonEvent &event); void buttonReleaseEvent(XButtonEvent &event);
void buttonPressEvent(XButtonEvent &event);
void setBackgroundPixmap(Pixmap pm); void setBackgroundPixmap(Pixmap pm);
void setPressedPixmap(Pixmap pm); void setPressedPixmap(Pixmap pm);
void setBackgroundColor(const FbTk::Color &color); void setBackgroundColor(const FbTk::Color &color);
void setPressedColor(const FbTk::Color &color); void setPressedColor(const FbTk::Color &color);
Pixmap getBackgroundPixmap() const;
Pixmap getPressedPixmap() const;
/// override for redrawing /// override for redrawing
void clear(); void clear();
void update(FbTk::Subject *subj); void update(FbTk::Subject *subj);
private: private:
void drawIcon(FbTk::FbPixmap icon, FbTk::FbPixmap mask);
void drawType(); void drawType();
Type m_type; ///< the button type Type m_type; ///< the button type
const FluxboxWindow &m_listen_to; const FluxboxWindow &m_listen_to;
@ -62,6 +62,6 @@ private:
FbTk::FbPixmap m_icon_pixmap; FbTk::FbPixmap m_icon_pixmap;
FbTk::FbPixmap m_icon_mask; FbTk::FbPixmap m_icon_mask;
bool m_override_bg; bool overrode_bg, overrode_pressed;
}; };