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 <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdio.h>
28
29 #include "_xitk.h"
30
31 static void _combo_rollunroll(xitk_widget_t *w, void *data, int state);
32
33 /*
34 *
35 */
enability(xitk_widget_t * w)36 static void enability(xitk_widget_t *w) {
37
38 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
39 (w->type & WIDGET_GROUP_WIDGET))) {
40 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
41
42 if(w->enable == WIDGET_ENABLE) {
43 xitk_enable_widget(private_data->label_widget);
44 xitk_enable_widget(private_data->button_widget);
45 }
46 else {
47
48 if(private_data->visible) {
49 xitk_checkbox_set_state(private_data->button_widget, 0);
50 _combo_rollunroll(private_data->button_widget, (void *)w, 0);
51 }
52
53
54 xitk_disable_widget(private_data->label_widget);
55 xitk_disable_widget(private_data->button_widget);
56 }
57
58 }
59 }
60
notify_destroy(xitk_widget_t * w)61 static void notify_destroy(xitk_widget_t *w) {
62
63 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
64 (w->type & WIDGET_GROUP_WIDGET))) {
65 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
66
67 if(private_data->visible)
68 _combo_rollunroll(private_data->button_widget, (void *)w, 0);
69
70 xitk_destroy_widgets(private_data->widget_list);
71
72 xitk_unregister_event_handler(&private_data->widget_key);
73 xitk_window_destroy_window(private_data->imlibdata, private_data->xwin);
74
75 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
76 XFreeGC(private_data->imlibdata->x.disp, private_data->widget_list->gc);
77 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
78
79 xitk_widget_list_defferred_destroy (private_data->widget_list);
80
81 XITK_FREE(private_data->skin_element_name);
82 free(private_data);
83 }
84 }
85
86 /*
87 *
88 */
paint(xitk_widget_t * w)89 static void paint(xitk_widget_t *w) {
90
91 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
92 (w->type & WIDGET_GROUP_WIDGET))) {
93 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
94
95 if(private_data->visible == 1 && (w->visible < 1)) {
96 xitk_checkbox_set_state(private_data->button_widget, 0);
97 _combo_rollunroll(private_data->button_widget, (void *)w, 0);
98 }
99 if(w->visible == 1) {
100 int bx, lw;
101
102 lw = xitk_get_widget_width(private_data->label_widget);
103 xitk_set_widget_pos(private_data->label_widget, w->x, w->y);
104 bx = w->x + lw;
105 xitk_set_widget_pos(private_data->button_widget, bx, w->y);
106
107 xitk_show_widget(private_data->label_widget);
108 xitk_show_widget(private_data->button_widget);
109 }
110 else {
111 xitk_hide_widget(private_data->label_widget);
112 xitk_hide_widget(private_data->button_widget);
113 }
114 }
115 }
116
117 /*
118 *
119 */
xitk_combo_callback_exec(xitk_widget_t * w)120 void xitk_combo_callback_exec(xitk_widget_t *w) {
121
122 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
123 (w->type & WIDGET_GROUP_WIDGET))) {
124 combo_private_data_t *private_data = (combo_private_data_t *)w->private_data;
125
126 if(private_data->callback)
127 private_data->callback(private_data->combo_widget,
128 private_data->userdata, private_data->selected);
129
130 }
131 }
132
133 /*
134 * Called on select action.
135 */
combo_select(xitk_widget_t * w,void * data,int selected)136 static void combo_select(xitk_widget_t *w, void *data, int selected) {
137
138 if(w && ((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER)) {
139 xitk_widget_t *c = (xitk_widget_t *) ((browser_private_data_t *)w->private_data)->userdata;
140 combo_private_data_t *private_data = (combo_private_data_t *)c->private_data;
141
142 private_data->selected = selected;
143
144 xitk_label_change_label(private_data->label_widget, private_data->entries[selected]);
145
146 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
147 XUnmapWindow(private_data->imlibdata->x.disp, (xitk_window_get_window(private_data->xwin)));
148 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
149
150 private_data->visible = 0;
151
152 xitk_browser_release_all_buttons(private_data->browser_widget);
153 xitk_browser_update_list(private_data->browser_widget,
154 (const char* const*)private_data->entries, NULL,
155 private_data->num_entries, 0);
156
157 xitk_checkbox_set_state(private_data->button_widget, 0);
158
159 if(private_data->callback)
160 private_data->callback(private_data->combo_widget, private_data->userdata, selected);
161
162 }
163 }
164
165 /*
166 * Handle Xevents here.
167 */
_combo_handle_event(XEvent * event,void * data)168 static void _combo_handle_event(XEvent *event, void *data) {
169 combo_private_data_t *private_data = (combo_private_data_t *)data;
170
171 switch(event->type) {
172
173 case ButtonRelease:
174 /*
175 * If we try to move the combo window,
176 * move it back to right position (under label*
177 */
178 if(private_data && private_data->visible) {
179 int x, y;
180 xitk_window_get_window_position(private_data->combo_widget->imlibdata,
181 private_data->xwin, &x, &y, NULL, NULL);
182 if((x != private_data->win_x) || (y != private_data->win_y))
183 xitk_combo_update_pos(private_data->combo_widget);
184 }
185 break;
186 }
187 }
188
189 /*
190 *
191 */
notify_change_skin(xitk_widget_t * w,xitk_skin_config_t * skonfig)192 static void notify_change_skin(xitk_widget_t *w, xitk_skin_config_t *skonfig) {
193
194 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
195 (w->type & WIDGET_GROUP_WIDGET))) {
196 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
197
198 if(private_data->skin_element_name) {
199 int x, y;
200
201 xitk_skin_lock(skonfig);
202
203 w->visible = (xitk_skin_get_visibility(skonfig, private_data->skin_element_name)) ? 1 : -1;
204 w->enable = xitk_skin_get_enability(skonfig, private_data->skin_element_name);
205
206 xitk_set_widget_pos(w, w->x, w->y);
207 xitk_get_widget_pos(private_data->label_widget, &x, &y);
208
209 w->x = x;
210 w->y = y;
211
212 x += xitk_get_widget_width(private_data->label_widget);
213
214 (void) xitk_set_widget_pos(private_data->button_widget, x, y);
215
216 xitk_skin_unlock(skonfig);
217 }
218 }
219 }
220
tips_timeout(xitk_widget_t * w,unsigned long timeout)221 static void tips_timeout(xitk_widget_t *w, unsigned long timeout) {
222 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
223 (w->type & WIDGET_GROUP_WIDGET))) {
224 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
225
226 private_data->combo_widget->tips_timeout = timeout;
227 private_data->label_widget->tips_timeout = timeout;
228 private_data->button_widget->tips_timeout = timeout;
229 private_data->browser_widget->tips_timeout = timeout;
230 }
231 }
232
notify_event(xitk_widget_t * w,widget_event_t * event,widget_event_result_t * result)233 static int notify_event(xitk_widget_t *w, widget_event_t *event, widget_event_result_t *result) {
234 int retval = 0;
235
236 switch(event->type) {
237 case WIDGET_EVENT_PAINT:
238 paint(w);
239 break;
240 case WIDGET_EVENT_CHANGE_SKIN:
241 notify_change_skin(w, event->skonfig);
242 break;
243 case WIDGET_EVENT_DESTROY:
244 notify_destroy(w);
245 break;
246 case WIDGET_EVENT_ENABLE:
247 enability(w);
248 break;
249 case WIDGET_EVENT_TIPS_TIMEOUT:
250 tips_timeout(w, event->tips_timeout);
251 break;
252 }
253
254 return retval;
255 }
256
257 /*
258 *
259 */
_combo_rollunroll(xitk_widget_t * w,void * data,int state)260 static void _combo_rollunroll(xitk_widget_t *w, void *data, int state) {
261 xitk_widget_t *combo = (xitk_widget_t *)data;
262 combo_private_data_t *private_data = (combo_private_data_t *)combo->private_data;
263
264 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
265 ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX))) {
266
267 if(state && private_data->visible == 0) {
268 private_data->visible = 1;
269 xitk_combo_update_pos(combo);
270 }
271 else {
272 private_data->visible = 0;
273
274 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
275 XUnmapWindow(private_data->imlibdata->x.disp, (xitk_window_get_window(private_data->xwin)));
276 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
277 }
278 }
279 }
280
281 /*
282 *
283 */
_combo_rollunroll_from_lbl(xitk_widget_t * w,void * data)284 static void _combo_rollunroll_from_lbl(xitk_widget_t *w, void *data) {
285 xitk_widget_t *combo = (xitk_widget_t *)data;
286 combo_private_data_t *private_data = (combo_private_data_t *)combo->private_data;
287
288 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
289 ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_LABEL))) {
290 int state;
291
292 state = !xitk_checkbox_get_state(private_data->button_widget);
293
294 xitk_checkbox_set_state(private_data->button_widget, state);
295
296 if(state && private_data->visible == 0) {
297 w->wl->widget_focused = private_data->button_widget;
298 private_data->visible = 1;
299 xitk_combo_update_pos(combo);
300 }
301 else {
302 private_data->visible = 0;
303
304 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
305 XUnmapWindow(private_data->imlibdata->x.disp, (xitk_window_get_window(private_data->xwin)));
306 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
307 }
308
309 }
310 }
311
312 /*
313 * ************************* END OF PRIVATES *******************************
314 */
315
xitk_combo_is_same_parent(xitk_widget_t * w1,xitk_widget_t * w2)316 int xitk_combo_is_same_parent(xitk_widget_t *w1, xitk_widget_t *w2) {
317
318 if((w1 && w2) && ((w1->type & WIDGET_GROUP_COMBO) && (w1->type & WIDGET_GROUP_COMBO))) {
319
320 if(w1 == w2)
321 return 1;
322
323 if(w1->wl == w2->wl) {
324 xitk_widget_list_t *wl = w1->wl;
325 xitk_widget_t *w, *wt;
326
327 w = (xitk_widget_t *)wl->list.head.next;
328 while (w->node.next && ((w != w1) && (w != w2))) {
329 w = (xitk_widget_t *)w->node.next;
330 }
331
332 if (w->node.next) {
333
334 wt = (w == w1) ? w2 : w1;
335
336 if((w->type & WIDGET_GROUP_COMBO) &&
337 ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_LABEL)) {
338 w = (xitk_widget_t *)w->node.next;
339 if (w->node.next)
340 w = (xitk_widget_t *)w->node.next;
341 }
342 else if((w->type & WIDGET_GROUP_COMBO) &&
343 ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX)) {
344 w = (xitk_widget_t *)w->node.next;
345 }
346
347 if (w->node.next && ((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
348 (w->type & WIDGET_GROUP_WIDGET)) {
349 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
350
351 if((wt == private_data->label_widget) || (wt == private_data->button_widget))
352 return 1;
353
354 }
355
356 }
357 }
358 }
359 return 0;
360 }
361
362 /*
363 *
364 */
xitk_combo_rollunroll(xitk_widget_t * w)365 void xitk_combo_rollunroll(xitk_widget_t *w) {
366
367 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO))) {
368
369 if((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_CHECKBOX) {
370 int state = !xitk_checkbox_get_state(w);
371 xitk_checkbox_callback_exec(w);
372 xitk_checkbox_set_state(w, state);
373 }
374 }
375 else if(w->type & WIDGET_GROUP_WIDGET) {
376 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
377 int state = !xitk_checkbox_get_state(private_data->button_widget);
378 xitk_checkbox_callback_exec(private_data->button_widget);
379 xitk_checkbox_set_state(private_data->button_widget, state);
380 }
381 }
382
383 /*
384 *
385 */
xitk_combo_set_select(xitk_widget_t * w,int select)386 void xitk_combo_set_select(xitk_widget_t *w, int select) {
387
388 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
389 (w->type & WIDGET_GROUP_WIDGET))) {
390 combo_private_data_t *private_data = (combo_private_data_t *)w->private_data;
391
392 if(private_data->entries && private_data->entries[select]) {
393 private_data->selected = select;
394 xitk_label_change_label(private_data->label_widget, private_data->entries[select]);
395 }
396
397 }
398 }
399
400 /*
401 *
402 */
xitk_combo_update_pos(xitk_widget_t * w)403 void xitk_combo_update_pos(xitk_widget_t *w) {
404
405 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
406 (w->type & WIDGET_GROUP_WIDGET))) {
407 combo_private_data_t *private_data = (combo_private_data_t *)w->private_data;
408 int xx = 0, yy = 0;
409 window_info_t wi;
410 XSizeHints hint;
411
412 if(private_data->visible) {
413 if((xitk_get_window_info(*(private_data->parent_wkey), &wi))) {
414 private_data->win_x = wi.x;
415 private_data->win_y = wi.y;
416 WINDOW_INFO_ZERO(&wi);
417 }
418
419 xitk_get_widget_pos(private_data->label_widget, &xx, &yy);
420
421 yy += xitk_get_widget_height(private_data->label_widget);
422 private_data->win_x += xx;
423 private_data->win_y += yy;
424
425 hint.x = private_data->win_x;
426 hint.y = private_data->win_y;
427 hint.flags = PPosition;
428
429 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
430 XSetWMNormalHints (private_data->imlibdata->x.disp,
431 xitk_window_get_window(private_data->xwin),
432 &hint);
433 XMoveWindow(private_data->imlibdata->x.disp,
434 (xitk_window_get_window(private_data->xwin)),
435 private_data->win_x, private_data->win_y);
436 XMapRaised(private_data->imlibdata->x.disp, (xitk_window_get_window(private_data->xwin)));
437 XSync(private_data->imlibdata->x.disp, False);
438 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
439
440 while(!xitk_is_window_visible(private_data->imlibdata->x.disp,
441 (xitk_window_get_window(private_data->xwin))))
442 xitk_usec_sleep(5000);
443
444 XLOCK (private_data->imlibdata->x.x_lock_display, private_data->imlibdata->x.disp);
445 XSetInputFocus(private_data->imlibdata->x.disp,
446 (xitk_window_get_window(private_data->xwin)), RevertToParent, CurrentTime);
447 XUNLOCK (private_data->imlibdata->x.x_unlock_display, private_data->imlibdata->x.disp);
448
449 /* No widget focused, give focus to the first one */
450 if(private_data->widget_list->widget_focused == NULL)
451 xitk_set_focus_to_next_widget(private_data->widget_list, 0);
452
453 }
454 }
455 }
456
457 /*
458 *
459 */
xitk_combo_get_current_selected(xitk_widget_t * w)460 int xitk_combo_get_current_selected(xitk_widget_t *w) {
461
462 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
463 (w->type & WIDGET_GROUP_WIDGET))) {
464 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
465
466 return private_data->selected;
467 }
468
469 return -1;
470 }
471
472 /*
473 *
474 */
xitk_combo_get_current_entry_selected(xitk_widget_t * w)475 const char *xitk_combo_get_current_entry_selected(xitk_widget_t *w) {
476
477 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
478 (w->type & WIDGET_GROUP_WIDGET))) {
479 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
480
481 if(private_data->entries && private_data->selected >= 0)
482 return(private_data->entries[private_data->selected]);
483 }
484
485 return NULL;
486 }
487
488 /*
489 *
490 */
xitk_combo_update_list(xitk_widget_t * w,const char * const * const list,int len)491 void xitk_combo_update_list(xitk_widget_t *w, const char *const *const list, int len) {
492
493 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
494 (w->type & WIDGET_GROUP_WIDGET))) {
495 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
496
497 private_data->entries = list;
498 private_data->num_entries = len;
499 private_data->selected = -1;
500
501 xitk_browser_update_list(private_data->browser_widget,
502 (const char* const*)private_data->entries, NULL,
503 private_data->num_entries, 0);
504 }
505 }
506
507 /*
508 *
509 */
xitk_combo_get_label_widget(xitk_widget_t * w)510 xitk_widget_t *xitk_combo_get_label_widget(xitk_widget_t *w) {
511
512 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_COMBO) &&
513 (w->type & WIDGET_GROUP_WIDGET))) {
514 combo_private_data_t *private_data = (combo_private_data_t *) w->private_data;
515
516 return private_data->label_widget;
517 }
518
519 return NULL;
520 }
521
522 /*
523 *
524 */
_xitk_combo_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_combo_widget_t * c,const char * skin_element_name,xitk_widget_t * mywidget,combo_private_data_t * private_data,int visible,int enable)525 static xitk_widget_t *_xitk_combo_create(xitk_widget_list_t *wl,
526 xitk_skin_config_t *skonfig,
527 xitk_combo_widget_t *c, const char *skin_element_name,
528 xitk_widget_t *mywidget,
529 combo_private_data_t *private_data,
530 int visible, int enable) {
531 Atom XA_WIN_LAYER;
532 long data[1];
533 const char **entries = c->entries;
534 unsigned int itemw, itemh = 20;
535 unsigned int slidw = 12;
536 xitk_browser_widget_t browser;
537 XClassHint xclasshint;
538 Status status;
539
540 XITK_WIDGET_INIT(&browser, c->imlibdata);
541
542 itemw = xitk_get_widget_width(private_data->label_widget);
543 itemw += xitk_get_widget_width(private_data->button_widget);
544 itemw -= 2; /* space for border */
545
546 private_data->imlibdata = c->imlibdata;
547 private_data->skin_element_name = (skin_element_name == NULL) ? NULL : strdup(skin_element_name);
548 private_data->entries = c->entries;
549 private_data->combo_widget = mywidget;
550 private_data->parent_wlist = c->parent_wlist;
551 private_data->parent_wkey = c->parent_wkey;
552 private_data->callback = c->callback;
553 private_data->userdata = c->userdata;
554
555 private_data->selected = -1;
556 {
557 int i = 0;
558
559 while(entries[i] != NULL) {
560 i++;
561 }
562
563 private_data->num_entries = i;
564 }
565
566 if(private_data->num_entries) {
567 xitk_label_change_label(private_data->label_widget, entries[0]);
568 private_data->selected = 0;
569 }
570
571 private_data->xwin = xitk_window_create_simple_window(c->imlibdata, 0, 0,
572 (itemw + 2), (itemh * 5) + slidw + 2);
573 XLOCK (c->imlibdata->x.x_lock_display, c->imlibdata->x.disp);
574
575 {
576 XSetWindowAttributes attr;
577 attr.override_redirect = True;
578 XLOCK (c->imlibdata->x.x_lock_display, c->imlibdata->x.disp);
579 XChangeWindowAttributes (c->imlibdata->x.disp,
580 (xitk_window_get_window(private_data->xwin)),
581 CWOverrideRedirect, &attr);
582 XUNLOCK (c->imlibdata->x.x_unlock_display, c->imlibdata->x.disp);
583 }
584
585 if(c->layer_above) {
586 XA_WIN_LAYER = XInternAtom(c->imlibdata->x.disp, "_WIN_LAYER", False);
587
588 data[0] = 10;
589 XChangeProperty(c->imlibdata->x.disp,
590 (xitk_window_get_window(private_data->xwin)), XA_WIN_LAYER,
591 XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data,
592 1);
593 }
594
595 XSetTransientForHint (c->imlibdata->x.disp,
596 (xitk_window_get_window(private_data->xwin)), private_data->parent_wlist->win);
597
598 /* Change default classhint to new one. */
599 if((status = XGetClassHint(c->imlibdata->x.disp,
600 (xitk_window_get_window(private_data->xwin)), &xclasshint)) != BadWindow) {
601 XFree(xclasshint.res_name);
602 XFree(xclasshint.res_class);
603 xclasshint.res_name = (char *)"Xitk Combo";
604 xclasshint.res_class = (char *)"Xitk";
605 XSetClassHint(c->imlibdata->x.disp, (xitk_window_get_window(private_data->xwin)), &xclasshint);
606 }
607
608 private_data->gc = XCreateGC(c->imlibdata->x.disp,
609 (xitk_window_get_window(private_data->xwin)), None, None);
610
611 XUNLOCK (c->imlibdata->x.x_unlock_display, c->imlibdata->x.disp);
612
613 private_data->widget_list = xitk_widget_list_new() ;
614 xitk_dlist_init (&private_data->widget_list->list);
615 private_data->widget_list->win = (xitk_window_get_window(private_data->xwin));
616 private_data->widget_list->gc = private_data->gc;
617
618 /* Browser */
619 browser.imlibdata = private_data->imlibdata;
620 browser.arrow_up.skin_element_name = NULL;
621 browser.slider.skin_element_name = NULL;
622 browser.arrow_dn.skin_element_name = NULL;
623 browser.browser.skin_element_name = NULL;
624 browser.browser.max_displayed_entries = 5;
625 browser.browser.num_entries = private_data->num_entries;
626 browser.browser.entries = (const char* const*)private_data->entries;
627 browser.callback = combo_select;
628 browser.dbl_click_callback = NULL;
629 browser.parent_wlist = private_data->widget_list;
630 browser.userdata = (void*)mywidget;
631 private_data->browser_widget = xitk_noskin_browser_create (private_data->widget_list, &browser,
632 private_data->gc, 1, 1, (itemw - slidw), itemh, slidw, DEFAULT_FONT_10);
633 xitk_dlist_add_tail (&private_data->widget_list->list, &private_data->browser_widget->node);
634 xitk_enable_and_show_widget(private_data->browser_widget);
635 private_data->browser_widget->type |= WIDGET_GROUP | WIDGET_GROUP_COMBO;
636
637 xitk_browser_update_list(private_data->browser_widget,
638 (const char* const*)private_data->entries, NULL,
639 private_data->num_entries, 0);
640
641 private_data->widget_key =
642 xitk_register_event_handler("xitk combo",
643 (xitk_window_get_window(private_data->xwin)),
644 _combo_handle_event,
645 NULL,
646 NULL,
647 private_data->widget_list,
648 (void *) private_data);
649
650 private_data->visible = 0;
651
652 mywidget->private_data = private_data;
653 mywidget->wl = wl;
654 mywidget->enable = enable;
655 mywidget->running = 1;
656 mywidget->visible = visible;
657 mywidget->have_focus = FOCUS_LOST;
658
659 mywidget->imlibdata = private_data->imlibdata;
660 // mywidget->x = mywidget->y = mywidget->width = mywidget->height = 0;
661 mywidget->type = WIDGET_GROUP | WIDGET_GROUP_WIDGET | WIDGET_GROUP_COMBO;
662 mywidget->event = notify_event;
663 mywidget->tips_timeout = 0;
664 mywidget->tips_string = NULL;
665
666 return mywidget;
667 }
668
669 /*
670 *
671 */
xitk_combo_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_combo_widget_t * c,xitk_widget_t ** lw,xitk_widget_t ** bw)672 xitk_widget_t *xitk_combo_create(xitk_widget_list_t *wl,
673 xitk_skin_config_t *skonfig, xitk_combo_widget_t *c,
674 xitk_widget_t **lw, xitk_widget_t **bw) {
675 xitk_widget_t *mywidget;
676 combo_private_data_t *private_data;
677 xitk_checkbox_widget_t cb;
678 xitk_label_widget_t lbl;
679
680 XITK_CHECK_CONSTITENCY(c);
681
682 mywidget = (xitk_widget_t *) xitk_xmalloc (sizeof(xitk_widget_t));
683
684 XITK_WIDGET_INIT(&cb, c->imlibdata);
685 XITK_WIDGET_INIT(&lbl, c->imlibdata);
686
687 private_data = (combo_private_data_t *) xitk_xmalloc (sizeof(combo_private_data_t));
688
689 /* Create label and button (skinable) */
690 lbl.label = "";
691 lbl.skin_element_name = c->skin_element_name;
692 lbl.window = c->parent_wlist->win;
693 lbl.gc = c->parent_wlist->gc;
694 lbl.callback = _combo_rollunroll_from_lbl;
695 lbl.userdata = (void *)mywidget;
696 private_data->label_widget = xitk_label_create (c->parent_wlist, skonfig, &lbl);
697 xitk_dlist_add_tail (&c->parent_wlist->list, &private_data->label_widget->node);
698 private_data->label_widget->type |= WIDGET_GROUP | WIDGET_GROUP_COMBO;
699
700 cb.skin_element_name = c->skin_element_name;
701 cb.callback = _combo_rollunroll;
702 cb.userdata = (void *)mywidget;
703 private_data->button_widget = xitk_checkbox_create (c->parent_wlist, skonfig, &cb);
704 xitk_dlist_add_tail (&c->parent_wlist->list, &private_data->button_widget->node);
705 private_data->button_widget->type |= WIDGET_GROUP | WIDGET_GROUP_COMBO;
706
707 if(lw)
708 *lw = private_data->label_widget;
709 if(bw)
710 *bw = private_data->button_widget;
711
712 {
713 int x, y;
714
715 xitk_get_widget_pos(private_data->label_widget, &x, &y);
716
717 mywidget->x = x;
718 mywidget->y = y;
719
720 x += xitk_get_widget_width(private_data->label_widget);
721
722 (void) xitk_set_widget_pos(private_data->button_widget, x, y);
723 }
724 return _xitk_combo_create(wl, skonfig, c, c->skin_element_name, mywidget, private_data,
725 (xitk_skin_get_visibility(skonfig, c->skin_element_name)) ? 1 : -1,
726 xitk_skin_get_enability(skonfig, c->skin_element_name));
727 }
728
729 /*
730 * ******************************************************************************
731 */
xitk_noskin_combo_create(xitk_widget_list_t * wl,xitk_combo_widget_t * c,int x,int y,int width,xitk_widget_t ** lw,xitk_widget_t ** bw)732 xitk_widget_t *xitk_noskin_combo_create(xitk_widget_list_t *wl,
733 xitk_combo_widget_t *c,
734 int x, int y, int width,
735 xitk_widget_t **lw, xitk_widget_t **bw) {
736 xitk_widget_t *mywidget;
737 combo_private_data_t *private_data;
738 xitk_checkbox_widget_t cb;
739 xitk_label_widget_t lbl;
740
741 XITK_CHECK_CONSTITENCY(c);
742
743 mywidget = (xitk_widget_t *) xitk_xmalloc (sizeof(xitk_widget_t));
744
745 XITK_WIDGET_INIT(&cb, c->imlibdata);
746 XITK_WIDGET_INIT(&lbl, c->imlibdata);
747
748 private_data = (combo_private_data_t *) xitk_xmalloc (sizeof(combo_private_data_t));
749
750 /* Create label and button (skinable) */
751 {
752 xitk_font_t *fs;
753 int height;
754
755 fs = xitk_font_load_font(c->imlibdata->x.disp, DEFAULT_FONT_10);
756 xitk_font_set_font(fs, c->parent_wlist->gc);
757 height = xitk_font_get_string_height(fs, " ") + 4;
758 xitk_font_unload_font(fs);
759
760
761 lbl.window = c->parent_wlist->win;
762 lbl.gc = c->parent_wlist->gc;
763 lbl.skin_element_name = NULL;
764 lbl.label = "";
765 lbl.callback = _combo_rollunroll_from_lbl;
766 lbl.userdata = (void *)mywidget;
767 private_data->label_widget = xitk_noskin_label_create (c->parent_wlist, &lbl,
768 x, y, (width - height), height, DEFAULT_FONT_10);
769 xitk_dlist_add_tail (&c->parent_wlist->list, &private_data->label_widget->node);
770 private_data->label_widget->type |= WIDGET_GROUP | WIDGET_GROUP_COMBO;
771
772 cb.skin_element_name = NULL;
773 cb.callback = _combo_rollunroll;
774 cb.userdata = (void *)mywidget;
775
776 private_data->button_widget = xitk_noskin_checkbox_create (c->parent_wlist, &cb,
777 x + (width - height), y, height, height);
778 xitk_dlist_add_tail (&c->parent_wlist->list, &private_data->button_widget->node);
779 private_data->button_widget->type |= WIDGET_GROUP | WIDGET_GROUP_COMBO;
780
781 if(lw)
782 *lw = private_data->label_widget;
783 if(bw)
784 *bw = private_data->button_widget;
785
786 mywidget->x = x;
787 mywidget->y = y;
788 mywidget->width = width;
789 mywidget->height = height;
790
791 {
792 xitk_image_t *wimage = xitk_get_widget_foreground_skin(private_data->label_widget);
793
794 if(wimage)
795 draw_rectangular_inner_box(c->imlibdata, wimage->image, 0, 0, wimage->width - 1, wimage->height - 1);
796
797 wimage = xitk_get_widget_foreground_skin(private_data->button_widget);
798
799 if(wimage) {
800 draw_bevel_three_state(c->imlibdata, wimage);
801 draw_arrow_down(c->imlibdata, wimage);
802 }
803
804 }
805
806 }
807
808 return _xitk_combo_create(wl, NULL, c, NULL, mywidget, private_data, 0, 0);
809 }
810