diff options
Diffstat (limited to 'src/WinButton.cc')
-rw-r--r-- | src/WinButton.cc | 380 |
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 | ||
29 | WinButton::WinButton(const FluxboxWindow &listen_to, | 30 | WinButton::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 | ||
40 | void WinButton::exposeEvent(XExposeEvent &event) { | 42 | void WinButton::exposeEvent(XExposeEvent &event) { |
41 | FbTk::Button::exposeEvent(event); | 43 | FbTk::Button::exposeEvent(event); |
42 | drawType(false, false); | 44 | drawType(); |
43 | } | 45 | } |
44 | 46 | ||
45 | void WinButton::buttonReleaseEvent(XButtonEvent &event) { | 47 | void 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 |
50 | void WinButton::drawType(bool clear, bool no_trans) { | 52 | void 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(), | 65 | void 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 | } | 77 | void 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 | } | 90 | void 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) { | 102 | Pixmap 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 | 148 | Pixmap 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()) |
165 | void 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 | ||
288 | void WinButton::clear() { | 233 | void WinButton::clear() { |
289 | drawType(true, true); | 234 | FbTk::Button::clear(); |
235 | drawType(); | ||
290 | } | 236 | } |
291 | 237 | ||
292 | void WinButton::update(FbTk::Subject *subj) { | 238 | void WinButton::update(FbTk::Subject *subj) { |