This source file includes following definitions.
- find_menu_item
- menu_get_increment_factor
- menu_set_increment_factor
- menu_increment_factor_string
- menu_calc_max_increment_factor
- increment_factor
- decrement_factor
- gui_menu_set_curr_menu
- get_curr_menu
- gui_menu_init
- gui_menu_rows
- gui_menu_erase_and_redraw
- gui_menu_cancel_redraw
- gui_menu_color_selected
- gui_menu_back
- do_callback
- update_int_value
- update_bool_value
- update_enum_value
- isText
- gui_activate_sub_menu
- select_sub_menu
- select_proc
- gui_menu_updown
- gui_menu_touch_handler
- gui_menu_kbd_process
- gui_menu_draw_initial
- gui_menu_draw_symbol
- gui_set_int_cursor
- gui_menu_draw_value
- gui_menu_draw_text
- factor_disp_len
- get_int_disp_string
- gui_menu_draw_state_value
- menu_text
- gui_menu_draw
- gui_menu_kbd_process_menu_btn
1 #include "camera_info.h"
2 #include "conf.h"
3 #include "keyboard.h"
4 #include "font.h"
5 #include "lang.h"
6 #include "gui.h"
7 #include "gui_draw.h"
8 #include "gui_menu.h"
9 #include "gui_user_menu.h"
10 #include "gui_lang.h"
11 #include "ctype.h"
12
13 #include "gui_palette.h"
14
15
16 #define MENUSTACK_MAXDEPTH 4
17
18
19 typedef struct {
20 CMenu *menu;
21 int curpos;
22 int toppos;
23 } CMenuStacked;
24
25
26
27 static CMenu *curr_menu;
28 static CMenuStacked gui_menu_stack[MENUSTACK_MAXDEPTH];
29 static unsigned int gui_menu_stack_ptr;
30 static int gui_menu_curr_item;
31 static int gui_menu_top_item;
32 static int gui_menu_redraw;
33
34 static int count;
35 static int x, y;
36 static int w, wplus, num_lines;
37 static int len_bool, len_int, len_enum, len_space, len_br1, len_br2, cl_rect;
38 static int int_incr = 1;
39 static confColor *item_color;
40 static int item_color_type;
41
42
43 CMenuItem* find_menu_item(CMenu *curr_menu, int itemid )
44 {
45 int gui_menu_curr_item;
46 CMenuItem* rv=0;
47
48 if ( itemid==0 )
49 return 0;
50
51 gui_menu_curr_item = 0;
52 while(curr_menu->menu[gui_menu_curr_item].text) {
53 if ( lang_strhash31(curr_menu->menu[gui_menu_curr_item].text) == (unsigned)itemid){
54 return (CMenuItem*) &(curr_menu->menu[gui_menu_curr_item]);
55 }
56 if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) == MENUITEM_SUBMENU)
57 {
58 if (curr_menu->menu[gui_menu_curr_item].text != LANG_MENU_USER_MENU) {
59 rv = find_menu_item((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), itemid);
60 if ( rv )
61 return rv;
62 }
63 }
64 gui_menu_curr_item++;
65 }
66 return 0;
67 }
68
69
70
71
72
73 int menu_get_increment_factor()
74 {
75 return int_incr;
76 }
77
78 void menu_set_increment_factor(int n)
79 {
80 int_incr = n;
81 }
82
83
84 char *menu_increment_factor_string()
85 {
86 static char buf[8];
87 buf[0] = 0;
88 if (int_incr >= 1000000)
89 sprintf(buf, "\xb1%dM",int_incr/1000000);
90 else if (int_incr >= 1000)
91 sprintf(buf, "\xb1%dK",int_incr/1000);
92 else
93 sprintf(buf, "\xb1%d",int_incr);
94 return buf;
95 }
96
97
98 int menu_calc_max_increment_factor(int max_value)
99 {
100 int max = 1;
101 while (max_value/10 != 0)
102 {
103 max *= 10;
104 max_value /= 10;
105 }
106 return max;
107 }
108
109
110
111
112
113 #define MAX(a,b) ((a>=b)?a:b)
114
115 static int increment_factor()
116 {
117
118
119
120
121 int item_flags = curr_menu->menu[gui_menu_curr_item].type;
122 int item_type = item_flags & MENUITEM_MASK;
123 int item_arg = curr_menu->menu[gui_menu_curr_item].arg;
124 int item_val = *(curr_menu->menu[gui_menu_curr_item].value);
125
126 if (item_type == MENUITEM_STATE_VAL_PAIR)
127 {
128 CMenuItem *c = (CMenuItem*)(curr_menu->menu[gui_menu_curr_item].value);
129 item_flags = c[0].type;
130 item_type = item_flags & MENUITEM_MASK;
131 item_arg = c[0].arg;
132 item_val = *(c[0].value);
133 }
134
135
136
137 int max = (item_flags & MENUITEM_DECIMAL) ? 100000 : (item_type == MENUITEM_INT) ? ((item_val < 0) ? 1000 : 10000) : 1;
138
139
140 int vmax = 0;
141 if ( item_flags & MENUITEM_F_MINMAX )
142 {
143 if ( item_flags & MENUITEM_F_UNSIGNED )
144 {
145 vmax = MAX(MENU_MIN_UNSIGNED(item_arg),MENU_MAX_UNSIGNED(item_arg));
146 }
147 else
148 {
149 vmax = MAX(abs(MENU_MIN_SIGNED(item_arg)),abs(MENU_MAX_SIGNED(item_arg)));
150 }
151 }
152
153
154 if (item_flags & MENUITEM_SD_INT)
155 {
156 vmax = item_arg;
157 }
158
159
160 if (vmax > 0)
161 {
162 max = menu_calc_max_increment_factor(vmax);
163 }
164
165
166 if (item_flags & MENUITEM_HHMMSS)
167 {
168 max = 100;
169 }
170
171
172 if (int_incr < max)
173 {
174 int_incr *= 10;
175 return 1;
176 }
177 if (int_incr > max)
178 {
179 int_incr = max;
180 return 1;
181 }
182
183 return 0;
184 }
185
186 static int decrement_factor()
187 {
188
189
190
191 if (int_incr > 1)
192 {
193 int_incr /= 10;
194 return 1;
195 }
196 return 0;
197 }
198
199
200 static void gui_menu_set_curr_menu(CMenu *menu_ptr, int top_item, int curr_item) {
201 curr_menu = menu_ptr;
202 gui_menu_top_item = top_item;
203 gui_menu_curr_item = curr_item;
204 }
205
206 CMenu* get_curr_menu()
207 {
208 return curr_menu;
209 }
210
211
212 void gui_menu_init(CMenu *menu_ptr) {
213
214 if (menu_ptr) {
215 if (conf.menu_select_first_entry)
216 gui_menu_set_curr_menu(menu_ptr, 0, 0);
217 else
218 gui_menu_set_curr_menu(menu_ptr, 0, -1);
219 gui_menu_stack_ptr = 0;
220
221
222 extern void set_tv_override_menu(CMenu *menu);
223 set_tv_override_menu(curr_menu);
224 }
225
226 len_bool = rbf_str_width("\x95");
227 len_int = rbf_str_width("99999");
228 len_enum = rbf_str_width("WUBfS3a");
229 len_space = rbf_char_width(' ');
230 len_br1 = rbf_char_width('[');
231 len_br2 = rbf_char_width(']');
232 cl_rect = rbf_font_height() - 4;
233 int_incr = 1;
234
235 gui_menu_redraw=2;
236 }
237
238
239 static int gui_menu_rows()
240 {
241 int n;
242
243 for(n = 0; curr_menu->menu[n].text; n++);
244 return n;
245 }
246
247
248
249 void gui_menu_erase_and_redraw()
250 {
251 gui_menu_redraw = 2;
252 gui_set_need_restore();
253 }
254 void gui_menu_cancel_redraw()
255 {
256 gui_menu_redraw = 0;
257 gui_cancel_need_restore();
258 }
259
260
261
262
263 static void gui_menu_color_selected(chdkColor clr)
264 {
265 if (item_color_type == MENUITEM_COLOR_FG)
266 {
267 item_color->fg = clr;
268 }
269 else
270 {
271 item_color->bg = clr;
272 }
273 gui_menu_erase_and_redraw();
274 }
275
276
277
278 void gui_menu_back()
279 {
280 if (gui_menu_stack_ptr > 0)
281 {
282 gui_menu_stack_ptr--;
283 gui_menu_set_curr_menu(gui_menu_stack[gui_menu_stack_ptr].menu, gui_menu_stack[gui_menu_stack_ptr].toppos, gui_menu_stack[gui_menu_stack_ptr].curpos);
284 gui_menu_erase_and_redraw();
285 }
286 else
287 {
288
289
290
291 gui_set_mode(&altGuiHandler);
292 }
293 }
294
295
296
297
298
299
300 static void do_callback(const CMenuItem *mi)
301 {
302 if ((mi->type & MENUITEM_ARG_MASK) == MENUITEM_ARG_CALLBACK && mi->arg)
303 {
304 ((void (*)())(mi->arg))();
305 }
306 }
307
308
309 static void update_int_value(const CMenuItem *mi, int direction)
310 {
311
312 *(mi->value) += int_incr * direction;
313
314
315 if ((mi->type & MENUITEM_F_UNSIGNED) || (mi->type & MENUITEM_SD_INT))
316 {
317 if (*(mi->value) < 0)
318 *(mi->value) = 0;
319
320 if ( mi->type & MENUITEM_F_MIN)
321 {
322 if (*(mi->value) < MENU_MIN_UNSIGNED(mi->arg))
323 *(mi->value) = MENU_MIN_UNSIGNED(mi->arg);
324 }
325 }
326 else
327 {
328 if (*(mi->value) < -9999)
329 *(mi->value) = -9999;
330
331 if ( mi->type & MENUITEM_F_MIN)
332 {
333 if (*(mi->value) < MENU_MIN_SIGNED(mi->arg))
334 *(mi->value) = MENU_MIN_SIGNED(mi->arg);
335 }
336 }
337
338 int maxval = (mi->type & MENUITEM_SD_INT) ? 9999999 : 99999;
339 if (*(mi->value) > maxval)
340 *(mi->value) = maxval;
341
342 if (mi->type & MENUITEM_F_UNSIGNED)
343 {
344 if ( mi->type & MENUITEM_F_MAX)
345 {
346 if (*(mi->value) > MENU_MAX_UNSIGNED(mi->arg))
347 *(mi->value) = MENU_MAX_UNSIGNED(mi->arg);
348 }
349 }
350 else
351 {
352 if (mi->type & MENUITEM_F_MAX)
353 {
354 if (*(mi->value) > MENU_MAX_SIGNED(mi->arg))
355 *(mi->value) = MENU_MAX_SIGNED(mi->arg);
356 }
357 }
358
359
360 do_callback(mi);
361
362
363 gui_menu_redraw=1;
364 }
365
366
367 static void update_bool_value(const CMenuItem *mi)
368 {
369
370 *(mi->value) = !(*(mi->value));
371
372
373 do_callback(mi);
374
375
376 gui_menu_redraw=1;
377 }
378
379
380 static void update_enum_value(const CMenuItem *mi, int direction)
381 {
382
383 if (mi->value)
384 {
385 if (mi->type & (MENUITEM_DECIMAL | MENUITEM_SD_INT | MENUITEM_HHMMSS))
386 direction *= int_incr;
387 if ((mi->type & MENUITEM_MASK) == MENUITEM_ENUM)
388 {
389 ((const char* (*)(int change, int arg))(mi->value))(direction, mi->arg);
390 }
391 else
392 {
393 extern const char* gui_change_enum2(const CMenuItem *menu_item, int change);
394 gui_change_enum2(mi, direction);
395 }
396 }
397
398
399 gui_menu_redraw=1;
400 }
401
402 static int isText(int n)
403 {
404 return (
405 (curr_menu->menu[n].type & MENUITEM_MASK) == MENUITEM_TEXT ||
406 (curr_menu->menu[n].type & MENUITEM_MASK) == MENUITEM_ERROR ||
407 (curr_menu->menu[n].type & MENUITEM_MASK) == MENUITEM_WARNING ||
408 (curr_menu->menu[n].type & MENUITEM_MASK) == MENUITEM_SEPARATOR
409 );
410 }
411
412
413 void gui_activate_sub_menu(CMenu *sub_menu)
414 {
415
416 gui_menu_stack[gui_menu_stack_ptr].menu = curr_menu;
417 gui_menu_stack[gui_menu_stack_ptr].curpos = gui_menu_curr_item;
418 gui_menu_stack[gui_menu_stack_ptr].toppos = gui_menu_top_item;
419
420
421 if (conf.menu_select_first_entry)
422 {
423 gui_menu_set_curr_menu(sub_menu, 0, 0);
424 if (isText(gui_menu_curr_item))
425 {
426
427 ++gui_menu_curr_item;
428 }
429 }
430 else
431 gui_menu_set_curr_menu(sub_menu, 0, -1);
432
433 gui_menu_stack_ptr++;
434
435
436 if (gui_menu_stack_ptr > MENUSTACK_MAXDEPTH)
437 {
438 draw_string(1, 0, "E1", MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
439 gui_menu_stack_ptr = 0;
440 }
441
442
443 extern void set_tv_override_menu(CMenu *menu);
444 set_tv_override_menu(curr_menu);
445
446
447 gui_menu_erase_and_redraw();
448 }
449
450
451 static void select_sub_menu()
452 {
453 gui_activate_sub_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value));
454 }
455
456
457 static void select_proc()
458 {
459 if (curr_menu->menu[gui_menu_curr_item].value)
460 {
461 ((void (*)(int arg))(curr_menu->menu[gui_menu_curr_item].value))(curr_menu->menu[gui_menu_curr_item].arg);
462
463 gui_menu_redraw=2;
464 }
465 }
466
467
468
469 static void gui_menu_updown(int increment)
470 {
471 int c, j;
472
473
474 if (camera_info.state.is_shutter_half_press || kbd_is_key_pressed(KEY_ZOOM_IN) || kbd_is_key_pressed(KEY_ZOOM_OUT)) c=4; else c=1;
475
476 for (j = 0; j < c; ++j)
477 {
478 do
479 {
480
481 gui_menu_curr_item += increment;
482
483 if (gui_menu_curr_item < 0)
484 {
485 gui_menu_curr_item = gui_menu_rows() - 1;
486 gui_menu_top_item = gui_menu_curr_item - num_lines + 1;
487 }
488 else if (gui_menu_curr_item >= gui_menu_rows())
489 {
490 gui_menu_curr_item = gui_menu_top_item = 0;
491 }
492 else if (increment == 1)
493 {
494 if (gui_menu_curr_item - gui_menu_top_item >= num_lines - 1)
495 {
496 gui_menu_top_item = gui_menu_curr_item - num_lines + 2;
497 if (gui_menu_top_item + num_lines > gui_menu_rows()) gui_menu_top_item = gui_menu_rows() - num_lines;
498 }
499 }
500 else
501 {
502 if (gui_menu_curr_item == gui_menu_top_item)
503 --gui_menu_top_item;
504 }
505
506
507 if (gui_menu_top_item < 0) gui_menu_top_item = 0;
508 } while (isText(gui_menu_curr_item));
509
510
511 int_incr = 1;
512 if (((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) == MENUITEM_STATE_VAL_PAIR) &&
513 (curr_menu->menu[gui_menu_curr_item].arg > 0))
514 int_incr = curr_menu->menu[gui_menu_curr_item].arg;
515
516
517 if (gui_menu_redraw == 0) gui_menu_redraw=1;
518 }
519 }
520
521 static int gui_menu_touch_handler(int tx, int ty)
522 {
523 int h = ((count > num_lines) ? num_lines : count) * rbf_font_height();
524 if ((tx >= x) && (ty >= y) && (tx < (x + w)) && (ty < (y + h)))
525 {
526 int r = ((ty - y) / rbf_font_height()) + gui_menu_top_item;
527 if (!isText(r))
528 {
529 if (gui_menu_curr_item != r)
530 {
531 gui_menu_curr_item = r;
532
533 if (gui_menu_redraw == 0) gui_menu_redraw = 1;
534 }
535 return KEY_SET;
536 }
537 }
538 return 0;
539 }
540
541
542
543 int gui_menu_kbd_process() {
544
545 switch (kbd_get_autoclicked_key() | get_jogdial_direction())
546 {
547 case KEY_ERASE:
548 case KEY_SHOOT_HALF:
549 if (!increment_factor())
550 int_incr = 1;
551 gui_menu_redraw=1;
552 break;
553 case JOGDIAL_LEFT:
554 case KEY_UP:
555 gui_menu_updown(-1);
556 break;
557 case JOGDIAL_RIGHT:
558 case KEY_DOWN:
559 gui_menu_updown(1);
560 break;
561 case FRONTDIAL_LEFT:
562 case KEY_LEFT:
563 if (gui_menu_curr_item >= 0) {
564 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) {
565 case MENUITEM_INT:
566 update_int_value(&curr_menu->menu[gui_menu_curr_item],-1);
567 break;
568 case MENUITEM_BOOL:
569 update_bool_value(&curr_menu->menu[gui_menu_curr_item]);
570 break;
571 case MENUITEM_ENUM:
572 case MENUITEM_ENUM2:
573 update_enum_value(&curr_menu->menu[gui_menu_curr_item],-1);
574 break;
575 case MENUITEM_UP:
576 gui_menu_back();
577 break;
578 case MENUITEM_STATE_VAL_PAIR:
579 {
580 CMenuItem *c = (CMenuItem*)(curr_menu->menu[gui_menu_curr_item].value);
581 if (*(c[1].value) == 0)
582 update_bool_value(&c[1]);
583 switch (c[0].type & MENUITEM_MASK)
584 {
585 case MENUITEM_INT:
586 update_int_value(&c[0],-1);
587 break;
588 case MENUITEM_ENUM:
589 case MENUITEM_ENUM2:
590 update_enum_value(&c[0],-1);
591 break;
592 }
593 }
594 break;
595 }
596 } else {
597 gui_menu_back();
598 }
599 break;
600 case FRONTDIAL_RIGHT:
601 case KEY_RIGHT:
602 if (gui_menu_curr_item >= 0) {
603 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK){
604 case MENUITEM_INT:
605 update_int_value(&curr_menu->menu[gui_menu_curr_item],1);
606 break;
607 case MENUITEM_BOOL:
608 update_bool_value(&curr_menu->menu[gui_menu_curr_item]);
609 break;
610 case MENUITEM_ENUM:
611 case MENUITEM_ENUM2:
612 update_enum_value(&curr_menu->menu[gui_menu_curr_item],1);
613 break;
614 case MENUITEM_SUBMENU_PROC:
615 select_proc();
616 break;
617 case MENUITEM_SUBMENU:
618 select_sub_menu();
619 break;
620 case MENUITEM_STATE_VAL_PAIR:
621 {
622 CMenuItem *c = (CMenuItem*)(curr_menu->menu[gui_menu_curr_item].value);
623 if (*(c[1].value) == 0)
624 update_bool_value(&c[1]);
625 switch (c[0].type & MENUITEM_MASK)
626 {
627 case MENUITEM_INT:
628 update_int_value(&c[0],1);
629 break;
630 case MENUITEM_ENUM:
631 case MENUITEM_ENUM2:
632 update_enum_value(&c[0],1);
633 break;
634 }
635 }
636 break;
637 }
638 }
639 break;
640 case KEY_SET:
641 if (gui_menu_curr_item >= 0) {
642 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK){
643 case MENUITEM_INT:
644 if (camera_info.state.is_shutter_half_press)
645 {
646 *(curr_menu->menu[gui_menu_curr_item].value) = 0;
647 gui_menu_redraw=1;
648 }
649 break;
650 case MENUITEM_BOOL:
651 update_bool_value(&curr_menu->menu[gui_menu_curr_item]);
652 break;
653 case MENUITEM_SUBMENU_PROC:
654 case MENUITEM_PROC:
655 select_proc();
656 break;
657 case MENUITEM_SUBMENU:
658 select_sub_menu();
659 break;
660 case MENUITEM_UP:
661 gui_menu_back();
662 break;
663 case MENUITEM_COLOR_FG:
664 item_color = (confColor*)(curr_menu->menu[gui_menu_curr_item].value);
665 item_color_type = MENUITEM_COLOR_FG;
666 libpalette->show_palette(PALETTE_MODE_SELECT, item_color->fg, gui_menu_color_selected);
667 gui_menu_redraw=2;
668 break;
669 case MENUITEM_COLOR_BG:
670 item_color = (confColor*)(curr_menu->menu[gui_menu_curr_item].value);
671 item_color_type = MENUITEM_COLOR_BG;
672 libpalette->show_palette(PALETTE_MODE_SELECT, item_color->bg, gui_menu_color_selected);
673 gui_menu_redraw=2;
674 break;
675 case MENUITEM_ENUM:
676 case MENUITEM_ENUM2:
677 update_enum_value(&curr_menu->menu[gui_menu_curr_item],1);
678 gui_menu_redraw=1;
679 break;
680 case MENUITEM_STATE_VAL_PAIR:
681 {
682 CMenuItem *c = (CMenuItem*)(curr_menu->menu[gui_menu_curr_item].value);
683 if ((c[1].type & MENUITEM_MASK) == MENUITEM_ENUM)
684 update_enum_value(&c[1],1);
685 else
686 update_bool_value(&c[1]);
687 }
688 break;
689 }
690 }
691 break;
692 case KEY_SHOOT_FULL:
693 if( (gui_menu_curr_item >= 0)
694 && ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) == MENUITEM_PROC)
695 && (curr_menu->menu[gui_menu_curr_item].value == (int *)gui_load_user_menu_script ))
696 select_proc();
697 break;
698 case KEY_ZOOM_IN:
699 if (decrement_factor())
700 gui_menu_redraw = 1;
701 break;
702
703 case KEY_ZOOM_OUT:
704 if (increment_factor())
705 gui_menu_redraw = 1;
706 break;
707
708 case KEY_DISPLAY:
709 if (camera_info.cam_has_zoom_lever)
710 {
711 gui_menu_back();
712 }
713 else
714 {
715
716 if (!increment_factor())
717 int_incr = 1;
718 gui_menu_redraw=1;
719 }
720 break;
721 }
722
723 return 0;
724 }
725
726
727
728 void gui_menu_draw_initial()
729 {
730 count = gui_menu_rows();
731
732
733 num_lines = (camera_screen.height - camera_screen.ts_menu_border*2)/rbf_font_height()-1;
734 y = (camera_screen.height - ((num_lines - 1) * rbf_font_height())) >> 1;
735 x = camera_screen.disp_left + camera_screen.menu_border_width;
736 w = camera_screen.disp_width - camera_screen.menu_border_width*2;
737
738
739 if ((count - gui_menu_top_item) < num_lines) {
740
741 gui_menu_top_item = count - num_lines;
742 if (gui_menu_top_item < 0) gui_menu_top_item = 0;
743 }
744 if ((gui_menu_curr_item - gui_menu_top_item + 1) > num_lines) {
745
746 gui_menu_top_item = gui_menu_curr_item - num_lines + 1;
747 }
748
749 if (count > num_lines)
750 {
751 wplus = 8;
752
753 draw_rectangle((x+w), y, (x+w)+wplus, y+num_lines*rbf_font_height()-1, MAKE_COLOR(BG_COLOR(user_color(conf.menu_color)), BG_COLOR(user_color(conf.menu_color))), RECT_BORDER0|DRAW_FILLED);
754 }
755 else
756 {
757 wplus = 0;
758 if (conf.menu_center)
759 {
760 y = (camera_screen.height - ((count - 1) * rbf_font_height())) >> 1;
761 }
762 }
763
764 rbf_draw_menu_header(x, y-rbf_font_height(), w+wplus, (conf.menu_symbol_enable)?curr_menu->symbol:0, lang_str(curr_menu->title), user_color(conf.menu_title_color));
765 }
766
767
768
769
770 static int imenu, yy, xx, symbol_width;
771 static twoColors cl, cl_symbol;
772
773
774 static void gui_menu_draw_symbol(int num_symbols)
775 {
776 if (conf.menu_symbol_enable)
777 {
778 xx += rbf_draw_char(xx, yy, ' ', cl_symbol);
779 xx += symbol_width = rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
780 symbol_width = (symbol_width * num_symbols) + len_space;
781 }
782 else
783 {
784 symbol_width = 0;
785 }
786
787 xx += rbf_draw_char(xx, yy, ' ', cl);
788 }
789
790 static void gui_set_int_cursor(int offset)
791 {
792 if (gui_menu_curr_item==imenu)
793 {
794 int n = int_incr;
795 while (n > 1)
796 {
797 n /= 10;
798 offset--;
799 }
800 rbf_enable_cursor(offset,offset);
801 }
802 }
803
804
805 static void gui_menu_draw_value(const char *str, int len_str)
806 {
807 gui_menu_draw_symbol(1);
808 xx += rbf_draw_string_len(xx, yy, w-len_space-len_space-len_br1-len_str-len_br2-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
809 xx += rbf_draw_string(xx, yy, " [", cl);
810 if (gui_menu_curr_item==imenu)
811 {
812 if (len_str == len_int)
813 gui_set_int_cursor(4);
814 else if (curr_menu->menu[imenu].type & MENUITEM_SD_INT)
815 gui_set_int_cursor(6);
816 else
817 rbf_enable_cursor(0,6);
818 }
819 xx += rbf_draw_string_right_len(xx, yy, len_str, str, cl);
820 rbf_disable_cursor();
821 rbf_draw_string(xx, yy, "] ", cl);
822 }
823
824
825 static void gui_menu_draw_text(char *str, int num_symbols)
826 {
827 gui_menu_draw_symbol(num_symbols);
828 xx += rbf_draw_string_len(xx, yy, w-len_space-len_space-symbol_width, str, cl);
829 if ((num_symbols == 2) && conf.menu_symbol_enable)
830 xx += rbf_draw_symbol(xx, yy, 0x52, cl_symbol);
831 rbf_draw_char(xx, yy, ' ', cl);
832 }
833
834
835 static int factor_disp_len()
836 {
837 int l = 0;
838 if (gui_menu_curr_item==imenu)
839 {
840 l = -1;
841 int n = int_incr;
842 while (n > 0)
843 {
844 l++;
845 n /= 10;
846 }
847 }
848 return l;
849 }
850
851 static char tbuf[64];
852
853
854
855 static void get_int_disp_string(int value, int dlen)
856 {
857 if (dlen == 6)
858 sprintf(tbuf, "%7d", value);
859 else
860 sprintf(tbuf, "%5d", value);
861 if (value < 0)
862 {
863 int spos, cpos;
864 for (spos=0; spos<5; spos++) if (tbuf[spos] == '-') break;
865 cpos = dlen - factor_disp_len();
866 if ((cpos > 0) && (cpos <= spos))
867 {
868 tbuf[spos] = ' ';
869 tbuf[cpos-1] = '-';
870 }
871 }
872 }
873
874
875 static void gui_menu_draw_state_value(CMenuItem *c)
876 {
877 const char *ch = "";
878
879 int text = curr_menu->menu[imenu].text;
880 if (c[0].text != 0)
881 text = c[0].text;
882
883 int wid = w-len_space-len_space-len_br1-len_enum-len_br2-len_space-symbol_width-len_br1-len_br2;
884 if ((c[1].type & MENUITEM_MASK) == MENUITEM_ENUM)
885 wid -= len_space*3;
886 else
887 wid -= len_bool;
888
889 gui_menu_draw_symbol(1);
890 xx += rbf_draw_string_len(xx, yy, wid, lang_str(text), cl);
891 xx += rbf_draw_string(xx, yy, " [", cl);
892 if ((c[1].type & MENUITEM_MASK) == MENUITEM_ENUM)
893 xx += rbf_draw_string_len(xx, yy, len_space*3, ((const char* (*)(int change, int arg))(c[1].value))(0, c[1].arg), cl);
894 else
895 xx += rbf_draw_string_len(xx, yy, len_bool, (*(c[1].value))?"\x95":"", cl);
896 xx += rbf_draw_string(xx, yy, "][", cl);
897
898 switch (c[0].type & MENUITEM_MASK)
899 {
900 case MENUITEM_INT:
901 get_int_disp_string(*(c[0].value), (c[0].type & MENUITEM_SD_INT)?6:4);
902 gui_set_int_cursor((c[0].type & MENUITEM_SD_INT)?6:4);
903 ch = tbuf;
904 break;
905 case MENUITEM_ENUM:
906 if (c[0].value)
907 ch = ((const char* (*)(int change, int arg))(c[0].value))(0, c[0].arg);
908 if ((c[0].type & MENUITEM_HHMMSS) && (gui_menu_curr_item==imenu))
909 {
910 switch (int_incr)
911 {
912 case 1:
913 rbf_enable_cursor(5,6);
914 break;
915 case 10:
916 rbf_enable_cursor(2,3);
917 break;
918 default:
919 rbf_enable_cursor(0,0);
920 break;
921 }
922 }
923 else if (c[0].type & MENUITEM_DECIMAL)
924 {
925 if (int_incr == 100000)
926 rbf_enable_cursor(0,0);
927 else
928 gui_set_int_cursor(6);
929 }
930 else if (c[0].type & MENUITEM_SD_INT)
931 {
932 if (isdigit(ch[strlen(ch)-1]))
933 gui_set_int_cursor(6);
934 }
935 else if (gui_menu_curr_item==imenu)
936 {
937 rbf_enable_cursor(0,6);
938 }
939 break;
940 case MENUITEM_ENUM2:
941 if (c[0].value)
942 {
943 extern const char* gui_change_enum2(const CMenuItem *menu_item, int change);
944 ch = gui_change_enum2(c, 0);
945 if (gui_menu_curr_item==imenu)
946 rbf_enable_cursor(0,6);
947 }
948 break;
949 }
950
951 xx += rbf_draw_string_right_len(xx, yy, len_enum, ch, cl);
952 rbf_disable_cursor();
953 rbf_draw_string(xx, yy, "] ", cl);
954 }
955
956
957 static void menu_text(color c)
958 {
959 twoColors save = cl;
960 cl = MAKE_COLOR(BG_COLOR(cl), c);
961 gui_menu_draw_text(lang_str(curr_menu->menu[imenu].text),1);
962 cl = save;
963 }
964
965 void gui_menu_draw(int enforce_redraw)
966 {
967 int i, j;
968 const char *ch = "";
969
970 if ( enforce_redraw )
971 gui_menu_redraw = 2;
972
973 if (gui_menu_redraw)
974 {
975 if (gui_menu_redraw==2)
976 gui_menu_draw_initial();
977
978 gui_menu_redraw=0;
979
980 for (imenu=gui_menu_top_item, i=0, yy=y; curr_menu->menu[imenu].text && i<num_lines; ++imenu, ++i, yy+=rbf_font_height())
981 {
982 cl = user_color((gui_menu_curr_item==imenu) ? conf.menu_cursor_color : conf.menu_color);
983
984
985
986
987
988
989
990
991
992
993 cl_symbol = (gui_menu_curr_item==imenu) ? MAKE_COLOR(BG_COLOR(cl),FG_COLOR(user_color(conf.menu_symbol_color))) : user_color(conf.menu_symbol_color);
994
995 xx = x;
996
997 switch (curr_menu->menu[imenu].type & MENUITEM_MASK)
998 {
999 case MENUITEM_STATE_VAL_PAIR:
1000 gui_menu_draw_state_value((CMenuItem*)(curr_menu->menu[imenu].value));
1001 break;
1002 case MENUITEM_BOOL:
1003 gui_menu_draw_value((*(curr_menu->menu[imenu].value))?"\x95":" ", len_bool);
1004 break;
1005 case MENUITEM_INT:
1006 get_int_disp_string(*(curr_menu->menu[imenu].value), (curr_menu->menu[imenu].type & MENUITEM_SD_INT)?6:4);
1007 gui_menu_draw_value(tbuf, (curr_menu->menu[imenu].type & MENUITEM_SD_INT)?len_enum:len_int);
1008 break;
1009 case MENUITEM_SUBMENU_PROC:
1010 case MENUITEM_SUBMENU:
1011 sprintf(tbuf, "%s%s", lang_str(curr_menu->menu[imenu].text),(conf.menu_symbol_enable)?"":" ->");
1012 gui_menu_draw_text(tbuf,2);
1013 break;
1014 case MENUITEM_UP:
1015 sprintf(tbuf, "%s%s", (conf.menu_symbol_enable)?"":"<- ", lang_str(curr_menu->menu[imenu].text));
1016 gui_menu_draw_text(tbuf,1);
1017 break;
1018 case MENUITEM_ERROR:
1019 menu_text(COLOR_RED);
1020 break;
1021 case MENUITEM_WARNING:
1022 menu_text(COLOR_YELLOW_DK);
1023 break;
1024 case MENUITEM_PROC:
1025 case MENUITEM_TEXT:
1026 gui_menu_draw_text(lang_str(curr_menu->menu[imenu].text),1);
1027 break;
1028 case MENUITEM_SEPARATOR:
1029 rbf_draw_char(x, yy, ' ', cl);
1030
1031 if (lang_str(curr_menu->menu[imenu].text)[0])
1032 sprintf(tbuf," %s ",lang_str(curr_menu->menu[imenu].text));
1033 else
1034 tbuf[0] = 0;
1035
1036 j = rbf_str_width(tbuf);
1037 xx += ((w - j) >> 1);
1038
1039 if (xx > (x + len_space))
1040 {
1041 draw_rectangle(x+len_space, yy, xx-1, yy+rbf_font_height()/2-1, MAKE_COLOR(BG_COLOR(cl), BG_COLOR(cl)), RECT_BORDER0|DRAW_FILLED);
1042 draw_line(x+len_space, yy+rbf_font_height()/2, xx-1, yy+rbf_font_height()/2, FG_COLOR(cl));
1043 draw_rectangle(x+len_space, yy+rbf_font_height()/2+1, xx-1, yy+rbf_font_height()-1, MAKE_COLOR(BG_COLOR(cl), BG_COLOR(cl)), RECT_BORDER0|DRAW_FILLED);
1044 }
1045 else
1046 {
1047 xx = x;
1048 }
1049
1050 if (j) xx += rbf_draw_clipped_string(xx, yy, tbuf, cl, 0, w);
1051
1052 if (xx < (x+w-len_space))
1053 {
1054 draw_rectangle(xx, yy, x+w-len_space-1, yy+rbf_font_height()/2-1, MAKE_COLOR(BG_COLOR(cl), BG_COLOR(cl)), RECT_BORDER0|DRAW_FILLED);
1055 draw_line(xx, yy+rbf_font_height()/2, x+w-1-len_space, yy+rbf_font_height()/2, FG_COLOR(cl));
1056 draw_rectangle(xx, yy+rbf_font_height()/2+1, x+w-len_space-1, yy+rbf_font_height()-1, MAKE_COLOR(BG_COLOR(cl), BG_COLOR(cl)), RECT_BORDER0|DRAW_FILLED);
1057 }
1058
1059 rbf_draw_char(x+w-len_space, yy, ' ', cl);
1060 break;
1061 case MENUITEM_COLOR_FG:
1062 {
1063 gui_menu_draw_symbol(1);
1064 xx+=rbf_draw_string_len(xx, yy, w-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
1065 color mc = FG_COLOR(user_color(*((confColor*)curr_menu->menu[imenu].value)));
1066 draw_rectangle(x+w-1-cl_rect-2-len_space, yy+2, x+w-1-2-len_space, yy+rbf_font_height()-1-2, MAKE_COLOR(mc,mc), RECT_BORDER0|DRAW_FILLED|RECT_ROUND_CORNERS);
1067 }
1068 break;
1069 case MENUITEM_COLOR_BG:
1070 {
1071 gui_menu_draw_symbol(1);
1072 xx+=rbf_draw_string_len(xx, yy, w-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
1073 color mc = BG_COLOR(user_color(*((confColor*)curr_menu->menu[imenu].value)));
1074 draw_rectangle(x+w-1-cl_rect-2-len_space, yy+2, x+w-1-2-len_space, yy+rbf_font_height()-1-2, MAKE_COLOR(mc,mc), RECT_BORDER0|DRAW_FILLED|RECT_ROUND_CORNERS);
1075 }
1076 break;
1077 case MENUITEM_ENUM:
1078 if (curr_menu->menu[imenu].value)
1079 ch = ((const char* (*)(int change, int arg))(curr_menu->menu[imenu].value))(0, curr_menu->menu[imenu].arg);
1080 gui_menu_draw_value(ch, len_enum);
1081 break;
1082 case MENUITEM_ENUM2:
1083 if (curr_menu->menu[imenu].value)
1084 {
1085 extern const char* gui_change_enum2(const CMenuItem *menu_item, int change);
1086 ch = gui_change_enum2(&curr_menu->menu[imenu], 0);
1087 }
1088 gui_menu_draw_value(ch, len_enum);
1089 break;
1090 }
1091 }
1092
1093
1094 if (count > num_lines)
1095 {
1096 i = num_lines*rbf_font_height()-1 -1;
1097 j = i*num_lines/count;
1098 if (j<20) j=20;
1099 i = (i-j)*((gui_menu_curr_item<0)?0:gui_menu_curr_item)/(count-1);
1100 draw_rectangle((x+w)+2, y+1, (x+w)+6, y+1+i, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED|RECT_ROUND_CORNERS);
1101 draw_rectangle((x+w)+2, y+i+j, (x+w)+6, y+num_lines*rbf_font_height()-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED|RECT_ROUND_CORNERS);
1102 draw_rectangle((x+w)+2, y+1+i, (x+w)+6, y+i+j, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE), RECT_BORDER0|DRAW_FILLED|RECT_ROUND_CORNERS);
1103 }
1104 }
1105 }
1106
1107
1108
1109 void gui_menu_kbd_process_menu_btn()
1110 {
1111 extern int gui_user_menu_flag;
1112
1113 conf_save();
1114
1115 if ( gui_user_menu_flag )
1116 {
1117 gui_set_mode(&menuGuiHandler);
1118 gui_user_menu_flag = 0;
1119 gui_menu_init(&root_menu);
1120 }
1121 else
1122 gui_set_mode(&altGuiHandler);
1123 }
1124
1125
1126
1127 gui_handler menuGuiHandler = { GUI_MODE_MENU, gui_menu_draw, gui_menu_kbd_process, gui_menu_kbd_process_menu_btn, gui_menu_touch_handler, 0 };
1128