1 // ---------------------------------------------------------------------------------
2 //
3 // Copyright (C) 2003-2013 Fons Adriaensen <fons@linuxaudio.org>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //
19 // ---------------------------------------------------------------------------------
20
21
22 #include "clxclient.h"
23
24
X_button(X_window * parent,X_callback * callb,X_button_style * style,int xp,int yp,int cbid)25 X_button::X_button (X_window *parent,
26 X_callback *callb,
27 X_button_style *style,
28 int xp, int yp,
29 int cbid) :
30 X_window (parent, xp, yp, style->size.x, style->size.y, style->color.shadow.bgnd),
31 _style (style),
32 _callb (callb),
33 _xs (style->size.x),
34 _ys (style->size.y),
35 _cbid (cbid),
36 _down (0),
37 _stat (0)
38 {
39 x_add_events (ExposureMask);
40 if (_callb) x_add_events (ButtonPressMask | ButtonReleaseMask | Button1MotionMask | LeaveWindowMask);
41 }
42
43
~X_button(void)44 X_button::~X_button (void)
45 {
46 }
47
48
handle_event(XEvent * E)49 void X_button::handle_event (XEvent *E)
50 {
51 switch (E->type)
52 {
53 case Expose:
54 expose ((XExposeEvent *) E);
55 break;
56
57 case ButtonPress:
58 bpress ((XButtonEvent *) E);
59 break;
60
61 case ButtonRelease:
62 brelease ((XButtonEvent *) E);
63 break;
64
65 case MotionNotify:
66 _callb->handle_callb (X_callback::BUTTON | MOVE, this, E);
67 break;
68
69 case LeaveNotify:
70 release ();
71 break;
72 }
73 }
74
75
bpress(XButtonEvent * E)76 void X_button::bpress (XButtonEvent *E)
77 {
78 _down = 1;
79 redraw ();
80 _callb->handle_callb (X_callback::BUTTON | PRESS, this, (XEvent *) E);
81 }
82
83
brelease(XButtonEvent * E)84 void X_button::brelease (XButtonEvent *E)
85 {
86 _down = 0;
87 redraw ();
88 _callb->handle_callb (X_callback::BUTTON | RELSE, this, (XEvent *) E);
89 }
90
91
expose(XExposeEvent * E)92 void X_button::expose (XExposeEvent *E)
93 {
94 if (E->count == 0) redraw ();
95 }
96
97
release(void)98 void X_button::release (void)
99 {
100 if (_style->type & X_button_style::HOLDPTR) return;
101 XUngrabPointer (dpy (), CurrentTime);
102 _down = 0;
103 redraw ();
104 }
105
106
set_stat(int stat)107 void X_button::set_stat (int stat)
108 {
109 if (_stat != stat)
110 {
111 _stat = stat;
112 redraw ();
113 }
114 }
115
116
redraw(void)117 void X_button::redraw (void)
118 {
119 GC gc = disp ()->dgc ();
120
121 XSetFunction (dpy (), gc, GXcopy);
122 XSetLineAttributes (dpy (), gc, 0, LineSolid, CapButt, JoinBevel);
123 switch (_style->type & 3)
124 {
125 case X_button_style::RAISED:
126 XSetForeground (dpy (), gc, _down ? _style->color.shadow.dark : _style->color.shadow.lite);
127 XDrawLine (dpy (), win (), gc, 0, 0, 0, _ys - 2);
128 XDrawLine (dpy (), win (), gc, 0, 0, _xs - 2, 0);
129 XSetForeground (dpy (), gc, _down ? _style->color.shadow.lite : _style->color.shadow.dark);
130 XDrawLine (dpy (), win (), gc, _xs - 1, 1, _xs - 1, _ys);
131 XDrawLine (dpy (), win (), gc, 1, _ys - 1, _xs, _ys - 1);
132 XSetForeground (dpy (), gc, _style->color.shadow.bgnd);
133 XDrawPoint (dpy (), win (), gc, 0, _ys - 1);
134 XDrawPoint (dpy (), win (), gc, _xs - 1, 0);
135 break;
136 }
137 }
138
139
140
X_tbutton(X_window * parent,X_callback * callb,X_button_style * style,int xp,int yp,const char * text1,const char * text2,int cbid)141 X_tbutton::X_tbutton (X_window *parent,
142 X_callback *callb,
143 X_button_style *style,
144 int xp,
145 int yp,
146 const char *text1,
147 const char *text2,
148 int cbid) :
149 X_button (parent, callb, style, xp, yp, cbid),
150 _bg (0),
151 _fg (0),
152 _len1 (0),
153 _len2 (0)
154 {
155 set_text (text1, text2);
156 }
157
158
~X_tbutton(void)159 X_tbutton::~X_tbutton (void)
160 {
161 }
162
163
set_text(const char * text1,const char * text2)164 void X_tbutton::set_text (const char *text1, const char *text2)
165 {
166 _len1 = 0;
167 _len2 = 0;
168 if (text1) while (((*(unsigned char *) text1) >= ' ') && (_len1 < MAXLEN - 1)) _text1 [_len1++] = *text1++;
169 if (text2) while (((*(unsigned char *) text2) >= ' ') && (_len2 < MAXLEN - 1)) _text2 [_len2++] = *text2++;
170 _text1 [_len1] = 0;
171 _text2 [_len2] = 0;
172 }
173
174
redraw(void)175 void X_tbutton::redraw (void)
176 {
177 int a, d, u, x, y;
178 GC G = dgc ();
179 XftDraw *D = xft ();
180 XftColor *C;
181 XftFont *F = _style->font;
182 XGlyphInfo K;
183 unsigned long b;
184
185 XftDrawChange (D, win ());
186 XSetFunction (dpy (), G, GXcopy);
187 b = (_stat > 3) ? _bg : _style->color.bg [_stat];
188 XSetForeground (dpy (), G, b);
189 XFillRectangle (dpy (), win (), G, 0, 0, _xs, _ys);
190
191 a = F->ascent;
192 d = F->descent;
193 u = a + d - _ys / 2;
194 if (u < 0) u = 0;
195
196 C = (_stat > 3) ? _fg : _style->color.fg [_stat];
197 if (_len1)
198 {
199 y = (_len2) ? _ys / 2 - d + u : (_ys + a - d) / 2;
200 if (_style->type & X_button_style::ALEFT) x = 6;
201 else
202 {
203 XftTextExtentsUtf8 (dpy (), F, (const FcChar8 *) _text1, _len1, &K);
204 if (_style->type & X_button_style::ARIGHT) x = _xs - K.width - 6;
205 else x = (_xs - K.width) / 2;
206 }
207 if (_down) { x += 1; y += 1; }
208 XftDrawStringUtf8 (D, C, F, x, y, (const FcChar8 *) _text1, _len1);
209 }
210 if (_len2)
211 {
212 y = (_len1) ? _ys / 2 + a - u : (_ys + a - d) / 2;
213 if (_style->type & X_button_style::ALEFT) x = 6;
214 else
215 {
216 XftTextExtentsUtf8 (dpy (), F, (const FcChar8 *) _text2, _len2, &K);
217 if (_style->type & X_button_style::ARIGHT) x = _xs - K.width - 6;
218 else x = (_xs - K.width) / 2;
219 }
220 if (_down) { x += 1; y += 1; }
221 XftDrawStringUtf8 (D, C, F, x, y, (const FcChar8 *) _text2, _len2);
222 }
223 if ((_style->type & 3) == X_button_style::BORDER)
224 {
225 XSetLineAttributes (dpy (), G, 1, LineSolid, CapButt, JoinBevel);
226 XSetForeground (dpy (), G, C->pixel);
227 XDrawRectangle (dpy (), win (), G, 0, 0, _xs - 1, _ys - 1);
228 }
229 else X_button::redraw ();
230 }
231
232
233
X_ibutton(X_window * parent,X_callback * callb,X_button_style * style,int xp,int yp,XImage * image,int cbid)234 X_ibutton::X_ibutton (X_window *parent,
235 X_callback *callb,
236 X_button_style *style,
237 int xp,
238 int yp,
239 XImage *image,
240 int cbid) :
241 X_button (parent, callb, style, xp, yp, cbid),
242 _bg (0),
243 _fg (0),
244 _image (image)
245 {
246 }
247
248
~X_ibutton(void)249 X_ibutton::~X_ibutton (void)
250 {
251 }
252
253
redraw(void)254 void X_ibutton::redraw (void)
255 {
256 int x, y;
257 unsigned long b, f;
258
259 b = (_stat > 3) ? _bg : _style->color.bg [_stat];
260 f = (_stat > 3) ? _fg : _style->color.fg [_stat]->pixel;
261 XSetState (dpy (), dgc (), f, b, GXcopy, ~0);
262 XSetWindowBackground (dpy (), win (), b);
263 XClearWindow (dpy (), win ());
264 if (_image)
265 {
266 x = (_xs - _image->width) / 2;
267 y = (_ys - _image->height) / 2;
268 XPutImage (dpy (), win (), dgc (), _image, 0, 0, x, y, _xs, _ys);
269 }
270 if ((_style->type & 3) == X_button_style::BORDER)
271 {
272 XSetLineAttributes (dpy (), dgc (), 1, LineSolid, CapButt, JoinBevel);
273 XSetForeground (dpy (), dgc (), f);
274 XDrawRectangle (dpy (), win (), dgc (), 0, 0, _xs - 1, _ys - 1);
275 }
276 else X_button::redraw ();
277 }
278
279
280
X_pbutton(X_window * parent,X_callback * callb,X_button_style * style,int xp,int yp,Pixmap map0,Pixmap map1,int cbid)281 X_pbutton::X_pbutton (X_window *parent,
282 X_callback *callb,
283 X_button_style *style,
284 int xp, int yp,
285 Pixmap map0,
286 Pixmap map1,
287 int cbid) :
288 X_button (parent, callb, style, xp, yp, cbid),
289 _map0 (map0),
290 _map1 (map1)
291 {
292 if (_map0) XSetWindowBackgroundPixmap (dpy (), win (), _map0);
293 }
294
295
~X_pbutton(void)296 X_pbutton::~X_pbutton (void)
297 {
298 }
299
300
set_stat(bool stat)301 void X_pbutton::set_stat (bool stat)
302 {
303 if (_stat != stat)
304 {
305 if (_map1) XSetWindowBackgroundPixmap (dpy (), win (), stat ? _map1 : _map0);
306 _stat = stat;
307 XClearWindow (dpy (), win ());
308 X_button::redraw ();
309 }
310 }
311
312