aboutsummaryrefslogtreecommitdiff
path: root/src/WinButton.cc
diff options
context:
space:
mode:
authorsimonb <simonb>2005-04-10 18:18:14 (GMT)
committersimonb <simonb>2005-04-10 18:18:14 (GMT)
commit88c66f0687d2a9e2018f22407b2587dc4d87d012 (patch)
tree197308ad2426783058f479d12329548c6a8a4374 /src/WinButton.cc
parent6cf66c66554a20a1c98eddf26af9e35b7c90cbd5 (diff)
downloadfluxbox-88c66f0687d2a9e2018f22407b2587dc4d87d012.zip
fluxbox-88c66f0687d2a9e2018f22407b2587dc4d87d012.tar.bz2
Big changes to how transparency works
Consequently rearrange lots of rendering ops, and strip calls to updateTransparent
Diffstat (limited to 'src/WinButton.cc')
-rw-r--r--src/WinButton.cc380
1 files changed, 163 insertions, 217 deletions
diff --git a/src/WinButton.cc b/src/WinButton.cc
index f9e6fe2..9ae2593 100644
--- a/src/WinButton.cc
+++ b/src/WinButton.cc
@@ -25,6 +25,7 @@
25#include "App.hh" 25#include "App.hh"
26#include "Window.hh" 26#include "Window.hh"
27#include "WinButtonTheme.hh" 27#include "WinButtonTheme.hh"
28#include "FbTk/Color.hh"
28 29
29WinButton::WinButton(const FluxboxWindow &listen_to, 30WinButton::WinButton(const FluxboxWindow &listen_to,
30 WinButtonTheme &theme, 31 WinButtonTheme &theme,
@@ -32,261 +33,206 @@ WinButton::WinButton(const FluxboxWindow &listen_to,
32 int x, int y, 33 int x, int y,
33 unsigned int width, unsigned int height): 34 unsigned int width, unsigned int height):
34 FbTk::Button(parent, x, y, width, height), 35 FbTk::Button(parent, x, y, width, height),
35 m_type(buttontype), m_listen_to(listen_to), m_theme(theme) { 36 m_type(buttontype), m_listen_to(listen_to), m_theme(theme),
37 overrode_bg(false), overrode_pressed(false) {
36 38
37 theme.reconfigSig().attach(this); 39 theme.reconfigSig().attach(this);
38} 40}
39 41
40void WinButton::exposeEvent(XExposeEvent &event) { 42void WinButton::exposeEvent(XExposeEvent &event) {
41 FbTk::Button::exposeEvent(event); 43 FbTk::Button::exposeEvent(event);
42 drawType(false, false); 44 drawType();
43} 45}
44 46
45void WinButton::buttonReleaseEvent(XButtonEvent &event) { 47void WinButton::buttonReleaseEvent(XButtonEvent &event) {
46 FbTk::Button::buttonReleaseEvent(event); 48 FbTk::Button::buttonReleaseEvent(event);
47} 49}
48 50
49// clear is used to force this to clear the window (e.g. called from clear()) 51// when someone else tries to set the background, we may override it
50void WinButton::drawType(bool clear, bool no_trans) { 52void WinButton::setBackgroundPixmap(Pixmap pm) {
51 bool used = false; 53 Pixmap my_pm = getBackgroundPixmap();
52 54
53 // if it's odd and we're centring, we need to add one 55 if (my_pm != 0) {
54 int oddW = width()%2; 56 overrode_bg = true;
55 int oddH = height()%2; 57 pm = my_pm;
56 58 } else {
57 switch (m_type) { 59 overrode_bg = false;
58 case MAXIMIZE: 60 }
59 61
60 if (pressed() && m_theme.maximizePressedPixmap().pixmap().drawable() != 0) { 62 FbTk::Button::setBackgroundPixmap(pm);
61 FbTk::FbWindow::setBackgroundPixmap(m_theme. 63}
62 maximizePressedPixmap().
63 pixmap().drawable());
64 used = true;
65 } else {
66 // check focus
67 if (!m_listen_to.isFocused()) {
68 if (m_theme.maximizeUnfocusPixmap().pixmap().drawable() != 0) {
69 // not focused
70 FbTk::FbWindow::setBackgroundPixmap(m_theme.
71 maximizeUnfocusPixmap().
72 pixmap().drawable());
73 used = true;
74 }
75 } else if (m_theme.maximizePixmap().pixmap().drawable() != 0) {
76 FbTk::FbWindow::setBackgroundPixmap(m_theme.
77 maximizePixmap().
78 pixmap().drawable());
79 used = true;
80 }
81 }
82 if (used || clear)
83 FbTk::FbWindow::clear();
84
85 // if no pixmap was used, use old style
86 if (!used) {
87 if (gc() == 0) // must have valid graphic context
88 return;
89 64
90 drawRectangle(gc(), 65void WinButton::setBackgroundColor(const FbTk::Color &color) {
91 2, 2, width() - 5, height() - 5); 66 Pixmap my_pm = getBackgroundPixmap();
92 drawLine(gc(),
93 2, 3, width() - 3, 3);
94 }
95 break;
96 case MINIMIZE:
97 67
98 if (pressed() && m_theme.iconifyPressedPixmap().pixmap().drawable() != 0) { 68 if (my_pm != 0) {
99 FbTk::FbWindow::setBackgroundPixmap(m_theme. 69 overrode_bg = true;
100 iconifyPressedPixmap(). 70 FbTk::Button::setBackgroundPixmap(my_pm);
101 pixmap().drawable()); 71 } else {
102 used = true; 72 overrode_bg = false;
103 } else { 73 FbTk::Button::setBackgroundColor(color);
104 if (m_theme.iconifyPixmap().pixmap().drawable()){ 74 }
105 // check focus 75}
106 if (!m_listen_to.isFocused()) {
107 if (m_theme.iconifyUnfocusPixmap().pixmap().drawable() != 0) {
108 // not focused
109 FbTk::FbWindow::setBackgroundPixmap(m_theme.
110 iconifyUnfocusPixmap().
111 pixmap().drawable());
112 used = true;
113 }
114 } else if (m_theme.iconifyPixmap().pixmap().drawable() != 0) {
115 FbTk::FbWindow::setBackgroundPixmap(m_theme.
116 iconifyPixmap().
117 pixmap().drawable());
118 used = true;
119 }
120 }
121 76
122 } 77void WinButton::setPressedPixmap(Pixmap pm) {
78 Pixmap my_pm = getPressedPixmap();
123 79
124 if (used || clear) { 80 if (my_pm != 0) {
125 FbTk::FbWindow::clear(); 81 overrode_pressed = true;
126 } 82 pm = my_pm;
127 if (!used && gc() != 0) { // must have valid graphic context 83 } else {
128 FbTk::FbWindow::drawRectangle(gc(), 84 overrode_pressed = false;
129 2, height() - 5, width() - 5, 2); 85 }
130 }
131 break;
132 case STICK:
133 86
134 if (m_listen_to.isStuck() && !pressed()) { 87 FbTk::Button::setBackgroundPixmap(pm);
135 if ( m_theme.stuckPixmap().pixmap().drawable() && 88}
136 ! pressed()) { // we're using the same pixmap for pressed as in not stuck
137 // check focus
138 if (!m_listen_to.isFocused()) {
139 if ( m_theme.stuckUnfocusPixmap().pixmap().drawable() != 0) {
140 // not focused
141 FbTk::FbWindow::setBackgroundPixmap(m_theme.
142 stuckUnfocusPixmap().
143 pixmap().drawable());
144 used = true;
145 }
146 } else if (m_theme.stuckPixmap().pixmap().drawable() != 0) {
147 // focused
148 FbTk::FbWindow::setBackgroundPixmap(m_theme.
149 stuckPixmap().
150 pixmap().drawable());
151 used = true;
152 }
153 }
154 } else { // not stuck and pressed
155 if (pressed()) {
156 if (m_theme.stickPressedPixmap().pixmap().drawable() != 0) {
157 FbTk::FbWindow::setBackgroundPixmap(m_theme.
158 stickPressedPixmap().
159 pixmap().drawable());
160 used = true;
161 }
162 } else { // not pressed
163 // check focus
164 if (!m_listen_to.isFocused()) {
165 if (m_theme.stickUnfocusPixmap().pixmap().drawable() != 0) {
166 // not focused
167 FbTk::FbWindow::setBackgroundPixmap(m_theme.
168 stickUnfocusPixmap().
169 pixmap().drawable());
170 used = true;
171 }
172 } else if (m_theme.stickPixmap().pixmap().drawable()) { // focused
173 FbTk::FbWindow::setBackgroundPixmap(m_theme.
174 stickPixmap().
175 pixmap().drawable());
176 used = true;
177 }
178 89
179 } 90void WinButton::setPressedColor(const FbTk::Color &color) {
180 91 Pixmap my_pm = getPressedPixmap();
181 }
182 92
183 if (used || clear) 93 if (my_pm != 0) {
184 FbTk::FbWindow::clear(); 94 overrode_pressed = true;
95 FbTk::Button::setPressedPixmap(my_pm);
96 } else {
97 overrode_pressed = false;
98 FbTk::Button::setPressedColor(color);
99 }
100}
185 101
186 if (!used && gc() != 0) { 102Pixmap WinButton::getBackgroundPixmap() const {
187 // width/4 != width/2, so we use /4*2 so that it's properly centred 103 bool focused = m_listen_to.isFocused();
188 if (m_listen_to.isStuck()) { 104 switch(m_type) {
189 fillRectangle(gc(), 105 case MAXIMIZE:
190 width()/2 - width()/4, height()/2 - height()/4, 106 if (focused)
191 width()/4*2 + oddW, height()/4*2 + oddH); 107 return m_theme.maximizePixmap().pixmap().drawable();
192 } else { 108 else
193 fillRectangle(gc(), 109 return m_theme.maximizeUnfocusPixmap().pixmap().drawable();
194 width()/2 - width()/10, height()/2 - height()/10, 110 break;
195 width()/10*2 + oddW, height()/10*2 + oddH); 111 case MINIMIZE:
196 } 112 if (focused)
113 return m_theme.iconifyPixmap().pixmap().drawable();
114 else
115 return m_theme.iconifyUnfocusPixmap().pixmap().drawable();
116 break;
117 case STICK: {
118 bool stuck = m_listen_to.isStuck();
119 if (stuck) {
120 if (focused)
121 return m_theme.stuckPixmap().pixmap().drawable();
122 else
123 return m_theme.stuckUnfocusPixmap().pixmap().drawable();
124 } else {
125 if (focused)
126 return m_theme.stickPixmap().pixmap().drawable();
127 else
128 return m_theme.stickUnfocusPixmap().pixmap().drawable();
197 } 129 }
130 }
198 break; 131 break;
199 case CLOSE: 132 case CLOSE:
200 133 if (focused)
201 if (pressed()) { 134 return m_theme.closePixmap().pixmap().drawable();
202 if (m_theme.closePressedPixmap().pixmap().drawable()) { 135 else
203 FbTk::FbWindow::setBackgroundPixmap(m_theme. 136 return m_theme.closeUnfocusPixmap().pixmap().drawable();
204 closePressedPixmap(). 137 break;
205 pixmap().drawable()); 138 case SHADE:
206 used = true; 139 if (focused)
207 } 140 return m_theme.shadePixmap().pixmap().drawable();
208 } else { // not pressed 141 else
209 // check focus 142 return m_theme.shadeUnfocusPixmap().pixmap().drawable();
210 if (!m_listen_to.isFocused()) { 143 break;
211 if (m_theme.closeUnfocusPixmap().pixmap().drawable() != 0) { 144 }
212 // not focused 145 return None;
213 FbTk::FbWindow::setBackgroundPixmap(m_theme. 146}
214 closeUnfocusPixmap().
215 pixmap().drawable());
216 used = true;
217 }
218 } else if (m_theme.closePixmap().pixmap().drawable() != 0) { // focused
219 FbTk::FbWindow::setBackgroundPixmap(m_theme.
220 closePixmap().
221 pixmap().drawable());
222 used = true;
223 }
224 }
225 147
226 148Pixmap WinButton::getPressedPixmap() const {
227 if (used || clear) 149 switch(m_type) {
228 FbTk::FbWindow::clear(); 150 case MAXIMIZE:
151 return m_theme.maximizePressedPixmap().pixmap().drawable();
152 case MINIMIZE:
153 return m_theme.iconifyPressedPixmap().pixmap().drawable();
154 case STICK:
155 return m_theme.stickPressedPixmap().pixmap().drawable();
156 case CLOSE:
157 return m_theme.closePressedPixmap().pixmap().drawable();
158 case SHADE:
159 return m_theme.shadePressedPixmap().pixmap().drawable();
160 }
161 return None;
162}
229 163
230 if (!used && gc() != 0) { // must have valid graphic context 164// clear is used to force this to clear the window (e.g. called from clear())
165void WinButton::drawType() {
166 bool used = false;
231 167
232 drawLine(gc(), 168 // if it's odd and we're centring, we need to add one
233 2, 2, 169 int oddW = width()%2;
234 width() - 3, height() - 3); 170 int oddH = height()%2;
235 // I can't figure out why this second one needs a y offset of 1????? 171
236 // but it does - at least on my box: 172 bool is_pressed = pressed();
237 // XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825) 173 if (is_pressed && overrode_pressed)
238 // (protocol Version 11, revision 0, vendor release 6600) 174 return;
239 // But not on mine? It's wonky. Put back to the same coords. 175 if (!is_pressed && overrode_bg)
240 // was width-2, 1 in the second drawline 176 return;
241 // Perhaps some X versions don't draw the endpoint? 177 if (gc() == 0)
242 // Mine: 178 return;
243 // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728)
244 // (X Protocol Version 11, Revision 0, Release 6.6)
245 179
180 // otherwise draw old style imagery
181 switch (m_type) {
182 case MAXIMIZE:
183 // if no pixmap was used, use old style
184 if (gc() == 0) // must have valid graphic context
185 return;
246 186
247 drawLine(gc(), 187 drawRectangle(gc(),
248 2, height() - 3, 188 2, 2, width() - 5, height() - 5);
249 width() - 3, 2); 189 drawLine(gc(),
190 2, 3, width() - 3, 3);
191 break;
192 case MINIMIZE:
193 FbTk::FbWindow::drawRectangle(gc(),
194 2, height() - 5, width() - 5, 2);
195 break;
196 case STICK:
197 // width/4 != width/2, so we use /4*2 so that it's properly centred
198 if (m_listen_to.isStuck()) {
199 fillRectangle(gc(),
200 width()/2 - width()/4, height()/2 - height()/4,
201 width()/4*2 + oddW, height()/4*2 + oddH);
202 } else {
203 fillRectangle(gc(),
204 width()/2 - width()/10, height()/2 - height()/10,
205 width()/10*2 + oddW, height()/10*2 + oddH);
250 } 206 }
251 break; 207 break;
208 case CLOSE:
209 drawLine(gc(),
210 2, 2,
211 width() - 3, height() - 3);
212 // I can't figure out why this second one needs a y offset of 1?????
213 // but it does - at least on my box:
214 // XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825)
215 // (protocol Version 11, revision 0, vendor release 6600)
216 // But not on mine? It's wonky. Put back to the same coords.
217 // was width-2, 1 in the second drawline
218 // Perhaps some X versions don't draw the endpoint?
219 // Mine:
220 // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728)
221 // (X Protocol Version 11, Revision 0, Release 6.6)
222
223 drawLine(gc(),
224 2, height() - 3,
225 width() - 3, 2);
226 break;
252 case SHADE: 227 case SHADE:
253 228 // no cute image defined
254 if (pressed()) {
255 if (m_theme.shadePressedPixmap().pixmap().drawable()) {
256 FbTk::FbWindow::setBackgroundPixmap(m_theme.
257 shadePressedPixmap().
258 pixmap().drawable());
259 used = true;
260 }
261 } else { // not pressed
262 // check focus
263 if (!m_listen_to.isFocused()) {
264 if ( m_theme.shadeUnfocusPixmap().pixmap().drawable() != 0) {
265 // not focused
266 FbTk::FbWindow::setBackgroundPixmap(m_theme.
267 shadeUnfocusPixmap().
268 pixmap().drawable());
269 used = true;
270 }
271 } else if (m_theme.shadePixmap().pixmap().drawable() != 0) { // focused
272 FbTk::FbWindow::setBackgroundPixmap(m_theme.
273 shadePixmap().
274 pixmap().drawable());
275 used = true;
276 }
277 }
278
279 if (used || clear)
280 FbTk::FbWindow::clear();
281
282 break; 229 break;
283 } 230 }
284 // if ((used || clear) && !no_trans)
285 updateTransparent();
286} 231}
287 232
288void WinButton::clear() { 233void WinButton::clear() {
289 drawType(true, true); 234 FbTk::Button::clear();
235 drawType();
290} 236}
291 237
292void WinButton::update(FbTk::Subject *subj) { 238void WinButton::update(FbTk::Subject *subj) {