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 <sys/time.h>
27 #include <unistd.h>
28
29 #include "_xitk.h"
30
31 #define WBUP 0 /* Position of button up in item_tree */
32 #define WSLID 1 /* Position of slider in item_tree */
33 #define WBDN 2 /* Position of button down in item_tree */
34 #define WBLF 3
35 #define WSLIDH 4
36 #define WBRT 5
37 #define WBSTART 6 /* Position of first item button in item_tree */
38
39 #define EXTRA_BTNS 50
40
41 static void notify_change_skin(xitk_widget_t *, xitk_skin_config_t *);
42 /*
43 *
44 */
paint(xitk_widget_t * w)45 static void paint(xitk_widget_t *w) {
46 browser_private_data_t *private_data;
47
48 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
49 (w->type & WIDGET_GROUP_WIDGET))) {
50 int i;
51
52 private_data = (browser_private_data_t *) w->private_data;
53
54 if(w->visible == 1) {
55 if(!private_data->skin_element_name) {
56 int x = w->x;
57 int y = w->y;
58 int itemw = xitk_get_widget_width(private_data->item_tree[WBSTART]);
59 int itemh = xitk_get_widget_height(private_data->item_tree[WBSTART]);
60 int iy = w->y;
61 int bh;
62
63 (void) xitk_set_widget_pos(private_data->item_tree[WBUP], x + itemw, y);
64 bh = xitk_get_widget_height(private_data->item_tree[WBUP]);
65 (void) xitk_set_widget_pos(private_data->item_tree[WSLID], x + itemw, y + bh);
66 bh += xitk_get_widget_height(private_data->item_tree[WSLID]);
67 (void) xitk_set_widget_pos(private_data->item_tree[WBDN], x + itemw, y + bh);
68 if(private_data->need_h_slider) {
69 #warning NEED
70
71 }
72
73 xitk_show_widget(private_data->item_tree[WBUP]);
74 xitk_show_widget(private_data->item_tree[WSLID]);
75 xitk_show_widget(private_data->item_tree[WBDN]);
76
77 xitk_show_widget(private_data->item_tree[WBLF]);
78 xitk_show_widget(private_data->item_tree[WSLIDH]);
79 xitk_show_widget(private_data->item_tree[WBRT]);
80
81 if(private_data->need_h_slider) {
82 #warning NEED
83 }
84
85 for(i = WBSTART; i < (private_data->max_length+WBSTART); i++) {
86 (void) xitk_set_widget_pos(private_data->item_tree[i], x, iy);
87 xitk_show_widget(private_data->item_tree[i]);
88 iy += itemh;
89 }
90 }
91 }
92 else {
93 for(i = 0; i < (private_data->max_length+WBSTART); i++) {
94 xitk_hide_widget(private_data->item_tree[i]);
95 }
96 }
97 }
98 }
99
notify_change_skin(xitk_widget_t * w,xitk_skin_config_t * skonfig)100 static void notify_change_skin(xitk_widget_t *w, xitk_skin_config_t *skonfig) {
101 browser_private_data_t *private_data;
102
103 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
104 (w->type & WIDGET_GROUP_WIDGET))) {
105
106 private_data = (browser_private_data_t *) w->private_data;
107
108 if(private_data->skin_element_name) {
109 int x, y, i = 0;
110
111 xitk_skin_lock(skonfig);
112
113 x = xitk_skin_get_coord_x(skonfig, private_data->skin_element_name);
114 y = xitk_skin_get_coord_y(skonfig, private_data->skin_element_name);
115 w->visible = (xitk_skin_get_visibility(skonfig, private_data->skin_element_name)) ? 1 : -1;
116 w->enable = xitk_skin_get_enability(skonfig, private_data->skin_element_name);
117
118 private_data->max_length = xitk_skin_get_browser_entries(skonfig,
119 private_data->skin_element_name);
120
121 for(i = WBSTART; i < (EXTRA_BTNS + WBSTART); i++) {
122 xitk_disable_widget(private_data->item_tree[i]);
123 xitk_hide_widget(private_data->item_tree[i]);
124 }
125
126 for(i = WBSTART; i < private_data->max_length + WBSTART; i++) {
127 (void) xitk_set_widget_pos(private_data->item_tree[i], x, y);
128 y += xitk_get_widget_height(private_data->item_tree[i]) + 1;
129 xitk_enable_and_show_widget(private_data->item_tree[i]);
130 }
131
132 xitk_browser_rebuild_browser(w, 0);
133
134 xitk_skin_unlock(skonfig);
135 }
136 }
137 }
138
notify_destroy(xitk_widget_t * w)139 static void notify_destroy(xitk_widget_t *w) {
140 browser_private_data_t *private_data;
141
142 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
143 (w->type & WIDGET_GROUP_WIDGET))) {
144 int i;
145
146 private_data = (browser_private_data_t *) w->private_data;
147
148 for(i = WBSTART; i < private_data->max_length + WBSTART + EXTRA_BTNS; i++)
149 XITK_FREE(private_data->bt[i]);
150
151 XITK_FREE(private_data->skin_element_name);
152 XITK_FREE(private_data);
153 }
154 }
155
enability(xitk_widget_t * w)156 static void enability(xitk_widget_t *w) {
157 browser_private_data_t *private_data;
158
159 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
160 (w->type & WIDGET_GROUP_WIDGET))) {
161 int i;
162 int max;
163
164 private_data = (browser_private_data_t *) w->private_data;
165
166 max = WBSTART;
167 max += (private_data->skin_element_name) ? EXTRA_BTNS : private_data->max_length;
168
169 if(w->enable == WIDGET_ENABLE) {
170 if(private_data->list_length >= private_data->max_length) {
171 xitk_enable_widget(private_data->item_tree[WBUP]);
172 xitk_enable_widget(private_data->item_tree[WSLID]);
173 xitk_enable_widget(private_data->item_tree[WBDN]);
174 }
175 if(private_data->need_h_slider) {
176 xitk_enable_widget(private_data->item_tree[WBLF]);
177 xitk_enable_widget(private_data->item_tree[WSLIDH]);
178 xitk_enable_widget(private_data->item_tree[WBRT]);
179 }
180 for(i = WBSTART; i < max; i++)
181 xitk_enable_widget(private_data->item_tree[i]);
182 }
183 else {
184 for(i = WBUP; i < max; i++)
185 xitk_disable_widget(private_data->item_tree[i]);
186 }
187 }
188 }
189
notify_event(xitk_widget_t * w,widget_event_t * event,widget_event_result_t * result)190 static int notify_event(xitk_widget_t *w, widget_event_t *event, widget_event_result_t *result) {
191 int retval = 0;
192
193 switch(event->type) {
194 case WIDGET_EVENT_PAINT:
195 paint(w);
196 break;
197 case WIDGET_EVENT_DESTROY:
198 notify_destroy(w);
199 break;
200 case WIDGET_EVENT_CHANGE_SKIN:
201 notify_change_skin(w, event->skonfig);
202 break;
203 case WIDGET_EVENT_ENABLE:
204 enability(w);
205 break;
206 }
207
208 return retval;
209 }
210
211 /**
212 * Return the number of displayed entries
213 */
xitk_browser_get_num_entries(xitk_widget_t * w)214 int xitk_browser_get_num_entries(xitk_widget_t *w) {
215 browser_private_data_t *private_data;
216
217 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
218 (w->type & WIDGET_GROUP_WIDGET))) {
219 private_data = (browser_private_data_t *) w->private_data;
220 return private_data->max_length;
221 }
222
223 return -1;
224 }
225
226 /**
227 * Return the real number of first displayed in list
228 */
xitk_browser_get_current_start(xitk_widget_t * w)229 int xitk_browser_get_current_start(xitk_widget_t *w) {
230 browser_private_data_t *private_data;
231
232 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
233 (w->type & WIDGET_GROUP_WIDGET))) {
234 private_data = (browser_private_data_t *) w->private_data;
235 return private_data->current_start;
236 }
237
238 return -1;
239 }
240
241 /**
242 * Change browser labels alignment
243 */
xitk_browser_set_alignment(xitk_widget_t * w,int align)244 void xitk_browser_set_alignment(xitk_widget_t *w, int align) {
245 browser_private_data_t *private_data;
246 int i;
247
248 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
249 (w->type & WIDGET_GROUP_WIDGET))) {
250
251 private_data = (browser_private_data_t *) w->private_data;
252
253 for(i = 0; i < private_data->max_length; i++) {
254 xitk_labelbutton_set_alignment(private_data->item_tree[i+WBSTART], align);
255 }
256
257 xitk_browser_rebuild_browser(w, -1);
258 }
259 }
260
261 /**
262 * Return the current selected button (if not, return -1)
263 */
xitk_browser_get_current_selected(xitk_widget_t * w)264 int xitk_browser_get_current_selected(xitk_widget_t *w) {
265 browser_private_data_t *private_data;
266 int i;
267
268 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
269 (w->type & WIDGET_GROUP_WIDGET))) {
270
271 private_data = (browser_private_data_t *) w->private_data;
272
273 for(i = 0; i < private_data->max_length; i++) {
274 if(xitk_labelbutton_get_state(private_data->item_tree[i+WBSTART]))
275 return (private_data->current_start + i);
276 }
277 }
278
279 return -1;
280 }
281
282 /**
283 * Release all enabled buttons
284 */
xitk_browser_release_all_buttons(xitk_widget_t * w)285 void xitk_browser_release_all_buttons(xitk_widget_t *w) {
286 browser_private_data_t *private_data;
287 int i;
288
289 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
290 (w->type & WIDGET_GROUP_WIDGET))) {
291
292 private_data = (browser_private_data_t *) w->private_data;
293
294 for(i = 0; i < private_data->max_length; i++) {
295 xitk_labelbutton_set_state(private_data->item_tree[i+WBSTART], 0);
296 }
297 }
298 }
299
300 /**
301 * Select the item 'select' in list
302 */
xitk_browser_set_select(xitk_widget_t * w,int select)303 void xitk_browser_set_select(xitk_widget_t *w, int select) {
304 browser_private_data_t *private_data;
305
306 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
307 (w->type & WIDGET_GROUP_WIDGET))) {
308
309 private_data = (browser_private_data_t *) w->private_data;
310
311 xitk_browser_release_all_buttons(w);
312
313 xitk_labelbutton_set_state(private_data->item_tree[(select - private_data->current_start) + WBSTART], 1);
314 private_data->current_button_clicked = xitk_browser_get_current_selected(w);
315 gettimeofday(&private_data->click_time, 0);
316 }
317 }
318
319 /**
320 * Redraw buttons/slider
321 */
xitk_browser_rebuild_browser(xitk_widget_t * w,int start)322 void xitk_browser_rebuild_browser(xitk_widget_t *w, int start) {
323 browser_private_data_t *private_data;
324 int i, j, max = 0;
325
326 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
327 (w->type & WIDGET_GROUP_WIDGET))) {
328 int item_width;
329 char *label_font;
330 xitk_font_t *fs = NULL;
331 int old_label_offset;
332
333 private_data = (browser_private_data_t *) w->private_data;
334 item_width = xitk_get_widget_width(private_data->item_tree[WBSTART]);
335 label_font = xitk_labelbutton_get_fontname(private_data->item_tree[WBSTART]);
336 old_label_offset = private_data->labels_offset;
337
338 xitk_browser_release_all_buttons(w);
339
340 j = (private_data->list_length > (private_data->max_length - 1) ?
341 (private_data->list_length - 1) : 1);
342
343 if(j <= (private_data->max_length - 1))
344 max = 0;
345 else if(j > (private_data->max_length - 1))
346 max = j - (private_data->max_length - 1);
347
348 if(((start >= 0) && max) || ((start == 0) && (max == 0)))
349 private_data->current_start = start;
350
351 private_data->need_h_slider = 0;
352 private_data->labels_offset = 0;
353
354 if(label_font) {
355 fs = xitk_font_load_font(private_data->imlibdata->x.disp, label_font);
356 xitk_font_set_font(fs, private_data->parent_wlist->gc);
357 }
358
359 if(private_data->shortcuts_content) {
360 int maxlen = 0;
361
362 for(i = 0; i < private_data->max_length; i++) {
363 char *nshortcut;
364
365 if((private_data->shortcuts_content[private_data->current_start + i]) &&
366 (nshortcut = private_data->shortcuts_content[private_data->current_start + i])) {
367 int nlen = strlen(nshortcut);
368
369 if(nlen > maxlen) {
370 maxlen = nlen;
371 }
372 }
373 }
374 }
375
376 if(fs) {
377 int label_width;
378 int j = 0;
379 int max = 0, offset = 0, len;
380
381 while(j < private_data->list_length) {
382 if((len = strlen(private_data->content[j])) > max) {
383 max = len;
384 offset = j;
385 }
386 j++;
387 }
388
389 label_width = (private_data->content && private_data->content[offset] && strlen(private_data->content[offset])) ? xitk_font_get_string_length(fs, private_data->content[offset]) : 0;
390
391 if(label_width > (item_width -2)) {
392 int diff_width = (label_width - (item_width - 2));
393
394 private_data->need_h_slider = 1;
395
396 if(private_data->labels_offset < diff_width)
397 private_data->labels_offset = diff_width;
398
399 }
400 else
401 private_data->need_h_slider = 0;
402 }
403
404 if(!private_data->need_h_slider) {
405 for(i = 0; i < private_data->max_length; i++)
406 xitk_labelbutton_set_label_offset(private_data->item_tree[i + WBSTART], 0);
407 }
408
409 for(i = 0; i < private_data->max_length; i++) {
410 if (((private_data->current_start + i) < private_data->list_length)
411 && (private_data->content[private_data->current_start + i] != NULL)) {
412
413 xitk_labelbutton_change_label(private_data->item_tree[i + WBSTART],
414 private_data->content[private_data->current_start + i]);
415
416 if(private_data->shortcuts_content) {
417 if(private_data->shortcuts_content[private_data->current_start + i])
418 xitk_labelbutton_change_shortcut_label(private_data->item_tree[i + WBSTART],
419 private_data->shortcuts_content[private_data->current_start + i],
420 item_width - (xitk_font_get_string_length(fs, private_data->shortcuts_content[private_data->current_start + i]) + 10),
421 NULL);
422 else
423 xitk_labelbutton_change_shortcut_label(private_data->item_tree[i + WBSTART], "", -1, NULL);
424 }
425
426 }
427 else {
428 xitk_labelbutton_change_label(private_data->item_tree[i+WBSTART], "");
429 xitk_labelbutton_change_shortcut_label(private_data->item_tree[i + WBSTART], "", -1, NULL);
430 }
431
432 }
433
434 XITK_FREE(label_font);
435
436 if(fs)
437 xitk_font_unload_font(fs);
438
439 if(private_data->need_h_slider) {
440 int npos, pos = xitk_slider_get_pos(private_data->item_tree[WSLIDH]);
441
442 xitk_enable_widget(private_data->item_tree[WSLIDH]);
443 xitk_enable_widget(private_data->item_tree[WBLF]);
444 xitk_enable_widget(private_data->item_tree[WBRT]);
445
446 if(private_data->labels_offset != old_label_offset) {
447 int align = xitk_labelbutton_get_alignment(private_data->item_tree[WBSTART]);
448
449 switch(align) {
450 case ALIGN_CENTER:
451 xitk_slider_set_min(private_data->item_tree[WSLIDH], -(private_data->labels_offset>>1));
452 xitk_slider_set_max(private_data->item_tree[WSLIDH], (private_data->labels_offset>>1));
453 break;
454 case ALIGN_LEFT:
455 xitk_slider_set_min(private_data->item_tree[WSLIDH], 0);
456 xitk_slider_set_max(private_data->item_tree[WSLIDH], private_data->labels_offset);
457 break;
458 case ALIGN_RIGHT:
459 xitk_slider_set_min(private_data->item_tree[WSLIDH], (-private_data->labels_offset) - 3);
460 xitk_slider_set_max(private_data->item_tree[WSLIDH], 0);
461 break;
462 }
463 }
464
465 if((pos > (npos = xitk_slider_get_max(private_data->item_tree[WSLIDH]))) ||
466 (pos < (npos = xitk_slider_get_min(private_data->item_tree[WSLIDH]))))
467 pos = npos;
468
469 xitk_slider_set_pos(private_data->item_tree[WSLIDH], pos);
470 }
471 else {
472 xitk_disable_widget(private_data->item_tree[WBLF]);
473 xitk_disable_widget(private_data->item_tree[WSLIDH]);
474 xitk_disable_widget(private_data->item_tree[WBRT]);
475
476 xitk_slider_set_max(private_data->item_tree[WSLIDH], 1);
477 xitk_slider_set_min(private_data->item_tree[WSLIDH], 0);
478 xitk_slider_reset(private_data->item_tree[WSLIDH]);
479 }
480
481
482 xitk_slider_set_max(private_data->item_tree[WSLID], max);
483
484 if(private_data->list_length >= private_data->max_length) {
485 xitk_enable_widget(private_data->item_tree[WBUP]);
486 xitk_enable_widget(private_data->item_tree[WSLID]);
487 xitk_enable_widget(private_data->item_tree[WBDN]);
488 }
489 else {
490 xitk_disable_widget(private_data->item_tree[WBUP]);
491 xitk_disable_widget(private_data->item_tree[WSLID]);
492 xitk_disable_widget(private_data->item_tree[WBDN]);
493 }
494
495 if(start == 0)
496 xitk_slider_set_to_max(private_data->item_tree[WSLID]);
497 else if(max) {
498 xitk_slider_set_pos(private_data->item_tree[WSLID],
499 (xitk_slider_get_max(private_data->item_tree[WSLID])
500 - xitk_slider_get_min(private_data->item_tree[WSLID])
501 - (private_data->current_start)));
502 }
503
504 }
505 }
506
507 /**
508 * Update the list, and rebuild button list
509 */
xitk_browser_update_list(xitk_widget_t * w,const char * const * list,const char * const * shortcut,int len,int start)510 void xitk_browser_update_list(xitk_widget_t *w, const char *const *list, const char *const *shortcut, int len, int start) {
511 browser_private_data_t *private_data;
512
513 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
514 (w->type & WIDGET_GROUP_WIDGET))) {
515
516 private_data = (browser_private_data_t *) w->private_data;
517 private_data->content = (char **)list;
518 private_data->shortcuts_content = (char **)shortcut;
519 private_data->list_length = len;
520 xitk_browser_rebuild_browser(w, start);
521 }
522 }
523
524 /**
525 * Handle slider movments
526 */
browser_slidmove(xitk_widget_t * w,void * data,int pos)527 static void browser_slidmove(xitk_widget_t *w, void *data, int pos) {
528 browser_private_data_t *private_data;
529 int realpos;
530
531 if(w && ((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER)) {
532
533 private_data = (browser_private_data_t *) ((xitk_widget_t*)data)->private_data;
534
535 if(xitk_browser_get_current_selected(((xitk_widget_t*)data)) > -1)
536 xitk_browser_release_all_buttons(((xitk_widget_t*)data));
537
538 realpos =
539 xitk_slider_get_max(private_data->item_tree[WSLID])
540 - xitk_slider_get_min(private_data->item_tree[WSLID])
541 - pos;
542
543 if(private_data->list_length > (private_data->max_length-1))
544 xitk_browser_rebuild_browser(((xitk_widget_t*)data), realpos);
545 else
546 xitk_browser_rebuild_browser(((xitk_widget_t*)data), -1);
547 }
548 }
549
browser_hslidmove(xitk_widget_t * w,void * data,int pos)550 static void browser_hslidmove(xitk_widget_t *w, void *data, int pos) {
551 browser_private_data_t *private_data;
552
553 if(w && ((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER)) {
554 int i;
555
556 private_data = (browser_private_data_t *) ((xitk_widget_t*)data)->private_data;
557
558 if(private_data->labels_offset) {
559
560 for(i = 0; i < private_data->max_length; i++) {
561 if (((private_data->current_start + i) < private_data->list_length)
562 && (private_data->content[private_data->current_start + i] != NULL)) {
563
564 xitk_labelbutton_set_label_offset(private_data->item_tree[i + WBSTART], -pos);
565
566 xitk_labelbutton_change_label(private_data->item_tree[i + WBSTART],
567 private_data->content[private_data->current_start + i]);
568 if(private_data->shortcuts_content)
569 xitk_labelbutton_change_shortcut_label(private_data->item_tree[i + WBSTART],
570 private_data->shortcuts_content[private_data->current_start + i], -1, NULL);
571
572 }
573 else {
574 xitk_labelbutton_change_label(private_data->item_tree[i+WBSTART], "");
575 xitk_labelbutton_change_shortcut_label(private_data->item_tree[i + WBSTART], "", -1, NULL);
576 }
577 }
578 }
579 else
580 xitk_slider_reset(private_data->item_tree[WSLIDH]);
581
582 }
583 }
584
585 /**
586 * slide up
587 */
browser_up(xitk_widget_t * w,void * data)588 static void browser_up(xitk_widget_t *w, void *data) {
589 browser_private_data_t *private_data;
590
591 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
592 private_data = (browser_private_data_t *) ((xitk_widget_t*)data)->private_data;
593
594 xitk_slider_make_step(private_data->item_tree[WSLID]);
595 browser_slidmove(w, data, xitk_slider_get_pos(private_data->item_tree[WSLID]));
596
597 }
598 }
599
600 /**
601 * slide down
602 */
browser_down(xitk_widget_t * w,void * data)603 static void browser_down(xitk_widget_t *w, void *data) {
604 browser_private_data_t *private_data;
605
606 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
607 private_data = (browser_private_data_t *) ((xitk_widget_t*)data)->private_data;
608
609 xitk_slider_make_backstep(private_data->item_tree[WSLID]);
610 browser_slidmove(w, data, xitk_slider_get_pos(private_data->item_tree[WSLID]));
611
612 }
613 }
614
615 /**
616 * slide up (extern).
617 */
xitk_browser_step_up(xitk_widget_t * w,void * data)618 void xitk_browser_step_up(xitk_widget_t *w, void *data) {
619 browser_private_data_t *private_data;
620
621 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
622 (w->type & WIDGET_GROUP_WIDGET))) {
623 private_data = (browser_private_data_t *) w->private_data;
624
625 xitk_slider_make_backstep(private_data->item_tree[WSLID]);
626 browser_slidmove(w, w, xitk_slider_get_pos(private_data->item_tree[WSLID]));
627
628 }
629 }
630
xitk_browser_page_up(xitk_widget_t * w,void * data)631 void xitk_browser_page_up(xitk_widget_t *w, void *data) {
632 browser_private_data_t *private_data;
633
634 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
635 (w->type & WIDGET_GROUP_WIDGET))) {
636 int min, pos, npos, vis;
637
638 private_data = (browser_private_data_t *) w->private_data;
639
640 min = xitk_slider_get_min(private_data->item_tree[WSLID]);
641 npos = pos = xitk_slider_get_pos(private_data->item_tree[WSLID]);
642 vis = private_data->max_length;
643
644 if((pos - vis) >= min)
645 npos -= vis;
646 else
647 npos = min;
648
649 xitk_slider_set_pos(private_data->item_tree[WSLID], npos);
650 browser_slidmove(w, w, xitk_slider_get_pos(private_data->item_tree[WSLID]));
651
652 }
653 }
xitk_browser_page_down(xitk_widget_t * w,void * data)654 void xitk_browser_page_down(xitk_widget_t *w, void *data) {
655 browser_private_data_t *private_data;
656
657 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
658 (w->type & WIDGET_GROUP_WIDGET))) {
659 int max, pos, npos, vis;
660
661 private_data = (browser_private_data_t *) w->private_data;
662
663 max = xitk_slider_get_max(private_data->item_tree[WSLID]);
664 npos = pos = xitk_slider_get_pos(private_data->item_tree[WSLID]);
665 vis = private_data->max_length;
666
667 if((pos + vis) <= max)
668 npos += vis;
669 else
670 npos = max;
671
672 xitk_slider_set_pos(private_data->item_tree[WSLID], npos);
673 browser_slidmove(w, w, xitk_slider_get_pos(private_data->item_tree[WSLID]));
674
675 }
676 }
677
678 /**
679 * slide Down (extern).
680 */
xitk_browser_step_down(xitk_widget_t * w,void * data)681 void xitk_browser_step_down(xitk_widget_t *w, void *data) {
682 browser_private_data_t *private_data;
683
684 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
685 (w->type & WIDGET_GROUP_WIDGET))) {
686
687 private_data = (browser_private_data_t *) w->private_data;
688
689 xitk_slider_make_step(private_data->item_tree[WSLID]);
690 browser_slidmove(w, w, xitk_slider_get_pos(private_data->item_tree[WSLID]));
691
692 }
693 }
694
695
696 /**
697 * slide left (extern).
698 */
xitk_browser_step_left(xitk_widget_t * w,void * data)699 void xitk_browser_step_left(xitk_widget_t *w, void *data) {
700 browser_private_data_t *private_data;
701
702 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
703 (w->type & WIDGET_GROUP_WIDGET))) {
704 private_data = (browser_private_data_t *) w->private_data;
705
706 xitk_slider_make_backstep(private_data->item_tree[WSLIDH]);
707 browser_hslidmove(w, w, xitk_slider_get_pos(private_data->item_tree[WSLIDH]));
708
709 }
710 }
711 /**
712 * slide right (extern).
713 */
xitk_browser_step_right(xitk_widget_t * w,void * data)714 void xitk_browser_step_right(xitk_widget_t *w, void *data) {
715 browser_private_data_t *private_data;
716
717 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
718 (w->type & WIDGET_GROUP_WIDGET))) {
719
720 private_data = (browser_private_data_t *) w->private_data;
721
722 xitk_slider_make_step(private_data->item_tree[WSLIDH]);
723 browser_hslidmove(w, w, xitk_slider_get_pos(private_data->item_tree[WSLIDH]));
724
725 }
726 }
727
browser_left(xitk_widget_t * w,void * data)728 static void browser_left(xitk_widget_t *w, void *data) {
729 browser_private_data_t *private_data;
730
731 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
732 private_data = (browser_private_data_t *) ((xitk_widget_t*)data)->private_data;
733
734 xitk_slider_make_backstep(private_data->item_tree[WSLIDH]);
735 browser_hslidmove(w, data, xitk_slider_get_pos(private_data->
736 item_tree[WSLIDH]));
737 }
738 }
browser_right(xitk_widget_t * w,void * data)739 static void browser_right(xitk_widget_t *w, void *data) {
740 browser_private_data_t *private_data;
741
742 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_BUTTON)) {
743 private_data = (browser_private_data_t *) ((xitk_widget_t*)data)->private_data;
744
745 xitk_slider_make_step(private_data->item_tree[WSLIDH]);
746 browser_hslidmove(w, data, xitk_slider_get_pos(private_data->
747 item_tree[WSLIDH]));
748 }
749 }
750
751 /**
752 * Handle list selections
753 */
browser_select(xitk_widget_t * w,void * data,int state)754 static void browser_select(xitk_widget_t *w, void *data, int state) {
755 browser_private_data_t *private_data;
756 int i, btn_selected;
757
758 if(w && ((w->type & WIDGET_TYPE_MASK) == WIDGET_TYPE_LABELBUTTON)) {
759
760 private_data = (browser_private_data_t*) ((btnlist_t*)data)->itemlist->private_data;
761
762 if(private_data->dbl_click_callback || private_data->callback) {
763 if(!strcasecmp((xitk_labelbutton_get_label(private_data-> item_tree[(int)((btnlist_t*)data)->sel])), "")) {
764 xitk_labelbutton_set_state((xitk_widget_t*)(private_data->item_tree[(int)((btnlist_t*)data)->sel]), 0);
765 }
766
767 for(i = WBSTART; i < private_data->max_length+WBSTART; i++) {
768 if((xitk_labelbutton_get_state(private_data->item_tree[i])) && (i != ((btnlist_t*)data)->sel)) {
769 xitk_labelbutton_set_state(private_data->item_tree[i], 0);
770 }
771 }
772
773 if((btn_selected = xitk_browser_get_current_selected(((btnlist_t*)data)->itemlist)) > -1) {
774 int cb2 = 0;
775 /* Callback call */
776 private_data->jumped = btn_selected;
777
778 /* A button is currently selected */
779 private_data->current_button_clicked = btn_selected;
780
781 if(private_data->last_button_clicked == private_data->current_button_clicked) {
782 struct timeval old_click_time, tm_diff;
783 long int click_diff;
784
785 private_data->last_button_clicked = -1;
786
787 timercpy(&private_data->click_time, &old_click_time);
788 gettimeofday(&private_data->click_time, 0);
789 timersub(&private_data->click_time, &old_click_time, &tm_diff);
790 click_diff = (tm_diff.tv_sec * 1000) + (tm_diff.tv_usec / 1000.0);
791
792 /* Ok, double click occur, call cb */
793 if(click_diff < private_data->dbl_click_time) {
794 private_data->click_time.tv_sec -= (xitk_get_timer_dbl_click() / 1000.0);
795 private_data->click_time.tv_usec -= (xitk_get_timer_dbl_click() * 1000.0);
796 if(private_data->dbl_click_callback)
797 cb2 = 1;
798 }
799
800 }
801 else {
802 private_data->last_button_clicked = private_data->current_button_clicked;
803 }
804
805 gettimeofday(&private_data->click_time, 0);
806
807 if(private_data->callback)
808 private_data->callback(((btnlist_t*)data)->itemlist, private_data->userdata, btn_selected);
809 if(cb2) {
810 private_data->dbl_click_callback(((btnlist_t*)data)->itemlist/*w*/,
811 private_data->userdata,
812 private_data->current_button_clicked);
813 }
814 /*
815 if(private_data->last_button_clicked == -1)
816 private_data->last_button_clicked = private_data->current_button_clicked;
817 */
818
819 }
820 else if((xitk_browser_get_current_selected(((btnlist_t*)data)->itemlist) < 0)
821 && (private_data->current_button_clicked > -1)) {
822 struct timeval old_click_time, tm_diff;
823 long int click_diff;
824 int cur_clicked = private_data->current_button_clicked;
825
826 timercpy(&private_data->click_time, &old_click_time);
827 gettimeofday(&private_data->click_time, 0);
828 timersub(&private_data->click_time, &old_click_time, &tm_diff);
829 click_diff = (tm_diff.tv_sec * 1000) + (tm_diff.tv_usec / 1000.0);
830
831 private_data->last_button_clicked = private_data->current_button_clicked;
832 private_data->current_button_clicked = -1;
833
834 gettimeofday(&private_data->click_time, 0);
835
836 /* Ok, double click occur, call cb */
837 if(click_diff < private_data->dbl_click_time) {
838 private_data->click_time.tv_sec -= (xitk_get_timer_dbl_click() / 1000.0);
839 private_data->click_time.tv_usec -= (xitk_get_timer_dbl_click() * 1000.0);
840 if(private_data->dbl_click_callback)
841 private_data->dbl_click_callback(((btnlist_t*)data)->itemlist,
842 private_data->userdata, cur_clicked);
843 }
844 }
845
846 }
847 else {
848 /* If there no callback, release selected button */
849 if((btn_selected = xitk_browser_get_current_selected(((btnlist_t*)data)->itemlist)) > -1) {
850 xitk_labelbutton_set_state(private_data->item_tree[(int)((btnlist_t*)data)->sel], 0);
851 }
852 }
853 }
854 }
855
856 /*
857 *
858 */
xitk_browser_get_browser(xitk_widget_t * w)859 xitk_widget_t *xitk_browser_get_browser(xitk_widget_t *w) {
860 xitk_widget_t *widget = NULL;
861
862 if(w && ((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER)) {
863 xitk_widget_list_t *wl = w->wl;
864
865 widget = (xitk_widget_t *)wl->list.head.next;
866 while (widget->node.next && (widget != w)) {
867 widget = (xitk_widget_t *)widget->node.next;
868 }
869 while (widget->node.next && (!(((widget->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
870 (widget->type & WIDGET_GROUP_WIDGET)))) {
871 widget = (xitk_widget_t *)widget->node.next;
872 }
873 }
874
875 return widget;
876 }
877
878 /*
879 * Jump to entry in list which match with the alphanum char key.
880 */
xitk_browser_warp_jump(xitk_widget_t * w,const char * key,int modifier)881 void xitk_browser_warp_jump(xitk_widget_t *w, const char *key, int modifier) {
882 browser_private_data_t *private_data;
883
884 if(w && (((w->type & WIDGET_GROUP_MASK) & WIDGET_GROUP_BROWSER) &&
885 (w->type & WIDGET_GROUP_WIDGET))) {
886
887 private_data = (browser_private_data_t *) w->private_data;
888
889 if(((modifier & 0xFFFFFFEF) == MODIFIER_NOMOD) || (modifier & MODIFIER_SHIFT)) {
890 int jumped;
891 int start, end, mark;
892 int focus;
893 widget_event_t event;
894
895 /* Jump wasn't happend yet */
896 if(private_data->jumped == -1)
897 jumped = 0;
898 else {
899 if((private_data->jumped + 1) < private_data->list_length)
900 jumped = private_data->jumped + 1;
901 else
902 jumped = 0;
903 }
904
905 start = jumped;
906 end = ((start - 1) > 0) ? (start - 1) : 0;
907 mark = private_data->list_length;
908
909
910 for(; start < mark; start++) {
911
912 if(!strncasecmp(private_data->content[start], key, strlen(key))) {
913
914 private_data->jumped = start;
915
916 focus = 0;
917 if((private_data->list_length - start) <= private_data->max_length) {
918
919 if(private_data->list_length >= private_data->max_length) {
920 focus = private_data->max_length - (private_data->list_length - start);
921 start = (private_data->list_length - private_data->max_length);
922 }
923 else
924 focus = start;
925
926 }
927
928 xitk_browser_rebuild_browser(w, start);
929
930 if(private_data->parent_wlist->widget_focused) {
931
932 if((private_data->parent_wlist->widget_focused->type & WIDGET_FOCUSABLE) &&
933 private_data->parent_wlist->widget_focused->enable == WIDGET_ENABLE) {
934
935 event.type = WIDGET_EVENT_FOCUS;
936 event.focus = FOCUS_LOST;
937
938 (void) private_data->parent_wlist->widget_focused->event(private_data->parent_wlist->widget_focused, &event, NULL);
939
940 private_data->parent_wlist->widget_focused->have_focus = FOCUS_LOST;
941 }
942
943 event.type = WIDGET_EVENT_PAINT;
944
945 (void) private_data->parent_wlist->widget_focused->event(private_data->parent_wlist->widget_focused, &event, NULL);
946
947 }
948
949 xitk_browser_set_select(w, focus + start);
950
951 private_data->parent_wlist->widget_focused = private_data->item_tree[WBSTART + focus];
952
953 if((private_data->parent_wlist->widget_focused->type & WIDGET_FOCUSABLE) &&
954 private_data->parent_wlist->widget_focused->enable == WIDGET_ENABLE) {
955
956 event.type = WIDGET_EVENT_FOCUS;
957 event.focus = FOCUS_RECEIVED;
958
959 (void) private_data->parent_wlist->widget_focused->event(private_data->parent_wlist->widget_focused, &event, NULL);
960
961 private_data->parent_wlist->widget_focused->have_focus = FOCUS_RECEIVED;
962
963 }
964
965 event.type = WIDGET_EVENT_PAINT;
966 (void) private_data->parent_wlist->widget_focused->event(private_data->parent_wlist->widget_focused, &event, NULL);
967
968 return;
969 }
970
971 if(((start + 1) == mark) && end) {
972 mark = end;
973 start = end = -1;
974 }
975 }
976
977 private_data->jumped = -1;
978 }
979 }
980 }
981
982 /**
983 * Create the list browser
984 */
_xitk_browser_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_browser_widget_t * br,int x,int y,int width,int height,const char * skin_element_name,xitk_widget_t * mywidget,browser_private_data_t * _private_data,int visible,int enable)985 static xitk_widget_t *_xitk_browser_create(xitk_widget_list_t *wl,
986 xitk_skin_config_t *skonfig, xitk_browser_widget_t *br,
987 int x, int y, int width, int height,
988 const char *skin_element_name,
989 xitk_widget_t *mywidget,
990 browser_private_data_t *_private_data,
991 int visible, int enable) {
992 browser_private_data_t *private_data = _private_data;
993 xitk_button_widget_t b;
994 xitk_labelbutton_widget_t lb;
995 xitk_slider_widget_t sl;
996
997 XITK_CHECK_CONSTITENCY(br);
998
999 XITK_WIDGET_INIT(&b, br->imlibdata);
1000 XITK_WIDGET_INIT(&lb, br->imlibdata);
1001 XITK_WIDGET_INIT(&sl, br->imlibdata);
1002
1003 private_data->bWidget = mywidget;
1004 private_data->imlibdata = br->imlibdata;
1005 private_data->skin_element_name = (skin_element_name == NULL) ? NULL : strdup(br->browser.skin_element_name);
1006 private_data->jumped = -1;
1007 private_data->content = (char **)br->browser.entries;
1008 private_data->shortcuts_content = NULL;
1009 private_data->list_length = br->browser.num_entries;
1010 private_data->max_length = br->browser.max_displayed_entries;
1011
1012 private_data->dbl_click_time = xitk_get_timer_dbl_click();
1013 gettimeofday(&private_data->click_time, 0);
1014
1015 if(br->dbl_click_callback)
1016 private_data->dbl_click_callback = br->dbl_click_callback;
1017 else
1018 private_data->dbl_click_callback = NULL;
1019
1020 private_data->current_button_clicked = -1;
1021 private_data->last_button_clicked = -1;
1022
1023 private_data->parent_wlist = br->parent_wlist;
1024
1025 private_data->callback = br->callback;
1026 private_data->userdata = br->userdata;
1027
1028 private_data->need_h_slider = 0;
1029 private_data->labels_offset = 0;
1030
1031 mywidget->private_data = private_data;
1032
1033 mywidget->wl = wl;
1034
1035 mywidget->enable = enable;
1036 mywidget->running = 1;
1037 mywidget->visible = visible;
1038 mywidget->have_focus = FOCUS_LOST;
1039
1040 mywidget->imlibdata = private_data->imlibdata;
1041 mywidget->x = x;
1042 mywidget->y = y;
1043 mywidget->width = width;
1044 mywidget->height = height;
1045 mywidget->type = WIDGET_GROUP | WIDGET_GROUP_WIDGET | WIDGET_GROUP_BROWSER;
1046 mywidget->event = notify_event;
1047 mywidget->tips_timeout = 0;
1048 mywidget->tips_string = NULL;
1049
1050 return mywidget;
1051 }
1052
1053 /**
1054 * Create the list browser
1055 */
xitk_browser_create(xitk_widget_list_t * wl,xitk_skin_config_t * skonfig,xitk_browser_widget_t * br)1056 xitk_widget_t *xitk_browser_create(xitk_widget_list_t *wl,
1057 xitk_skin_config_t *skonfig, xitk_browser_widget_t *br) {
1058 xitk_widget_t *mywidget;
1059 browser_private_data_t *private_data;
1060 xitk_button_widget_t b;
1061 xitk_labelbutton_widget_t lb;
1062 xitk_slider_widget_t sl;
1063
1064 XITK_CHECK_CONSTITENCY(br);
1065
1066 XITK_WIDGET_INIT(&b, br->imlibdata);
1067 XITK_WIDGET_INIT(&lb, br->imlibdata);
1068 XITK_WIDGET_INIT(&sl, br->imlibdata);
1069
1070 mywidget = (xitk_widget_t *) xitk_xmalloc(sizeof(xitk_widget_t));
1071 private_data = (browser_private_data_t *) xitk_xmalloc(sizeof(browser_private_data_t));
1072 private_data->skonfig = skonfig;
1073
1074
1075 br->browser.max_displayed_entries = xitk_skin_get_browser_entries(skonfig,
1076 br->browser.skin_element_name);
1077
1078 {
1079
1080 int x, y, i;
1081
1082 x = xitk_skin_get_coord_x(skonfig, br->browser.skin_element_name);
1083 y = xitk_skin_get_coord_y(skonfig, br->browser.skin_element_name);
1084
1085 for(i = WBSTART; i < (EXTRA_BTNS + WBSTART); i++) {
1086
1087 private_data->bt[i] = (btnlist_t *) xitk_xmalloc(sizeof(btnlist_t));
1088 private_data->bt[i]->itemlist = mywidget;
1089 private_data->bt[i]->sel = i;
1090
1091 lb.button_type = RADIO_BUTTON;
1092 lb.align = ALIGN_DEFAULT;
1093 lb.label = "";
1094 lb.callback = NULL;
1095 lb.state_callback = browser_select;
1096 lb.userdata = (void *)(private_data->bt[i]);
1097 lb.skin_element_name = br->browser.skin_element_name;
1098 private_data->item_tree[i] = xitk_labelbutton_create (br->parent_wlist, skonfig, &lb);
1099 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[i]->node);
1100 private_data->item_tree[i]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1101
1102 xitk_disable_widget(private_data->item_tree[i]);
1103 xitk_hide_widget(private_data->item_tree[i]);
1104
1105 (void) xitk_set_widget_pos(private_data->item_tree[i], x, y);
1106
1107 y += xitk_get_widget_height(private_data->item_tree[i]) + 1;
1108 }
1109
1110 for(i = WBSTART; i < (br->browser.max_displayed_entries + WBSTART); i++)
1111 xitk_enable_and_show_widget(private_data->item_tree[i]);
1112
1113 }
1114
1115 b.skin_element_name = br->arrow_up.skin_element_name;
1116 b.callback = browser_up;
1117 b.userdata = (void *)mywidget;
1118 private_data->item_tree[WBUP] = xitk_button_create (br->parent_wlist, skonfig, &b);
1119 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBUP]->node);
1120 private_data->item_tree[WBUP]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1121
1122 sl.min = 0;
1123 sl.max = (br->browser.num_entries > (br->browser.max_displayed_entries-1) ? br->browser.num_entries-1 : 0);
1124 sl.step = 1;
1125 sl.skin_element_name = br->slider.skin_element_name;
1126 sl.callback = browser_slidmove;
1127 sl.userdata = (void*)mywidget;
1128 sl.motion_callback = browser_slidmove;
1129 sl.motion_userdata = (void*)mywidget;
1130 private_data->item_tree[WSLID] = xitk_slider_create (br->parent_wlist, skonfig, &sl);
1131 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WSLID]->node);
1132 private_data->item_tree[WSLID]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1133
1134 xitk_slider_set_to_max(private_data->item_tree[WSLID]);
1135
1136 b.skin_element_name = br->arrow_dn.skin_element_name;
1137 b.callback = browser_down;
1138 b.userdata = (void *)mywidget;
1139 private_data->item_tree[WBDN] = xitk_button_create (br->parent_wlist, skonfig, &b);
1140 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBDN]->node);
1141 private_data->item_tree[WBDN]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1142
1143 b.skin_element_name = br->arrow_left.skin_element_name;
1144 b.callback = browser_left;
1145 b.userdata = (void *)mywidget;
1146 private_data->item_tree[WBLF] = xitk_button_create (br->parent_wlist, skonfig, &b);
1147 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBLF]->node);
1148 private_data->item_tree[WBLF]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1149
1150 sl.min = 0;
1151 sl.max = 1;
1152 sl.step = 1;
1153 sl.skin_element_name = br->slider_h.skin_element_name;
1154 sl.callback = browser_hslidmove;
1155 sl.userdata = (void*)mywidget;
1156 sl.motion_callback = browser_hslidmove;
1157 sl.motion_userdata = (void*)mywidget;
1158 private_data->item_tree[WSLIDH] = xitk_slider_create (br->parent_wlist, skonfig, &sl);
1159 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WSLIDH]->node);
1160 private_data->item_tree[WSLIDH]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1161
1162 xitk_slider_reset(private_data->item_tree[WSLIDH]);
1163
1164 b.skin_element_name = br->arrow_right.skin_element_name;
1165 b.callback = browser_right;
1166 b.userdata = (void *)mywidget;
1167 private_data->item_tree[WBRT] = xitk_button_create (br->parent_wlist, skonfig, &b);
1168 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBRT]->node);
1169 private_data->item_tree[WBRT]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1170
1171 return _xitk_browser_create(wl, skonfig, br,
1172 0, 0, 0, 0, br->browser.skin_element_name, mywidget, private_data,
1173 (xitk_skin_get_visibility(skonfig, br->browser.skin_element_name)) ? 1 : -1,
1174 xitk_skin_get_enability(skonfig, br->browser.skin_element_name));
1175 }
1176
1177 /*
1178 *
1179 */
xitk_noskin_browser_create(xitk_widget_list_t * wl,xitk_browser_widget_t * br,GC gc,int x,int y,int itemw,int itemh,int slidw,const char * fontname)1180 xitk_widget_t *xitk_noskin_browser_create(xitk_widget_list_t *wl,
1181 xitk_browser_widget_t *br, GC gc, int x, int y,
1182 int itemw, int itemh, int slidw, const char *fontname) {
1183 xitk_widget_t *mywidget;
1184 browser_private_data_t *private_data;
1185 xitk_button_widget_t b;
1186 xitk_labelbutton_widget_t lb;
1187 xitk_slider_widget_t sl;
1188 int btnh = (itemh - (itemh /2)) < slidw ? slidw : (itemh - (itemh /2));
1189
1190 XITK_CHECK_CONSTITENCY(br);
1191 XITK_WIDGET_INIT(&b, br->imlibdata);
1192 XITK_WIDGET_INIT(&lb, br->imlibdata);
1193 XITK_WIDGET_INIT(&sl, br->imlibdata);
1194
1195 mywidget = (xitk_widget_t *) xitk_xmalloc(sizeof(xitk_widget_t));
1196 private_data = (browser_private_data_t *) xitk_xmalloc(sizeof(browser_private_data_t));
1197 private_data->skonfig = NULL;
1198
1199 {
1200 int ix = x, iy = y, i;
1201 xitk_image_t *wimage;
1202
1203 for(i = WBSTART; i < (br->browser.max_displayed_entries+WBSTART); i++) {
1204
1205 private_data->bt[i] = (btnlist_t *) xitk_xmalloc(sizeof(btnlist_t));
1206 private_data->bt[i]->itemlist = mywidget;
1207 private_data->bt[i]->sel = i;
1208
1209 lb.button_type = RADIO_BUTTON;
1210 lb.label = "";
1211 lb.align = ALIGN_LEFT;
1212 lb.callback = NULL;
1213 lb.state_callback = browser_select;
1214 lb.userdata = (void *)(private_data->bt[i]);
1215 lb.skin_element_name = NULL;
1216 private_data->item_tree[i] = xitk_noskin_labelbutton_create (br->parent_wlist, &lb,
1217 ix, iy, itemw, itemh, "Black", "Black", "White", fontname);
1218 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[i]->node);
1219 private_data->item_tree[i]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1220
1221 wimage = xitk_get_widget_foreground_skin(private_data->item_tree[i]);
1222 if(wimage)
1223 draw_flat_three_state(br->imlibdata, wimage);
1224
1225 (void) xitk_set_widget_pos(private_data->item_tree[i], ix, iy);
1226
1227 iy += itemh;
1228
1229 }
1230 }
1231
1232 b.skin_element_name = NULL;
1233 b.callback = browser_up;
1234 b.userdata = (void *)mywidget;
1235 private_data->item_tree[WBUP] = xitk_noskin_button_create (br->parent_wlist, &b,
1236 x + itemw, y + 0, slidw, btnh);
1237 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBUP]->node);
1238 private_data->item_tree[WBUP]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1239
1240 { /* Draw arrow in button */
1241 xitk_image_t *wimage = xitk_get_widget_foreground_skin(private_data->item_tree[WBUP]);
1242
1243 if(wimage)
1244 draw_arrow_up(b.imlibdata, wimage);
1245
1246 }
1247
1248 sl.min = 0;
1249 sl.max = (br->browser.num_entries > (br->browser.max_displayed_entries-1) ? br->browser.num_entries-1 : 0);
1250 sl.step = 1;
1251 sl.skin_element_name = NULL;
1252 sl.callback = browser_slidmove;
1253 sl.userdata = (void*)mywidget;
1254 sl.motion_callback = browser_slidmove;
1255 sl.motion_userdata = (void*)mywidget;
1256 private_data->item_tree[WSLID] = xitk_noskin_slider_create (br->parent_wlist, &sl,
1257 x + itemw, y + btnh, slidw, (itemh * br->browser.max_displayed_entries) - (btnh * 2), XITK_VSLIDER);
1258 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WSLID]->node);
1259 private_data->item_tree[WSLID]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1260
1261 xitk_slider_set_to_max(private_data->item_tree[WSLID]);
1262
1263 b.skin_element_name = NULL;
1264 b.callback = browser_down;
1265 b.userdata = (void *)mywidget;
1266 private_data->item_tree[WBDN] = xitk_noskin_button_create (br->parent_wlist, &b,
1267 x + itemw, y + ((itemh * br->browser.max_displayed_entries) - btnh), slidw, btnh);
1268 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBDN]->node);
1269 private_data->item_tree[WBDN]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1270
1271 { /* Draw arrow in button */
1272 xitk_image_t *wimage = xitk_get_widget_foreground_skin(private_data->item_tree[WBDN]);
1273
1274 if(wimage)
1275 draw_arrow_down(b.imlibdata, wimage);
1276
1277 }
1278
1279 b.skin_element_name = NULL;
1280 b.callback = browser_left;
1281 b.userdata = (void *)mywidget;
1282 private_data->item_tree[WBLF] = xitk_noskin_button_create (br->parent_wlist, &b,
1283 x, y + (itemh * br->browser.max_displayed_entries), slidw, btnh);
1284 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBLF]->node);
1285 private_data->item_tree[WBLF]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1286
1287 { /* Draw arrow in button */
1288 xitk_image_t *wimage = xitk_get_widget_foreground_skin(private_data->item_tree[WBLF]);
1289
1290 if(wimage)
1291 draw_arrow_left(b.imlibdata, wimage);
1292
1293 }
1294
1295 sl.min = 0;
1296 sl.max = 1;
1297 sl.step = 1;
1298 sl.skin_element_name = NULL;
1299 sl.callback = browser_hslidmove;
1300 sl.userdata = (void*)mywidget;
1301 sl.motion_callback = browser_hslidmove;
1302 sl.motion_userdata = (void*)mywidget;
1303 private_data->item_tree[WSLIDH] = xitk_noskin_slider_create (br->parent_wlist, &sl,
1304 x + btnh, y + (itemh * br->browser.max_displayed_entries), (itemw - (btnh * 2)), slidw, XITK_HSLIDER);
1305 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WSLIDH]->node);
1306 private_data->item_tree[WSLIDH]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1307
1308 xitk_slider_reset(private_data->item_tree[WSLIDH]);
1309
1310 b.skin_element_name = NULL;
1311 b.callback = browser_right;
1312 b.userdata = (void *)mywidget;
1313 private_data->item_tree[WBRT] = xitk_noskin_button_create (br->parent_wlist, &b,
1314 x + (itemw - btnh), y + (itemh * br->browser.max_displayed_entries), slidw, btnh);
1315 xitk_dlist_add_tail (&br->parent_wlist->list, &private_data->item_tree[WBRT]->node);
1316 private_data->item_tree[WBRT]->type |= WIDGET_GROUP | WIDGET_GROUP_BROWSER;
1317
1318 { /* Draw arrow in button */
1319 xitk_image_t *wimage = xitk_get_widget_foreground_skin(private_data->item_tree[WBRT]);
1320
1321 if(wimage)
1322 draw_arrow_right(b.imlibdata, wimage);
1323
1324 }
1325
1326 return _xitk_browser_create(wl, NULL, br, x, y,
1327 (itemw + slidw), (itemh * br->browser.max_displayed_entries) + slidw,
1328 NULL, mywidget, private_data, 0, 0);
1329 }
1330
1331