1 /*
2 * Copyright (C) 2000-2019 the xine project
3 *
4 * This file is part of xine, a unix video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include <math.h>
27
28 #include "_xitk.h"
29
30 #ifndef M_PI
31 #define M_PI 3.14159265358979323846
32 #endif
33
34 /*
35 *
36 */
slider_update_value(xitk_widget_t * w,float value)37 static void slider_update_value(xitk_widget_t *w, float value) {
38 slider_private_data_t *private_data = (slider_private_data_t *) w->private_data;
39 float range;
40
41 if(value < private_data->lower)
42 private_data->value = private_data->lower;
43 else if(value > private_data->upper)
44 private_data->value = private_data->upper;
45 else
46 private_data->value = value;
47
48 range = (private_data->upper + -private_data->lower);
49
50 private_data->percentage = (private_data->value + -private_data->lower) / range;
51 private_data->angle = 7.*M_PI/6. - (private_data->value - private_data->lower) *
52 4.*M_PI/3. / (private_data->upper - private_data->lower);
53
54 }
55
56 /*
57 *
58 */
slider_update_minmax(xitk_widget_t * w,float min,float max)59 static void slider_update_minmax(xitk_widget_t *w, float min, float max) {
60 slider_private_data_t *private_data = (slider_private_data_t *) w->private_data;
61
62 if(min > max) {
63 XITK_WARNING("%s@%d: slider min value > max value !\n", __FILE__, __LINE__);
64 return;
65 }
66
67 private_data->upper = (min == max) ? max + 1 : max;
68 private_data->lower = min;
69 slider_update_value(w, private_data->value);
70 }
71
72 /*
73 *
74 */
slider_update(xitk_widget_t * w,int x,int y)75 static void slider_update(xitk_widget_t *w, int x, int y) {
76 slider_private_data_t *private_data = (slider_private_data_t *) w->private_data;
77
78 if(private_data->sType == XITK_RSLIDER) {
79 int xc, yc;
80 float old_value;
81
82 xc = private_data->bg_skin->width / 2;
83 yc = private_data->bg_skin->height / 2;
84
85 old_value = private_data->value;
86 private_data->angle = atan2(yc - y, x - xc);
87
88 if(private_data->angle < -M_PI / 2.)
89 private_data->angle += 2 * M_PI;
90
91 if(private_data->angle < -M_PI / 6)
92 private_data->angle = -M_PI / 6;
93
94 if(private_data->angle > 7. * M_PI / 6.)
95 private_data->angle = 7. * M_PI / 6.;
96
97 private_data->value = private_data->lower + (7. * M_PI / 6 - private_data->angle) *
98 (private_data->upper - private_data->lower) / (4. * M_PI / 3.);
99
100 if(private_data->value != old_value) {
101 float new_value;
102
103 new_value = private_data->value;
104
105 if(new_value < private_data->lower)
106 new_value = private_data->lower;
107
108 if(new_value > private_data->upper)
109 new_value = private_data->upper;
110
111 slider_update_value(w, new_value);
112
113 }
114 }
115 else {
116 float width, height;
117 float old_value, new_value = 0.0;
118
119 old_value = private_data->value;
120
121 width = (float)private_data->bg_skin->width;
122 height = (float)private_data->bg_skin->height;
123
124 if(private_data->paddle_cover_bg == 1) {
125
126 if(x < 0)
127 x = 0;
128 if(x > width)
129 x = width;
130
131 if(y < 0)
132 y = 0;
133 if(y > height)
134 y = height;
135
136 if(private_data->sType == XITK_HSLIDER)
137 new_value = (x * .01) / (width * .01);
138 else if(private_data->sType == XITK_VSLIDER)
139 new_value = ((height - y) * .01) / (height * .01);
140
141 }
142 else {
143 int pwidth, pheight;
144
145 pwidth = private_data->button_width;
146 pheight = private_data->paddle_skin->height;
147
148 if(private_data->sType == XITK_HSLIDER) {
149 x -= pwidth >> 1;
150
151 if(x < 0)
152 x = 0;
153 if(x > (width - pwidth))
154 x = width - pwidth;
155
156 if(y < 0)
157 y = 0;
158 if(y > height)
159 y = height;
160
161 }
162 else { /* XITK_VSLIDER */
163
164 if(x < 0)
165 x = 0;
166 if(x > width)
167 x = width;
168
169 y += pheight >> 1;
170
171 if(y < 0)
172 y = 0;
173 if(y > (height + pheight))
174 y = height + pheight ;
175 }
176
177 if(private_data->sType == XITK_HSLIDER)
178 new_value = (x * .01) / ((width - pwidth) * .01);
179 else if(private_data->sType == XITK_VSLIDER)
180 new_value = ((height - y) * .01) / ((height - pheight) * .01);
181 }
182
183 private_data->value = private_data->lower +
184 (new_value * (private_data->upper - private_data->lower));
185
186 if(private_data->value != old_value) {
187 float new_value;
188
189 new_value = private_data->value;
190
191 if (new_value < private_data->lower)
192 new_value = private_data->lower;
193
194 if (new_value > private_data->upper)
195 new_value = private_data->upper;
196
197 slider_update_value(w, new_value);
198 }
199 }
200 }
201
202 /*
203 *
204 */
notify_destroy(xitk_widget_t * w)205 static void notify_destroy(xitk_widget_t *w) {
206 slider_private_data_t *private_data;
207
208 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
209 private_data = (slider_private_data_t *) w->private_data;
210
211 if(!private_data->skin_element_name) {
212 xitk_image_free_image(private_data->imlibdata, &(private_data->paddle_skin));
213 xitk_image_free_image(private_data->imlibdata, &(private_data->bg_skin));
214 }
215
216 XITK_FREE(private_data->skin_element_name);
217 XITK_FREE(private_data);
218 }
219 }
220
221 /*
222 *
223 */
get_skin(xitk_widget_t * w,int sk)224 static xitk_image_t *get_skin(xitk_widget_t *w, int sk) {
225 slider_private_data_t *private_data;
226
227 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
228
229 private_data = (slider_private_data_t *) w->private_data;
230
231 if(sk == FOREGROUND_SKIN && private_data->paddle_skin) {
232 return private_data->paddle_skin;
233 }
234 else if(sk == BACKGROUND_SKIN && private_data->bg_skin) {
235 return private_data->bg_skin;
236 }
237 }
238
239 return NULL;
240 }
241
242 /*
243 *
244 */
notify_inside(xitk_widget_t * w,int x,int y)245 static int notify_inside(xitk_widget_t *w, int x, int y) {
246 slider_private_data_t *private_data;
247
248 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
249
250 private_data = (slider_private_data_t *) w->private_data;
251
252 if(w->visible == 1) {
253 xitk_image_t *skin;
254
255 if(private_data->paddle_cover_bg == 1)
256 skin = private_data->paddle_skin;
257 else
258 skin = private_data->bg_skin;
259
260 if(skin->mask)
261 return xitk_is_cursor_out_mask(private_data->imlibdata->x.disp, w, skin->mask->pixmap, x, y);
262 }
263 else
264 return 0;
265 }
266
267 return 1;
268 }
269
270 /*
271 * Draw widget
272 */
paint_slider(xitk_widget_t * w)273 static void paint_slider(xitk_widget_t *w) {
274 int button_width, button_height;
275 slider_private_data_t *private_data;
276 GC bgc, pgc;
277 xitk_image_t *bg;
278 xitk_image_t *paddle;
279
280 if(w && (((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER) && w->visible == 1)) {
281 int x, y, srcx1, srcx2, destx1, srcy1, srcy2, desty1;
282 int xcenter, ycenter;
283 int paddle_width;
284 int paddle_height;
285 double angle;
286
287 private_data = (slider_private_data_t *) w->private_data;
288 bg = (xitk_image_t *) private_data->bg_skin;
289 paddle = (xitk_image_t *) private_data->paddle_skin;
290
291 x = y = srcx1 = srcx2 = destx1 = srcy1 = srcy2 = desty1 = 0;
292
293 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
294 bgc = XCreateGC(private_data->imlibdata->x.disp, bg->image->pixmap, None, None);
295 XCopyGC(private_data->imlibdata->x.disp, w->wl->gc, (1 << GCLastBit) - 1, bgc);
296 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
297
298 if(bg->mask) {
299 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
300 XSetClipOrigin(private_data->imlibdata->x.disp, bgc, w->x, w->y);
301 XSetClipMask(private_data->imlibdata->x.disp, bgc, bg->mask->pixmap);
302 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
303 }
304
305 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
306 XCopyArea(private_data->imlibdata->x.disp, bg->image->pixmap, w->wl->win, bgc, 0, 0,
307 bg->width, bg->height, w->x, w->y);
308
309 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
310
311 if(w->enable == WIDGET_ENABLE) {
312
313 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
314 pgc = XCreateGC(private_data->imlibdata->x.disp, paddle->image->pixmap, None, None);
315 XCopyGC(private_data->imlibdata->x.disp, w->wl->gc, (1 << GCLastBit) - 1, pgc);
316 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
317
318 if(private_data->sType == XITK_RSLIDER) {
319
320 button_width = private_data->bg_skin->width;
321 button_height = private_data->bg_skin->height;
322
323 xcenter = (bg->width /2) + w->x;
324 ycenter = (bg->width /2) + w->y;
325 paddle_width = paddle->width / 3;
326 paddle_height = paddle->height;
327 angle = private_data->angle;
328
329 if(angle < M_PI / -2)
330 angle = angle + M_PI * 2;
331
332 x = (int) (0.5 + xcenter + private_data->radius * cos(angle)) - (paddle_width / 2);
333 y = (int) (0.5 + ycenter - private_data->radius * sin(angle)) - (paddle_height / 2);
334
335 srcx1 = 0;
336
337 if((private_data->focus == FOCUS_RECEIVED) || (private_data->focus == FOCUS_MOUSE_IN)) {
338 srcx1 += paddle_width;
339 if(private_data->bClicked)
340 srcx1 += paddle_width;
341 }
342
343 srcy1 = 0;
344 srcx2 = paddle_width;
345 srcy2 = paddle_height;
346 destx1 = x;
347 desty1 = y;
348
349 }
350 else {
351 int dir_area;
352 float tmp;
353
354 button_width = private_data->button_width;
355 button_height = paddle->height;
356
357 dir_area = (float)(private_data->sType == XITK_HSLIDER) ?
358 w->width - button_width : w->height - button_height;
359
360 tmp = (dir_area * .01) * (private_data->percentage * 100.0);
361
362 if(private_data->sType == XITK_HSLIDER) {
363 x = rint(w->x + tmp);
364 y = w->y;
365 }
366 else if(private_data->sType == XITK_VSLIDER) {
367 x = w->x;
368 y = rint(w->y + private_data->bg_skin->height - button_height - tmp);
369 }
370
371 if(private_data->paddle_cover_bg == 1) {
372 int pixpos;
373 int direction;
374
375 x = w->x;
376 y = w->y;
377
378 direction = (private_data->sType == XITK_HSLIDER) ?
379 private_data->bg_skin->width : private_data->bg_skin->height;
380
381 pixpos = (int)private_data->value /
382 ((private_data->upper - private_data->lower) / direction);
383
384 if(private_data->sType == XITK_VSLIDER) {
385 pixpos = button_height - pixpos;
386 srcx1 = 0;
387 srcy1 = pixpos;
388 srcx2 = button_width;
389 srcy2 = paddle->height - pixpos;
390 destx1 = w->x;
391 desty1 = w->y + pixpos;
392 }
393 else if(private_data->sType == XITK_HSLIDER) {
394 srcx1 = 0;
395 srcy1 = 0;
396 srcx2 = pixpos;
397 srcy2 = paddle->height;
398 destx1 = w->x;
399 desty1 = w->y;
400 }
401 }
402 else {
403 srcy1 = 0;
404 srcx2 = button_width;
405 srcy2 = paddle->height;
406 destx1 = x;
407 desty1 = y;
408 }
409
410 if((private_data->focus == FOCUS_RECEIVED) || (private_data->focus == FOCUS_MOUSE_IN)) {
411 if(private_data->bClicked)
412 srcx1 = 2*button_width;
413 else
414 srcx1 = button_width;
415 }
416
417 }
418
419 if(paddle->mask) {
420 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
421 XSetClipOrigin(private_data->imlibdata->x.disp, pgc, x, y);
422 XSetClipMask(private_data->imlibdata->x.disp, pgc, paddle->mask->pixmap);
423 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
424 }
425
426 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
427 XCopyArea(private_data->imlibdata->x.disp, paddle->image->pixmap, w->wl->win, pgc,
428 srcx1, srcy1, srcx2, srcy2, destx1, desty1);
429 XFreeGC(private_data->imlibdata->x.disp, pgc);
430 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
431 }
432
433 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
434 XFreeGC(private_data->imlibdata->x.disp, bgc);
435 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
436 }
437
438 }
439
440 /*
441 *
442 */
notify_change_skin(xitk_widget_t * w,xitk_skin_config_t * skonfig)443 static void notify_change_skin(xitk_widget_t *w, xitk_skin_config_t *skonfig) {
444 slider_private_data_t *private_data;
445
446 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
447
448 private_data = (slider_private_data_t *) w->private_data;
449
450 if(private_data->skin_element_name) {
451
452 xitk_skin_lock(skonfig);
453
454 private_data->paddle_skin = xitk_skin_get_image(skonfig, xitk_skin_get_slider_skin_filename(skonfig, private_data->skin_element_name));
455 private_data->button_width = private_data->paddle_skin->width / 3;
456 private_data->bg_skin = xitk_skin_get_image(skonfig, xitk_skin_get_skin_filename(skonfig, private_data->skin_element_name));
457 private_data->sType = xitk_skin_get_slider_type(skonfig, private_data->skin_element_name);
458 private_data->paddle_cover_bg = 0;
459
460 if(private_data->sType == XITK_HSLIDER) {
461 if(private_data->button_width == private_data->bg_skin->width)
462 private_data->paddle_cover_bg = 1;
463 }
464 else if(private_data->sType == XITK_VSLIDER) {
465 if(private_data->paddle_skin->height == private_data->bg_skin->height)
466 private_data->paddle_cover_bg = 1;
467 }
468
469 private_data->radius = xitk_skin_get_slider_radius(skonfig, private_data->skin_element_name);
470
471 w->x = xitk_skin_get_coord_x(skonfig, private_data->skin_element_name);
472 w->y = xitk_skin_get_coord_y(skonfig, private_data->skin_element_name);
473 w->width = private_data->bg_skin->width;
474 w->height = private_data->bg_skin->height;
475 w->visible = (xitk_skin_get_visibility(skonfig, private_data->skin_element_name)) ? 1 : -1;
476 w->enable = xitk_skin_get_enability(skonfig, private_data->skin_element_name);
477
478 xitk_skin_unlock(skonfig);
479
480 xitk_set_widget_pos(w, w->x, w->y);
481 }
482 }
483 }
484
485 /*
486 * Got click
487 */
notify_click_slider(xitk_widget_t * w,int button,int bUp,int x,int y)488 static int notify_click_slider(xitk_widget_t *w, int button, int bUp, int x, int y) {
489 slider_private_data_t *private_data;
490 int ret = 0;
491
492 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
493 if(button == Button1) {
494 private_data = (slider_private_data_t *) w->private_data;
495
496 if(private_data->focus == FOCUS_RECEIVED) {
497 int old_value = (int) private_data->value;
498
499 slider_update(w, (x - w->x), (y - w->y));
500
501 if(private_data->bClicked == bUp)
502 private_data->bClicked = !bUp;
503
504 if(bUp == 0) {
505
506 if(old_value != ((int) private_data->value))
507 slider_update_value(w, private_data->value);
508
509 paint_slider(w);
510
511 /*
512 * Exec motion callback function (if available)
513 */
514 if(old_value != ((int) private_data->value)) {
515 if(private_data->motion_callback)
516 private_data->motion_callback(private_data->sWidget,
517 private_data->motion_userdata,
518 (int) private_data->value);
519 }
520
521 }
522 else if(bUp == 1) {
523 private_data->bClicked = 0;
524
525 slider_update_value(w, private_data->value);
526 paint_slider(w);
527
528 if(private_data->callback) {
529 private_data->callback(private_data->sWidget,
530 private_data->userdata,
531 (int) private_data->value);
532 }
533 }
534 }
535 ret = 1;
536 }
537 }
538
539 return ret;
540 }
541
542 /*
543 * Got focus
544 */
notify_focus_slider(xitk_widget_t * w,int focus)545 static int notify_focus_slider(xitk_widget_t *w, int focus) {
546 slider_private_data_t *private_data;
547
548 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
549 private_data = (slider_private_data_t *) w->private_data;
550 if(!private_data->bClicked)
551 private_data->focus = focus;
552 }
553
554 return 1;
555 }
556
notify_event(xitk_widget_t * w,widget_event_t * event,widget_event_result_t * result)557 static int notify_event(xitk_widget_t *w, widget_event_t *event, widget_event_result_t *result) {
558 int retval = 0;
559
560 switch(event->type) {
561 case WIDGET_EVENT_PAINT:
562 paint_slider(w);
563 break;
564 case WIDGET_EVENT_CLICK:
565 result->value = notify_click_slider(w, event->button,
566 event->button_pressed, event->x, event->y);
567 retval = 1;
568 break;
569 case WIDGET_EVENT_FOCUS:
570 notify_focus_slider(w, event->focus);
571 break;
572 case WIDGET_EVENT_INSIDE:
573 result->value = notify_inside(w, event->x, event->y);
574 retval = 1;
575 break;
576 case WIDGET_EVENT_CHANGE_SKIN:
577 notify_change_skin(w, event->skonfig);
578 break;
579 case WIDGET_EVENT_DESTROY:
580 notify_destroy(w);
581 break;
582 case WIDGET_EVENT_GET_SKIN:
583 if(result) {
584 result->image = get_skin(w, event->skin_layer);
585 retval = 1;
586 }
587 break;
588 }
589
590 return retval;
591 }
592
593 /*
594 * Increment position
595 */
xitk_slider_make_step(xitk_widget_t * w)596 void xitk_slider_make_step(xitk_widget_t *w) {
597 slider_private_data_t *private_data;
598
599 if (w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
600 private_data = (slider_private_data_t *) w->private_data;
601 if(!private_data->bClicked) {
602 if(((xitk_slider_get_pos(w)) + private_data->step) <= (xitk_slider_get_max(w)))
603 xitk_slider_set_pos(w, xitk_slider_get_pos(w) + private_data->step);
604 }
605 }
606
607 }
608
609 /*
610 * Decrement position
611 */
xitk_slider_make_backstep(xitk_widget_t * w)612 void xitk_slider_make_backstep(xitk_widget_t *w) {
613 slider_private_data_t *private_data;
614
615 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
616 private_data = (slider_private_data_t *) w->private_data;
617 if(!private_data->bClicked) {
618 if(((xitk_slider_get_pos(w)) - private_data->step) >= (xitk_slider_get_min(w)))
619 xitk_slider_set_pos(w, xitk_slider_get_pos(w) - private_data->step);
620 }
621
622 }
623
624 }
625
626 /*
627 * Set value MIN.
628 */
xitk_slider_set_min(xitk_widget_t * w,int min)629 void xitk_slider_set_min(xitk_widget_t *w, int min) {
630 slider_private_data_t *private_data;
631
632 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
633 private_data = (slider_private_data_t *) w->private_data;
634 slider_update_minmax(w, (float)((min == private_data->upper)
635 ? min - 1 : min), private_data->upper);
636 }
637 }
638
639 /*
640 * Return the MIN value
641 */
xitk_slider_get_min(xitk_widget_t * w)642 int xitk_slider_get_min(xitk_widget_t *w) {
643 slider_private_data_t *private_data;
644
645 if((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER) {
646 private_data = (slider_private_data_t *) w->private_data;
647 return (int) private_data->lower;
648 }
649
650 return -1;
651 }
652
653 /*
654 * Return the MAX value
655 */
xitk_slider_get_max(xitk_widget_t * w)656 int xitk_slider_get_max(xitk_widget_t *w) {
657 slider_private_data_t *private_data;
658
659 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
660 private_data = (slider_private_data_t *) w->private_data;
661 return (int) private_data->upper;
662 }
663
664 return -1;
665 }
666
667 /*
668 * Set value MAX
669 */
xitk_slider_set_max(xitk_widget_t * w,int max)670 void xitk_slider_set_max(xitk_widget_t *w, int max) {
671 slider_private_data_t *private_data;
672
673 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
674 private_data = (slider_private_data_t *) w->private_data;
675 slider_update_minmax(w, private_data->lower, (float)((max == private_data->lower)
676 ? max + 1 : max));
677 }
678 }
679
680 /*
681 * Set pos to 0 and redraw the widget.
682 */
xitk_slider_reset(xitk_widget_t * w)683 void xitk_slider_reset(xitk_widget_t *w) {
684 slider_private_data_t *private_data;
685
686 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
687 private_data = (slider_private_data_t *) w->private_data;
688 slider_update_value(w, 0.0);
689 private_data->bClicked = 0;
690 paint_slider(w);
691 }
692 }
693
694 /*
695 * Set pos to max and redraw the widget.
696 */
xitk_slider_set_to_max(xitk_widget_t * w)697 void xitk_slider_set_to_max(xitk_widget_t *w) {
698 slider_private_data_t *private_data;
699
700 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
701 private_data = (slider_private_data_t *) w->private_data;
702 if(!private_data->bClicked) {
703 slider_update_value(w, private_data->upper);
704 paint_slider(w);
705 }
706 }
707 }
708
709 /*
710 * Return current position.
711 */
xitk_slider_get_pos(xitk_widget_t * w)712 int xitk_slider_get_pos(xitk_widget_t *w) {
713 slider_private_data_t *private_data;
714
715 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
716 private_data = (slider_private_data_t *) w->private_data;
717 return (int) private_data->value;
718 }
719
720 return -1;
721 }
722
723 /*
724 * Set position.
725 */
xitk_slider_set_pos(xitk_widget_t * w,int pos)726 void xitk_slider_set_pos(xitk_widget_t *w, int pos) {
727 slider_private_data_t *private_data;
728
729 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
730 float value = (float) pos;
731
732 private_data = (slider_private_data_t *) w->private_data;
733
734 if(!private_data->bClicked) {
735 if(value >= private_data->lower && value <= private_data->upper) {
736 slider_update_value(w, value);
737 paint_slider(w);
738 }
739 }
740
741 }
742 }
743
744 /*
745 * Call callback for current position
746 */
xitk_slider_callback_exec(xitk_widget_t * w)747 void xitk_slider_callback_exec(xitk_widget_t *w) {
748 slider_private_data_t *private_data;
749
750 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_SLIDER)) {
751 private_data = (slider_private_data_t *) w->private_data;
752
753 if(private_data->callback) {
754 private_data->callback(private_data->sWidget,
755 private_data->userdata,
756 (int) private_data->value);
757 }
758 else {
759
760 if(private_data->motion_callback) {
761 private_data->motion_callback(private_data->sWidget,
762 private_data->motion_userdata,
763 (int) private_data->value);
764 }
765
766 }
767 }
768 }
769
770 /*
771 * Create the widget
772 */
_xitk_slider_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_slider_widget_t * s,int x,int y,const char * skin_element_name,xitk_image_t * bg_skin,xitk_image_t * pad_skin,int stype,int radius,int visible,int enable)773 static xitk_widget_t *_xitk_slider_create(xitk_widget_list_t *wl,
774 xitk_skin_config_t *skonfig, xitk_slider_widget_t *s,
775 int x, int y, const char *skin_element_name,
776 xitk_image_t *bg_skin, xitk_image_t *pad_skin,
777 int stype, int radius, int visible, int enable) {
778 xitk_widget_t *mywidget;
779 slider_private_data_t *private_data;
780
781 mywidget = (xitk_widget_t *) xitk_xmalloc (sizeof(xitk_widget_t));
782
783 private_data = (slider_private_data_t *) xitk_xmalloc (sizeof (slider_private_data_t));
784
785 private_data->imlibdata = s->imlibdata;
786 private_data->skin_element_name = (skin_element_name == NULL) ? NULL : strdup(s->skin_element_name);
787
788 private_data->sWidget = mywidget;
789 private_data->sType = stype;
790 private_data->bClicked = 0;
791 private_data->focus = FOCUS_LOST;
792
793 private_data->angle = 0.0;
794
795 private_data->upper = (float)((s->min == s->max) ? s->max + 1 : s->max);
796 private_data->lower = (float)s->min;
797
798 private_data->value = 0.0;
799 private_data->percentage = 0.0;
800 private_data->radius = radius;
801
802 private_data->step = s->step;
803
804 private_data->paddle_skin = pad_skin;
805 private_data->button_width = private_data->paddle_skin->width / 3;
806
807 private_data->bg_skin = bg_skin;
808
809 private_data->paddle_cover_bg = 0;
810 if(private_data->sType == XITK_HSLIDER) {
811 if(private_data->button_width == private_data->bg_skin->width)
812 private_data->paddle_cover_bg = 1;
813 }
814 else if(private_data->sType == XITK_VSLIDER) {
815 if(private_data->paddle_skin->height == private_data->bg_skin->height)
816 private_data->paddle_cover_bg = 1;
817 }
818
819 private_data->motion_callback = s->motion_callback;
820 private_data->motion_userdata = s->motion_userdata;
821 private_data->callback = s->callback;
822 private_data->userdata = s->userdata;
823
824 mywidget->private_data = private_data;
825
826 mywidget->wl = wl;
827
828 mywidget->enable = enable;
829 mywidget->running = 1;
830 mywidget->visible = visible;
831 mywidget->have_focus = FOCUS_LOST;
832 mywidget->imlibdata = private_data->imlibdata;
833 mywidget->x = x;
834 mywidget->y = y;
835 mywidget->width = private_data->bg_skin->width;
836 mywidget->height = private_data->bg_skin->height;
837 mywidget->type = WIDGET_TYPE_SLIDER | WIDGET_FOCUSABLE | WIDGET_CLICKABLE | WIDGET_KEYABLE;
838 mywidget->event = notify_event;
839 mywidget->tips_timeout = 0;
840 mywidget->tips_string = NULL;
841
842 return mywidget;
843 }
844
845 /*
846 * Create the widget
847 */
xitk_slider_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_slider_widget_t * s)848 xitk_widget_t *xitk_slider_create(xitk_widget_list_t *wl,
849 xitk_skin_config_t *skonfig, xitk_slider_widget_t *s) {
850
851 XITK_CHECK_CONSTITENCY(s);
852
853 return _xitk_slider_create(wl, skonfig, s,
854 (xitk_skin_get_coord_x(skonfig, s->skin_element_name)),
855 (xitk_skin_get_coord_y(skonfig, s->skin_element_name)),
856 s->skin_element_name,
857 (xitk_skin_get_image(skonfig,
858 xitk_skin_get_skin_filename(skonfig, s->skin_element_name))),
859 (xitk_skin_get_image(skonfig,
860 xitk_skin_get_slider_skin_filename(skonfig, s->skin_element_name))),
861 (xitk_skin_get_slider_type(skonfig, s->skin_element_name)),
862 (xitk_skin_get_slider_radius(skonfig, s->skin_element_name)),
863 ((xitk_skin_get_visibility(skonfig, s->skin_element_name)) ? 1 : -1),
864 (xitk_skin_get_enability(skonfig, s->skin_element_name)));
865 }
866
867 /*
868 * Create the widget (not skined).
869 */
xitk_noskin_slider_create(xitk_widget_list_t * wl,xitk_slider_widget_t * s,int x,int y,int width,int height,int type)870 xitk_widget_t *xitk_noskin_slider_create(xitk_widget_list_t *wl,
871 xitk_slider_widget_t *s,
872 int x, int y, int width, int height, int type) {
873 xitk_image_t *b, *p;
874 int radius;
875
876 XITK_CHECK_CONSTITENCY(s);
877
878 if(type == XITK_VSLIDER)
879 p = xitk_image_create_image(s->imlibdata, width * 3, height / 5);
880 else if(type == XITK_HSLIDER)
881 p = xitk_image_create_image(s->imlibdata, (width / 5) * 3, height);
882 else if(type == XITK_RSLIDER) {
883 int w;
884
885 w = ((((width + height) >> 1) >> 1) / 10) * 3;
886 p = xitk_image_create_image(s->imlibdata, (w * 3), w);
887 }
888 else
889 XITK_DIE("Slider type unhandled.\n");
890
891 xitk_image_add_mask(s->imlibdata, p);
892 if(type == XITK_VSLIDER)
893 draw_paddle_three_state_vertical(s->imlibdata, p);
894 else if(type == XITK_HSLIDER)
895 draw_paddle_three_state_horizontal(s->imlibdata, p);
896 else if(type == XITK_RSLIDER) {
897 draw_paddle_rotate(s->imlibdata, p);
898 }
899
900 b = xitk_image_create_image(s->imlibdata, width, height);
901 xitk_image_add_mask(s->imlibdata, b);
902 if((type == XITK_HSLIDER) || (type == XITK_VSLIDER))
903 draw_inner(s->imlibdata, b->image, width, height);
904 else if(type == XITK_RSLIDER) {
905 draw_rotate_button(s->imlibdata, b);
906 }
907
908 radius = (b->height >> 1) - (p->height);
909
910 return _xitk_slider_create(wl,NULL, s, x, y, NULL, b, p, type, radius, 0, 0);
911 }
912