root/modules/user_menu_edit.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. validrow
  2. gui_menu_disp_rows
  3. gui_menu_rows
  4. gui_menu_erase_and_redraw
  5. inUserMenu
  6. add_usermenu_item
  7. add_usermenu
  8. del_usermenu_item
  9. del_usermenu
  10. move_usermenu_item
  11. move_usermenu_item_up
  12. move_usermenu_item_down
  13. add_extern_to_user_menu
  14. add_script_to_user_menu
  15. add_module_to_user_menu
  16. gui_menu_set_curr_menu
  17. gui_init
  18. gui_menu_back
  19. gui_activate_sub_menu
  20. select_sub_menu
  21. gui_menu_updown
  22. gui_draw_initial
  23. gui_draw_symbol
  24. gui_draw_value
  25. gui_draw_text
  26. gui_draw_state_value
  27. gui_draw
  28. gui_uedit_kbd_process_menu_btn
  29. skip_whitespace
  30. skip_toeol
  31. skip_eol
  32. chk_ext
  33. gui_uedit_script_selected
  34. gui_uedit_module_selected
  35. uedit_set
  36. gui_uedit_kbd_process
  37. _run
  38. _module_can_unload
  39. _module_exit_alt
  40. _module_unload

   1 #include "camera_info.h"
   2 #include "stdlib.h"
   3 #include "conf.h"
   4 #include "keyboard.h"
   5 #include "font.h"
   6 #include "lang.h"
   7 #include "fileutil.h"
   8 #include "gui.h"
   9 #include "gui_draw.h"
  10 #include "gui_menu.h"
  11 #include "gui_user_menu.h"
  12 #include "gui_lang.h"
  13 #include "gui_mbox.h"
  14 #include "gui_mpopup.h"
  15 #include "gui_fselect.h"
  16 
  17 #include "module_load.h"
  18 #include "module_def.h"
  19 
  20 //-------------------------------------------------------------------
  21 #define MENUSTACK_MAXDEPTH  4
  22 
  23 //-------------------------------------------------------------------
  24 typedef struct {
  25     CMenu       *menu;
  26     int         curpos;
  27     int         toppos;
  28 } CMenuStacked;
  29 
  30 //-------------------------------------------------------------------
  31 
  32 static CMenu        *curr_menu;
  33 static CMenuStacked gui_menu_stack[MENUSTACK_MAXDEPTH];
  34 static unsigned int gui_menu_stack_ptr;
  35 static int          gui_menu_curr_item;
  36 static int          gui_menu_top_item;
  37 static int          gui_menu_redraw;
  38 
  39 static int          count;
  40 static int          x, y;
  41 static int          w, wplus, num_lines;
  42 static int          len_bool, len_space;
  43 
  44 static int running = 0;
  45 static gui_handler *gui_mode_old; // stored previous gui_mode
  46 
  47 //-------------------------------------------------------------------
  48 static int validrow(int n)
  49 {
  50     if (((curr_menu->menu[n].type & MENUITEM_MASK) != MENUITEM_SEPARATOR) &&
  51         ((curr_menu->menu[n].type & MENUITEM_SCRIPT_PARAM) != MENUITEM_SCRIPT_PARAM) &&
  52         ((curr_menu->menu[n].type & MENUITEM_TEXT) != MENUITEM_TEXT) &&
  53         (curr_menu->menu[n].text != LANG_MENU_USER_MENU) &&
  54         (curr_menu->menu[n].text != LANG_MENU_MAIN_TITLE))
  55         return 1;
  56     return 0;
  57 }
  58 
  59 static int gui_menu_disp_rows()
  60 {
  61     int n, m;
  62     // Count the numer of rows in current menu
  63     for(n = 0, m = 0; curr_menu->menu[n].text; n++)
  64         if (validrow(n)) m++;
  65     return m;
  66 }
  67 
  68 static int gui_menu_rows()
  69 {
  70     int n;
  71     // Count the numer of rows in current menu
  72     for(n = 0; curr_menu->menu[n].text; n++);
  73     return n;
  74 }
  75 
  76 //-------------------------------------------------------------------
  77 // Full screen erase and redraw of menu
  78 void gui_menu_erase_and_redraw()
  79 {
  80     gui_menu_redraw = 2;
  81     gui_set_need_restore();
  82 }
  83 
  84 //-------------------------------------------------------------------
  85 static int inUserMenu(int n)
  86 {
  87     int i;
  88     for (i=1; user_submenu.menu[i].text != 0; i++)
  89     {
  90         if (user_submenu.menu[i].text == curr_menu->menu[n].text)
  91             return 1;
  92     }
  93     return 0;
  94 }
  95 
  96 //-------------------------------------------------------------------
  97 static CMenuItem mod_menu_item;
  98 static char msgbuf[200];
  99 
 100 void add_usermenu_item(unsigned int btn)
 101 {
 102     gui_menu_erase_and_redraw();
 103     if (btn == MBOX_BTN_YES)
 104     {
 105         int i;
 106 
 107         /*
 108          * Insert new Item at end of existing entries
 109          */
 110         CMenuItem *items = (CMenuItem*)user_submenu.menu;
 111 
 112         for (i = 1; i < USER_MENU_ITEMS + 1; i++)
 113         {
 114             if (!items[i].text)
 115             {
 116                 items[i] = mod_menu_item;
 117                 camera_info.state.user_menu_has_changed = 1;
 118                 return;
 119             }
 120         }
 121         gui_mbox_init(LANG_MENU_USER_MENU, LANG_USER_MENU_FULL, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
 122     }
 123 }
 124 
 125 static void add_usermenu()
 126 {
 127     if (!inUserMenu(gui_menu_curr_item) && (curr_menu->menu[gui_menu_curr_item].text != LANG_MENU_BACK))
 128     {
 129         mod_menu_item = curr_menu->menu[gui_menu_curr_item];
 130         sprintf(msgbuf, lang_str(LANG_USER_MENU_ADD), lang_str(mod_menu_item.text));
 131         gui_mbox_init(LANG_INFORMATION, (int)msgbuf, MBOX_BTN_YES_NO|MBOX_DEF_BTN1|MBOX_TEXT_CENTER, add_usermenu_item);
 132     }
 133 }
 134 
 135 static void del_usermenu_item(unsigned int btn)
 136 {
 137     gui_menu_erase_and_redraw();
 138     if (btn == MBOX_BTN_YES)
 139     {
 140         int i, c;
 141 
 142         /*
 143          * Delete user menu entry by sliding all the lower valid/existing entries up.
 144          */
 145         CMenuItem *items = (CMenuItem*)user_submenu.menu;
 146 
 147         for (c = 1; c < USER_MENU_ITEMS + 1; c++)
 148         {
 149             if (items[c].text == mod_menu_item.text)
 150             {
 151                 for (i = c; items[i].text; i++)
 152                 {
 153                     items[i] = items[i+1];
 154 
 155                     if (conf.user_menu_vars.items[i-1].script_file)
 156                         free(conf.user_menu_vars.items[i-1].script_file);
 157                     conf.user_menu_vars.items[i-1].script_file = conf.user_menu_vars.items[i].script_file;
 158                     conf.user_menu_vars.items[i].script_file = 0;
 159 
 160                     if (conf.user_menu_vars.items[i-1].script_title)
 161                         free(conf.user_menu_vars.items[i-1].script_title);
 162                     conf.user_menu_vars.items[i-1].script_title = conf.user_menu_vars.items[i].script_title;
 163                     conf.user_menu_vars.items[i].script_title = 0;
 164                 }
 165 
 166                 camera_info.state.user_menu_has_changed = 1;
 167 
 168                 if (curr_menu->title == LANG_MENU_USER_MENU)
 169                 {
 170                     if (gui_menu_curr_item >= gui_menu_rows())
 171                         gui_menu_curr_item--;
 172                 }
 173 
 174                 return;
 175             }
 176         }
 177     }
 178 }
 179 
 180 static void del_usermenu()
 181 {
 182     if (inUserMenu(gui_menu_curr_item))
 183     {
 184         mod_menu_item = curr_menu->menu[gui_menu_curr_item];
 185         sprintf(msgbuf, lang_str(LANG_USER_MENU_DEL), lang_str(mod_menu_item.text));
 186         gui_mbox_init(LANG_INFORMATION, (int)msgbuf, MBOX_BTN_YES_NO|MBOX_DEF_BTN1|MBOX_TEXT_CENTER, del_usermenu_item);
 187     }
 188 }
 189 
 190 static void move_usermenu_item(int* cur_menu_item_indx, int dir)
 191 {
 192     int src_index, dst_index ;
 193     char *tbuff;
 194 
 195     src_index = *cur_menu_item_indx ;
 196     dst_index = *cur_menu_item_indx + dir;    
 197         
 198     // Move current user menu item up (dir = -1) or down (dir = 1)
 199     CMenuItem *items = (CMenuItem*)user_submenu.menu;
 200         
 201     CMenuItem tmp_menu_item = items[dst_index];
 202     items[dst_index] = items[src_index];
 203     items[src_index] = tmp_menu_item;
 204     
 205     src_index--; dst_index--;
 206    
 207     tbuff = conf.user_menu_vars.items[dst_index].script_file;
 208     conf.user_menu_vars.items[dst_index].script_file = conf.user_menu_vars.items[src_index].script_file;    
 209     conf.user_menu_vars.items[src_index].script_file = tbuff;
 210             
 211     tbuff = conf.user_menu_vars.items[dst_index].script_title;
 212     conf.user_menu_vars.items[dst_index].script_title = conf.user_menu_vars.items[src_index].script_title;    
 213     conf.user_menu_vars.items[src_index].script_title = tbuff;
 214         
 215     *cur_menu_item_indx += dir;
 216 
 217     gui_menu_erase_and_redraw();
 218     camera_info.state.user_menu_has_changed = 1;
 219 }
 220 
 221 static void move_usermenu_item_up(int* cur_menu_item_indx)
 222 {
 223     /*
 224      * Move entry up
 225      */
 226     if (*cur_menu_item_indx > 1)
 227         move_usermenu_item(cur_menu_item_indx, -1);
 228 }
 229 
 230 static void move_usermenu_item_down(int* cur_menu_item_indx)
 231 {
 232     // don't allow moving link to main menu
 233     if (*cur_menu_item_indx == 0)
 234         return;
 235 
 236     /*
 237      * Move entry down below next entry if next entry is not empty
 238      */
 239     if((*cur_menu_item_indx < (USER_MENU_ITEMS)) && (user_submenu.menu[*cur_menu_item_indx +1].text))
 240         move_usermenu_item(cur_menu_item_indx, 1);
 241 }
 242 
 243 static void add_extern_to_user_menu(const char* fname, char* title, char sym, short type, int* func)
 244 {
 245     int i;
 246     /*
 247      * Insert script/module info at end of existing entries
 248      */
 249     CMenuItem *items = (CMenuItem*)user_submenu.menu;
 250     gui_menu_erase_and_redraw();
 251 
 252     for(i = 1; i < USER_MENU_ITEMS + 1; i++)
 253     {
 254         if (!items[i].text)   // insert script/module title & full filename in next available spot 
 255         {
 256             if (conf.user_menu_vars.items[i-1].script_file == 0)
 257                 conf.user_menu_vars.items[i-1].script_file = malloc(CONF_STR_LEN);
 258             strcpy(conf.user_menu_vars.items[i-1].script_file, fname);
 259             if (conf.user_menu_vars.items[i-1].script_title == 0)
 260                 conf.user_menu_vars.items[i-1].script_title = malloc(CONF_STR_LEN);
 261             strcpy(conf.user_menu_vars.items[i-1].script_title, title);
 262 
 263             items[i].symbol = sym;
 264             items[i].opt_len = 0;
 265             items[i].type = type;
 266             items[i].text = (int) conf.user_menu_vars.items[i-1].script_title;
 267             items[i].value = func;
 268             items[i].arg = (int) conf.user_menu_vars.items[i-1].script_file;
 269             
 270             sprintf(msgbuf,lang_str(LANG_USER_MENU_ITEM_ADDED), lang_str(items[i].text));
 271             gui_mbox_init(LANG_MENU_USER_MENU, (int)msgbuf, MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, NULL);
 272             camera_info.state.user_menu_has_changed = 1;
 273             return;
 274         }
 275     }
 276     gui_mbox_init(LANG_MENU_USER_MENU, LANG_USER_MENU_FULL, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
 277 }
 278 
 279 static void add_script_to_user_menu(const char* fname, char* title)
 280 {
 281     add_extern_to_user_menu(fname, title, 0x35, MENUITEM_PROC, (int*)gui_load_user_menu_script);
 282 }
 283 
 284 static void add_module_to_user_menu(const char* fname, char* title)
 285 {
 286     add_extern_to_user_menu(fname, title, 0x28, MENUITEM_PROC|MENUITEM_USER_MODULE, (int*)module_run);
 287 }
 288 
 289 //-------------------------------------------------------------------
 290 static void gui_menu_set_curr_menu(CMenu *menu_ptr, int top_item, int curr_item)
 291 {
 292     curr_menu = menu_ptr;
 293     gui_menu_top_item = top_item;
 294     gui_menu_curr_item = curr_item;
 295     while (!validrow(gui_menu_curr_item))
 296     {
 297         ++gui_menu_curr_item;
 298     }
 299 }
 300 
 301 //-------------------------------------------------------------------
 302 static void gui_init(CMenu *menu_ptr) {
 303 
 304     if (menu_ptr) {
 305         gui_menu_set_curr_menu(menu_ptr, 0, 0);
 306         gui_menu_stack_ptr = 0;
 307     }
 308 
 309     num_lines = camera_screen.height/rbf_font_height()-1;
 310     x = camera_screen.disp_left + camera_screen.menu_border_width;
 311     w = camera_screen.disp_width - camera_screen.menu_border_width;
 312     len_bool = rbf_str_width("\x95");
 313     len_space = rbf_char_width(' ');
 314 
 315     gui_menu_redraw=2;
 316 }
 317 
 318 //-------------------------------------------------------------------
 319 // Return to previous menu on stack
 320 void gui_menu_back() {
 321     if (gui_menu_stack_ptr > 0)
 322     {
 323         gui_menu_stack_ptr--;
 324         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);
 325         gui_menu_erase_and_redraw();
 326     }
 327 }
 328 
 329 //-------------------------------------------------------------------
 330 // Helper functions for gui_uedit_kbd_process
 331 //  common code blocks extracted to try and make it easier to understand
 332 
 333 // Open a sub-menu
 334 void gui_activate_sub_menu(CMenu *sub_menu)
 335 {
 336     // push current menu on stack
 337     gui_menu_stack[gui_menu_stack_ptr].menu = curr_menu;
 338     gui_menu_stack[gui_menu_stack_ptr].curpos = gui_menu_curr_item;
 339     gui_menu_stack[gui_menu_stack_ptr].toppos = gui_menu_top_item;
 340 
 341     gui_menu_set_curr_menu(sub_menu, 0, 0);
 342 
 343     gui_menu_stack_ptr++;
 344 
 345     // FIXME check on stack overrun;
 346     if (gui_menu_stack_ptr > MENUSTACK_MAXDEPTH)
 347     {
 348         draw_string(1, 0, "E1", MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
 349         gui_menu_stack_ptr = 0;
 350     }
 351 
 352     // Force full redraw
 353     gui_menu_erase_and_redraw();
 354 }
 355 
 356 // Open a sub-menu
 357 static void select_sub_menu()
 358 {
 359     gui_activate_sub_menu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value));
 360 }
 361 
 362 // Move up / down in menu, adjusting scroll position if needed
 363 //   increment = -1 to move up, 1 to move down
 364 static void gui_menu_updown(int increment)
 365 {
 366     int c, j;
 367 
 368     if (count == 0) return;
 369 
 370     // Determine number of rows to move (1 or 4)
 371     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;
 372 
 373     for (j = 0; j < c; ++j)
 374     {
 375         do
 376         {
 377             // Move to next or previous row
 378             gui_menu_curr_item += increment;
 379 
 380             if (gui_menu_curr_item < 0)                                     // Off top, move to bottom
 381             {
 382                 gui_menu_curr_item = gui_menu_rows() - 1;
 383                 gui_menu_top_item = gui_menu_curr_item - num_lines + 1;
 384             }
 385             else if (gui_menu_curr_item >= gui_menu_rows())                 // Off bottom, move to top
 386             {
 387                 gui_menu_curr_item = gui_menu_top_item = 0;
 388             }
 389             else if (increment == 1)                                        // Still in menu, if moving down adjust scroll if needed
 390             {
 391                 if (gui_menu_curr_item - gui_menu_top_item >= num_lines - 1)
 392                 {
 393                     gui_menu_top_item = gui_menu_curr_item - num_lines + 2;
 394                     if (gui_menu_top_item + num_lines > gui_menu_rows()) gui_menu_top_item = gui_menu_rows() - num_lines;
 395                 }
 396             }
 397             else                                                            // Still in menu, and moving up, adjust scroll
 398             {
 399                 if (gui_menu_curr_item == gui_menu_top_item) 
 400                     --gui_menu_top_item;
 401             }
 402 
 403             // Check in case scroll moved off top of menu
 404             if (gui_menu_top_item < 0) gui_menu_top_item = 0;
 405         } while (!validrow(gui_menu_curr_item));
 406 
 407         // Redraw menu if needed
 408         if (gui_menu_redraw == 0) gui_menu_redraw=1;
 409     }
 410 }
 411 
 412 //-------------------------------------------------------------------
 413 // Draw menu scroll bar if needed, and title bar
 414 static void gui_draw_initial()
 415 { 
 416     count = gui_menu_disp_rows();
 417 
 418     if (count > num_lines)
 419     {
 420         y = ((camera_screen.height-(num_lines-1)*rbf_font_height())>>1);
 421         wplus = 8; 
 422         // scrollbar background 
 423         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);
 424     }
 425     else
 426     {
 427         wplus = 0;
 428         if (conf.menu_center)
 429         {
 430             y = (camera_screen.height-(count-1)*rbf_font_height())>>1; 
 431         }
 432         else
 433         {
 434             y = ((camera_screen.height-(num_lines-1)*rbf_font_height())>>1);  
 435         }
 436     }
 437 
 438     rbf_draw_menu_header(x, y-rbf_font_height(), w+wplus, (conf.menu_symbol_enable)?curr_menu->symbol:0, lang_str(curr_menu->title), MAKE_COLOR(COLOR_RED,COLOR_WHITE));
 439 }
 440 
 441 //-------------------------------------------------------------------
 442 
 443 // Local variables used by menu draw functions
 444 static int imenu, yy, xx, symbol_width;
 445 static twoColors cl, cl_symbol;
 446 
 447 // Common code extracted from gui_draw for displaying the symbol on the left
 448 static void gui_draw_symbol(int num_symbols)
 449 {
 450     if (conf.menu_symbol_enable)
 451     {
 452         xx += rbf_draw_char(xx, yy, ' ', cl_symbol);
 453         xx += symbol_width = rbf_draw_symbol(xx, yy, curr_menu->menu[imenu].symbol, cl_symbol);
 454         symbol_width = (symbol_width * num_symbols) + len_space;
 455     }
 456     else
 457     {
 458         symbol_width = 0;
 459     }
 460 
 461     xx += rbf_draw_char(xx, yy, ' ', cl);
 462 }
 463 
 464 // Common code extracted from gui_draw for displaying an int, enum or bool value on the right
 465 static void gui_draw_value()
 466 {
 467     gui_draw_symbol(1);
 468     xx += rbf_draw_string_len(xx, yy, w-len_space*4, lang_str(curr_menu->menu[imenu].text), cl);
 469 }
 470 
 471 // Common code extracted from gui_draw for displaying a text menu string
 472 static void gui_draw_text(char *str, int num_symbols)
 473 {
 474     gui_draw_symbol(num_symbols);
 475     xx += rbf_draw_string_len(xx, yy, w-len_space-len_space-symbol_width, str, cl);
 476     if ((num_symbols == 2) && conf.menu_symbol_enable)
 477         xx += rbf_draw_symbol(xx, yy, 0x52, cl_symbol);
 478     rbf_draw_char(xx, yy, ' ', cl);
 479 }
 480 
 481 // Common code extracted from gui_draw for displaying an int or enum that can be enabled/disabled
 482 static void gui_draw_state_value(CMenuItem *c)
 483 {
 484     const char *ch = "";
 485 
 486     int text = curr_menu->menu[imenu].text;
 487     if (c[0].text != 0)
 488         text = c[0].text;
 489 
 490     int wid = w-len_space-len_space;
 491 
 492     gui_draw_symbol(1);
 493     xx += rbf_draw_string_len(xx, yy, wid, lang_str(text), cl);
 494 }
 495 
 496 //-------------------------------------------------------------------
 497 static void gui_draw(int enforce_redraw)
 498 {
 499     int i, j;
 500     const char *ch = "";
 501 
 502         if ( enforce_redraw )
 503                 gui_menu_redraw = 2;
 504 
 505     if (gui_menu_redraw)
 506     {
 507         if (gui_menu_redraw==2)
 508             gui_draw_initial();
 509 
 510         gui_menu_redraw=0;
 511 
 512         for (imenu=gui_menu_top_item, i=0, yy=y; curr_menu->menu[imenu].text && i<num_lines; ++imenu)
 513         {
 514             if (validrow(imenu))
 515             {
 516                 cl = user_color((gui_menu_curr_item==imenu) ? conf.menu_cursor_color : conf.menu_color);
 517                 if (inUserMenu(imenu) && (curr_menu->title != LANG_MENU_USER_MENU))
 518                     cl = MAKE_COLOR(BG_COLOR(cl),COLOR_GREEN);
 519                 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);
 520 
 521                 xx = x;
 522 
 523                 switch (curr_menu->menu[imenu].type & MENUITEM_MASK)
 524                 {
 525                 case MENUITEM_STATE_VAL_PAIR:
 526                     gui_draw_state_value((CMenuItem*)(curr_menu->menu[imenu].value));
 527                     break;
 528                 case MENUITEM_BOOL:
 529                 case MENUITEM_INT:
 530                 case MENUITEM_ENUM:
 531                 case MENUITEM_ENUM2:
 532                     gui_draw_value();
 533                     break;
 534                 case MENUITEM_SUBMENU_PROC:
 535                 case MENUITEM_SUBMENU:
 536                     sprintf(msgbuf, "%s%s", lang_str(curr_menu->menu[imenu].text),(conf.menu_symbol_enable)?"":" ->");
 537                     gui_draw_text(msgbuf,2);
 538                     break;
 539                 case MENUITEM_UP:
 540                     sprintf(msgbuf, "%s%s", (conf.menu_symbol_enable)?"":"<- ", lang_str(curr_menu->menu[imenu].text));
 541                     gui_draw_text(msgbuf,1);
 542                     break;
 543                 case MENUITEM_PROC:
 544                     gui_draw_text(lang_str(curr_menu->menu[imenu].text),1);
 545                     break;
 546                 case MENUITEM_COLOR_FG:
 547                 case MENUITEM_COLOR_BG:
 548                     gui_draw_symbol(1);
 549                     xx+=rbf_draw_string_len(xx, yy, w-len_space-symbol_width, lang_str(curr_menu->menu[imenu].text), cl);
 550                     break;
 551                 }
 552 
 553                 yy += rbf_font_height();
 554                 i++;
 555             }
 556         }
 557 
 558         // scrollbar
 559         if (count > num_lines)
 560         {
 561             i = num_lines*rbf_font_height()-1 -1;           // full height
 562             j = i*num_lines/count;                          // bar height
 563             if (j<20) j=20;
 564             i = (i-j)*((gui_menu_curr_item<0)?0:gui_menu_curr_item)/(count-1);   // top pos
 565             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);
 566             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);
 567             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);
 568         }
 569     }
 570 }
 571 
 572 //-------------------------------------------------------------------
 573 // Menu button handler for Menu mode
 574 static void gui_uedit_kbd_process_menu_btn()
 575 {
 576     if (curr_menu->title == LANG_MENU_USER_MENU)
 577     {
 578         running = 0;
 579         gui_set_mode(gui_mode_old);
 580     }
 581     else
 582     {
 583         gui_menu_erase_and_redraw();
 584         gui_init(&user_submenu);
 585     }
 586 }
 587 
 588 //-------------------------------------------------------------------
 589 #define UEDIT_MENU      1
 590 #define UEDIT_SCRIPT    2
 591 #define UEDIT_MODULE    4
 592 #define UEDIT_REMOVE    8
 593 
 594 static struct mpopup_item popup_uedit[]= {
 595         { UEDIT_MENU,           LANG_USER_MENU_ITEMS },
 596         { UEDIT_SCRIPT,         LANG_MENU_USER_MENU_SCRIPT_ADD },
 597         { UEDIT_MODULE,         LANG_MENU_USER_MENU_MODULE_ADD },
 598         { UEDIT_REMOVE,         LANG_MENU_USER_MENU_REMOVE },
 599         { 0,                    0 },
 600 };
 601 
 602 const char* skip_whitespace(const char* p)  { while (*p==' ' || *p=='\t') p++; return p; }                                  // Skip past whitespace
 603 const char* skip_toeol(const char* p)       { while (*p && *p!='\r' && *p!='\n') p++; return p; }                           // Skip to end of line
 604 const char* skip_eol(const char *p)         { p = skip_toeol(p); if (*p == '\r') p++; if (*p == '\n') p++; return p; }      // Skip past end of line
 605 
 606 static int chk_ext(char *ext, char *tst)
 607 {
 608     if (ext && (strlen(ext) == strlen(tst)+1))
 609     {
 610         int i;
 611         for (i=0; i<strlen(tst); i++)
 612             if (toupper(ext[i+1]) != toupper(tst[i]))
 613                 return 0;
 614         return 1;
 615     }
 616     return 0;
 617 }
 618 
 619 static void gui_uedit_script_selected(const char *fn)
 620 {
 621     if (fn)
 622     {
 623         char *ext = strrchr(fn,'.');
 624         if (chk_ext(ext,"lua") || chk_ext(ext,"bas"))
 625         {
 626             char* buf;
 627 
 628             buf = load_file(fn, 0, 1);
 629 
 630             if (buf)
 631             {
 632                 char script_title[36];
 633                 register const char *ptr = buf;
 634                 char *c;
 635 
 636                 // Build title
 637 
 638                 c=strrchr(fn, '/');
 639                 strncpy(script_title, (c)?c+1:fn, sizeof(script_title));
 640                 script_title[sizeof(script_title)-1]=0;
 641 
 642                 while (ptr[0])
 643                 {
 644                     ptr = skip_whitespace(ptr);
 645                     if (ptr[0]=='@') {
 646                         if (strncmp("@title", ptr, 6)==0)
 647                         {
 648                             ptr = ptr + 6;
 649                             register int i=0;
 650 
 651                             ptr = skip_whitespace(ptr);
 652                             while (i<(sizeof(script_title)-1) && ptr[i] && ptr[i]!='\r' && ptr[i]!='\n')
 653                             {
 654                                 script_title[i]=ptr[i];
 655                                 ++i;
 656                             }
 657                             script_title[i]=0;
 658                             break;
 659                         }
 660                     }
 661                     ptr = skip_eol(ptr);
 662                 }
 663 
 664                 add_script_to_user_menu(fn, script_title);
 665                 free(buf);
 666             }
 667         }
 668     }
 669 }
 670 
 671 static void gui_uedit_module_selected(const char *fn)
 672 {
 673     if (fn)
 674     {
 675         char *ext = strrchr(fn,'.');
 676         if (chk_ext(ext,"flt"))
 677         {
 678             _version_t v = ANY_VERSION;
 679             flat_hdr* mod = module_preload(fn, fn, v);  // Pass fn as both path and name (file browser sends us full path to module)
 680             if (mod > 0)
 681             {
 682                 if (mod->_module_info->lib->run != 0)   // Simple Module?
 683                 {
 684                     char *n;
 685                     if (mod->_module_info->moduleName < 0)
 686                         n = lang_str(-mod->_module_info->moduleName);
 687                     else
 688                         n = (char*)mod->_module_info->moduleName;
 689                     add_module_to_user_menu(fn, n);
 690                     free(mod);
 691                 }
 692                 else
 693                 {
 694                     sprintf(msgbuf, lang_str(LANG_MODULE_NOT_SIMPLE), fn);
 695                     gui_mbox_init(LANG_ERROR, (int)msgbuf, MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, NULL);
 696                 }
 697             }
 698         }
 699     }
 700 }
 701 
 702 static void uedit_set(unsigned int actn)
 703 {
 704     switch (actn)
 705     {
 706         case UEDIT_MENU:
 707             gui_init(&root_menu);
 708             break;
 709         case UEDIT_SCRIPT:
 710             libfselect->file_select(LANG_MENU_USER_MENU_SCRIPT_ADD, conf.script_file, "A/CHDK/SCRIPTS", gui_uedit_script_selected);
 711             break;
 712         case UEDIT_MODULE:
 713             libfselect->file_select(LANG_MENU_USER_MENU_MODULE_ADD, "A/CHDK/MODULES", "A/CHDK/MODULES", gui_uedit_module_selected);
 714             break;
 715         case UEDIT_REMOVE:
 716             del_usermenu();
 717             break;
 718     }
 719     gui_menu_erase_and_redraw();
 720 }
 721 
 722 // Process button presses when in GUI_MODE_MENU mode
 723 static int gui_uedit_kbd_process() {
 724 
 725     switch (kbd_get_autoclicked_key() | get_jogdial_direction())
 726     {
 727         case JOGDIAL_LEFT:
 728         case KEY_UP:
 729             gui_menu_updown(-1);
 730             break;
 731         case JOGDIAL_RIGHT:
 732         case KEY_DOWN: 
 733             gui_menu_updown(1);
 734             break;
 735         case FRONTDIAL_LEFT:
 736         case KEY_LEFT:
 737             if (curr_menu->title == LANG_MENU_USER_MENU)
 738             {
 739                 move_usermenu_item_up(&gui_menu_curr_item);
 740             }
 741             else
 742             {
 743                 del_usermenu();
 744             }
 745             break;
 746         case KEY_SHOOT_HALF:
 747         case KEY_ERASE:
 748             del_usermenu();
 749             break;
 750         case FRONTDIAL_RIGHT:
 751         case KEY_RIGHT:
 752             if (curr_menu->title == LANG_MENU_USER_MENU)
 753             {
 754                 move_usermenu_item_down(&gui_menu_curr_item);
 755             }
 756             else
 757             {
 758                 add_usermenu();
 759             }
 760             break;
 761         case KEY_SET:
 762             if (curr_menu->title == LANG_MENU_USER_MENU)
 763             {
 764                 libmpopup->show_popup( popup_uedit, UEDIT_MENU|UEDIT_SCRIPT|UEDIT_MODULE|UEDIT_REMOVE, uedit_set);
 765             }
 766             else
 767             {
 768                 switch (curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK)
 769                 {
 770                     case MENUITEM_UP:
 771                         gui_menu_back();
 772                         break;
 773                     case MENUITEM_SUBMENU:
 774                         select_sub_menu();
 775                         break;
 776                 }
 777             }
 778             break;
 779         case KEY_DISPLAY:
 780             gui_menu_back();
 781             break;
 782     }
 783 
 784     return 0;
 785 }
 786 
 787 //-------------------------------------------------------------------
 788 // GUI handler for menus
 789 static gui_handler ueditGuiHandler = { GUI_MODE_MODULE, gui_draw, gui_uedit_kbd_process, gui_uedit_kbd_process_menu_btn, 0, 0 };
 790 //-------------------------------------------------------------------
 791 
 792 
 793 // =========  MODULE INIT =================
 794 #include "simple_module.h"
 795 
 796 int _run()
 797 {
 798     running = 1;
 799     gui_menu_redraw = 2;
 800     gui_init(&user_submenu);
 801     gui_mode_old = gui_set_mode(&ueditGuiHandler);
 802 
 803     return 0;
 804 }
 805 
 806 int _module_can_unload()
 807 {
 808     return running == 0;
 809 }
 810 
 811 int _module_exit_alt()
 812 {
 813     running = 0;
 814     return 0;
 815 }
 816 
 817 int _module_unload()
 818 {
 819     conf_save();
 820     return 0;
 821 }
 822 
 823 libsimple_sym _librun =
 824 {
 825     {
 826         0,
 827         _module_unload,
 828         _module_can_unload,
 829         _module_exit_alt,
 830         _run
 831     }
 832 };
 833 
 834 /******************** Module Information structure ******************/
 835 
 836 ModuleInfo _module_info =
 837 {
 838     MODULEINFO_V1_MAGICNUM,
 839     sizeof(ModuleInfo),
 840     SIMPLE_MODULE_VERSION,              // Module version
 841 
 842     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,                       // Requirements of CHDK version
 843     ANY_PLATFORM_ALLOWED,               // Specify platform dependency
 844 
 845     -LANG_MENU_USER_MENU_EDIT,
 846     MTYPE_EXTENSION,
 847 
 848     &_librun.base,
 849 
 850     CONF_VERSION,               // CONF version
 851     CAM_SCREEN_VERSION,         // CAM SCREEN version
 852     ANY_VERSION,                // CAM SENSOR version
 853     ANY_VERSION,                // CAM INFO version
 854 };

/* [<][>][^][v][top][bottom][index][help] */