1
2 /*
3 * Diverse Bristol audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 /*
23 * This will be a highlighted button. Primarily used for the Bit emulators.
24 */
25
26 #include <math.h>
27
28 #include "brightoninternals.h"
29
30 extern int brightonPanelLocation();
31
32 char *tbm;
33
34 int
destroyHButton(brightonDevice * dev)35 destroyHButton(brightonDevice *dev)
36 {
37 printf("destroyHButton()\n");
38
39 if (dev->image)
40 brightonFreeBitmap(dev->bwin, dev->image);
41 if (dev->image2)
42 brightonFreeBitmap(dev->bwin, dev->image2);
43 dev->image = NULL;
44 dev->image2 = NULL;
45
46 return(0);
47 }
48
49 static void
displayhbutton(brightonDevice * dev)50 displayhbutton(brightonDevice *dev)
51 {
52 int flags = dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags;
53
54 if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN)
55 return;
56
57 if (flags & BRIGHTON_WITHDRAWN)
58 return;
59
60 /*
61 * This is not needed except for moving parts - sliders primarily, but
62 * also touch panels. Rotary and hbuttons are located and stay that way.
63 */
64 brightonDevUndraw(dev->bwin, dev->bwin->dlayer,
65 dev->x + dev->bwin->app->resources[dev->panel].sx,
66 dev->y + ((int) dev->lastposition)
67 + dev->bwin->app->resources[dev->panel].sy,
68 dev->width, dev->height);
69
70 /*
71 if (dev->value)
72 id = brightonPut(dev->bwin, "bitmaps/buttons/green.xpm",
73 dev->x, dev->y, dev->width, dev->height);
74 else
75 brightonRemove(dev->bwin, id);
76 */
77 if (dev->value)
78 brightonStretch(dev->bwin, dev->image2,
79 dev->bwin->dlayer,
80 dev->x + dev->bwin->app->resources[dev->panel].sx,
81 dev->y + dev->bwin->app->resources[dev->panel].sy,
82 dev->width, dev->height,
83 flags);
84 else
85 brightonStretch(dev->bwin, dev->image,
86 dev->bwin->dlayer,
87 dev->x + dev->bwin->app->resources[dev->panel].sx,
88 dev->y + dev->bwin->app->resources[dev->panel].sy,
89 dev->width, dev->height,
90 flags);
91
92 brightonFinalRender(dev->bwin,
93 dev->x + dev->bwin->app->resources[dev->panel].sx,
94 dev->y + dev->bwin->app->resources[dev->panel].sy,
95 dev->width, dev->height);
96
97 dev->lastvalue = dev->value;
98 dev->lastposition = dev->position;
99 }
100
101 /*
102 * This will go into brighton render
103 */
104 static int
renderHighlights(brightonWindow * bwin,brightonDevice * dev)105 renderHighlights(brightonWindow *bwin, brightonDevice *dev)
106 {
107 float d, streak, dx, dy;
108 brightonCoord p[8];
109
110 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags &
111 (BRIGHTON_CHECKBUTTON|BRIGHTON_NOSHADOW|BRIGHTON_WITHDRAWN))
112 return(0);
113
114 dx = dev->x - bwin->lightX;
115 dy = dev->y - bwin->lightY;
116
117 d = sqrt((double) (dx * dx + dy * dy));
118
119 streak = (dev->width * 2.0 * d / bwin->lightH)
120 / (1 - dev->width * 2.0 / bwin->lightH);
121
122 p[0].x = dev->x;
123 p[0].y = dev->y + dev->height;
124 p[1].x = dev->x + dev->width;
125 p[1].y = dev->y;
126 p[2].x = dev->x + dx * streak / d;
127 p[2].y = dev->y + dy * streak / d;
128
129 /* XFillPolygon(bwin->display, bwin->background, bwin->cheap_shade, */
130 /* (XPoint *) &p, 3, Complex, CoordModeOrigin); */
131 return(0);
132 }
133
considercallback(brightonDevice * dev)134 static int considercallback(brightonDevice *dev)
135 {
136 brightonIResource *panel = &dev->bwin->app->resources[dev->panel];
137
138 if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
139 & BRIGHTON_WITHDRAWN)
140 || (dev->bwin->flags & BRIGHTON_NO_DRAW))
141 return(0);
142
143 if ((dev->lastvalue != dev->value)
144 || (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
145 & BRIGHTON_CHECKBUTTON))
146 {
147 if (panel->devlocn[dev->index].callback)
148 {
149 panel->devlocn[dev->index].callback(dev->bwin, dev->panel,
150 dev->index, dev->value);
151 } else {
152 if (panel->callback)
153 panel->callback(dev->bwin, dev->panel, dev->index, dev->value);
154 }
155 }
156 return(0);
157 }
158
159 static int
configure(brightonDevice * dev,brightonEvent * event)160 configure(brightonDevice *dev, brightonEvent *event)
161 {
162 /* printf("configureHButton(%i, %f)\n", dev->index, dev->value); */
163
164 if (dev->bwin->app->resources[dev->panel].flags & BRIGHTON_WITHDRAWN)
165 return(0);
166
167 if (event->command == -1)
168 return(-1);
169
170 if (event->command == BRIGHTON_RESIZE)
171 {
172 dev->x = event->x;
173 dev->y = event->y;
174 dev->width = event->w;
175 dev->height = event->h;
176 /*
177 * We should consider altering the locations structure, so that
178 * event dispatching is correct.
179 */
180 if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
181 & BRIGHTON_CHECKBUTTON) == 0)
182 considercallback(dev);
183
184 brightonPanelLocation(dev->bwin,
185 dev->panel, dev->index, dev->x, dev->y, dev->width, dev->height);
186
187 /*
188 * We need to build in some shadow, to prevent the hbutton from looking
189 * like it is hanging in mid air.
190 renderHighlights(dev->bwin, dev);
191 */
192
193 dev->lastvalue = -1;
194 displayhbutton(dev);
195
196 return(0);
197 }
198
199 if (event->command == BRIGHTON_LEAVE)
200 {
201 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
202 & BRIGHTON_CHECKBUTTON)
203 {
204 dev->value = 0;
205
206 displayhbutton(dev);
207 }
208 return(0);
209 }
210
211 if (event->command == BRIGHTON_ENTER)
212 {
213 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
214 & BRIGHTON_CHECKBUTTON)
215 {
216 dev->value = 1;
217
218 displayhbutton(dev);
219 }
220 return(0);
221 }
222
223 if (event->command == BRIGHTON_BUTTONRELEASE)
224 {
225 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
226 & BRIGHTON_CHECKBUTTON)
227 {
228 dev->value = 0;
229
230 displayhbutton(dev);
231
232 if ((event->x >= dev->x) && (event->y >= dev->y)
233 && (event->x < (dev->x + dev->width))
234 && (event->y < (dev->y + dev->height)))
235 considercallback(dev);
236 }
237 return(0);
238 }
239
240 if (event->command == BRIGHTON_BUTTONPRESS)
241 {
242 brightonIResource *panel = &dev->bwin->app->resources[dev->panel];
243
244 if (event->key == BRIGHTON_BUTTON2)
245 {
246 brightonRegisterController(dev);
247
248 return(0);
249 }
250
251 if (dev->value == 0)
252 dev->value = panel->devlocn[dev->index].to;
253 else
254 dev->value = panel->devlocn[dev->index].from;
255
256 if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
257 & BRIGHTON_CHECKBUTTON) == 0)
258 considercallback(dev);
259
260 displayhbutton(dev);
261
262 return(0);
263 }
264
265 if (event->command == BRIGHTON_KEYPRESS)
266 {
267 brightonIResource *panel = &dev->bwin->app->resources[dev->panel];
268
269 if (event->key == 0x20)
270 {
271 if (dev->value == 0)
272 dev->value = panel->devlocn[dev->index].to;
273 else
274 dev->value = panel->devlocn[dev->index].from;
275
276 considercallback(dev);
277
278 displayhbutton(dev);
279
280 return(0);
281 }
282 /*
283 * If this was not a space bar which we use to activate and de-activate
284 * any arbitrary hbutton then it could be that we pressed some key that
285 * can otherwise be interpretted.
286 * This is awkward since here we are in a single hbutton and I would
287 * like to use keypress to emulate a piano keyboard from the computer.
288 * These events would have to be delivered to the parent, not to the
289 * device, and the parent would then decide to which device the event
290 * should be delivered.
291 */
292 }
293
294 if (event->command == BRIGHTON_KEYRELEASE)
295 {
296 /*
297 * This is just to clear the event and repaint the key, we should not
298 * be bothered with the callback.
299 */
300 if (event->key == 0x20)
301 {
302 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
303 & BRIGHTON_CHECKBUTTON)
304 {
305 dev->value = 0;
306
307 displayhbutton(dev);
308
309 /* considercallback(dev); */
310 }
311 }
312 return(0);
313 }
314
315 if (event->command == BRIGHTON_PARAMCHANGE)
316 {
317 if (dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
318 & BRIGHTON_CHECKBUTTON)
319 {
320 dev->value = 0;
321
322 displayhbutton(dev);
323
324 considercallback(dev);
325 return(0);
326 }
327
328 dev->value = event->value;
329 dev->lastvalue = -1;
330
331 if ((dev->bwin->app->resources[dev->panel].devlocn[dev->index].flags
332 & BRIGHTON_CHECKBUTTON) == 0)
333 considercallback(dev);
334
335 displayhbutton(dev);
336
337 return(0);
338 }
339
340 return(0);
341 }
342
343 int *
createHButton(brightonWindow * bwin,brightonDevice * dev,int index,char * bitmap)344 createHButton(brightonWindow *bwin, brightonDevice *dev, int index, char *bitmap)
345 {
346 brightonIResource *panel = &bwin->app->resources[dev->panel];
347
348 dev->destroy = destroyHButton;
349 dev->configure = configure;
350 dev->bwin = bwin;
351
352 if (bitmap == NULL) {
353 if (dev->image)
354 brightonFreeBitmap(bwin, dev->image);
355 /*
356 * If we have been passed a specific image name for this device then
357 * use it.
358 */
359 if (panel->devlocn[dev->index].image != 0)
360 dev->image =
361 bwin->app->resources[dev->panel].devlocn[dev->index].image;
362 else
363 dev->image = brightonReadImage(bwin,
364 "bitmaps/hbuttons/rockerred.xpm");
365 if (panel->devlocn[dev->index].image2 != 0)
366 dev->image2 =
367 bwin->app->resources[dev->panel].devlocn[dev->index].image2;
368 else
369 dev->image =
370 brightonReadImage(bwin, "bitmaps/hbuttons/rockerred.xpm");
371 tbm = bitmap;
372 } else {
373 if (dev->image)
374 brightonFreeBitmap(bwin, dev->image);
375
376 if (panel->devlocn[dev->index].image != 0)
377 dev->image =
378 bwin->app->resources[dev->panel].devlocn[dev->index].image;
379 else
380 dev->image = brightonReadImage(bwin, bitmap);
381
382 if (dev->image2)
383 brightonFreeBitmap(bwin, dev->image2);
384
385 dev->image2 = brightonReadImage(bwin,
386 bwin->template->resources[dev->panel].devlocn[dev->index].image2);
387
388 /*
389 if (panel->devlocn[dev->index].image2 != 0)
390 dev->image2 =
391 bwin->app->resources[dev->panel].devlocn[dev->index].image2;
392 */
393 }
394
395 /*
396 * These will force an update when we first display ourselves.
397 */
398 dev->value = 0;
399 dev->lastvalue = -1;
400 dev->lastposition = -1;
401
402 return(0);
403 }
404
405