#include #include #include #include "plugin.h" #include "lib/display_text.h" PLUGIN_HEADER #define MAX_OUTPUT_WIDTH LCD_WIDTH #define MAX_OUTPUT_HEIGHT LCD_HEIGHT #define MAX_LINE_LEN 200 #define MAX_WORD_LEN 50 #define MAX_BOX_SIZE 500 #define NUMBER_OF_BOXES 3 #define CONFIG_FILE PLUGIN_APPS_DIR "/rockvoc.config" #define MAX_VOCFILES 100 #define GREEN LCD_RGBPACK(0,140,0) #define RED LCD_RGBPACK(230,10,10) #define DARKRED LCD_RGBPACK(160,0,0) #define BLACK LCD_RGBPACK(0,0,0) #define SOFTWHITE LCD_RGBPACK(255,255,240) #define BLUE LCD_RGBPACK(60,100,230) #define WHITE LCD_RGBPACK(255,255,255) #define AMBER LCD_RGBPACK(240,186,38) #define SLATEGRAY LCD_RGBPACK(46,70,80) #define LIGHTGRAY LCD_RGBPACK(211,211,211) #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD) || \ (CONFIG_KEYPAD == ARCHOS_AV300_PAD) #define ROCKVOC_QUIT BUTTON_OFF #define ROCKVOC_NEXT BUTTON_SELECT #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "SELECT" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define ROCKVOC_QUIT BUTTON_MENU #define ROCKVOC_NEXT BUTTON_SELECT #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "SELECT" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == RECORDER_PAD) #define ROCKVOC_QUIT BUTTON_MENU #define ROCKVOC_QUIT BUTTON_OFF #define ROCKVOC_NEXT BUTTON_PLAY #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "PLAY" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == ONDIO_PAD) #define ROCKVOC_QUIT BUTTON_OFF #define ROCKVOC_NEXT (BUTTON_MENU | BUTTON_REL) #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "MENU" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) || \ (CONFIG_KEYPAD == GIGABEAT_PAD) #define ROCKVOC_QUIT BUTTON_POWER #define ROCKVOC_NEXT BUTTON_SELECT #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "SELECT" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) #define ROCKVOC_QUIT (BUTTON_HOME|BUTTON_REPEAT) #define ROCKVOC_NEXT (BUTTON_SELECT|BUTTON_REL) #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "SELECT" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_C200_PAD) || \ (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ (CONFIG_KEYPAD == SANSA_M200_PAD) #define ROCKVOC_QUIT BUTTON_POWER #define ROCKVOC_NEXT (BUTTON_SELECT|BUTTON_REL) #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "SELECT" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) #define ROCKVOC_QUIT (BUTTON_HOME|BUTTON_REPEAT) #define ROCKVOC_NEXT (BUTTON_SELECT|BUTTON_REL) #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "SELECT" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) #define ROCKVOC_QUIT BUTTON_POWER #define ROCKVOC_NEXT (BUTTON_PLAY | BUTTON_REL) #define ROCKVOC_OK BUTTON_RIGHT #define ROCKVOC_NOK BUTTON_LEFT #define H_ROCKVOC_NEXT "PLAY" #define H_ROCKVOC_OK "RIGHT" #define H_ROCKVOC_NOK "LEFT" #endif static char delim[] = ";"; static char line[MAX_LINE_LEN]; static int max_card_index; static int button; static char cardbox[MAX_BOX_SIZE][4][MAX_WORD_LEN]; static int box_start[NUMBER_OF_BOXES]; static char vocfile_dir[MAX_PATH]; static char bbuf[MAX_PATH]; static char bbuf_s[MAX_PATH]; static struct tree_context *tree = NULL; static struct { fb_data* backdrop; unsigned foreground; unsigned background; } lcd_settings, lcd_settings_old; static struct configuration { char filename[MAX_PATH]; char filename_short[MAX_PATH]; char directory[MAX_PATH]; char direction[7]; int display_comment; int theme; } config; #define MAX_TEXT 256 static union { fb_data clipboard[ LCD_HEIGHT*LCD_WIDTH]; struct { char text[MAX_TEXT]; char font[MAX_PATH]; char old_font[MAX_PATH]; int fh_buf[30]; int fw_buf[30]; char fontname_buf[30][MAX_PATH]; } text; } file_buffer; static void menu_main(void); static void menu_options(void); static void menu_change_direction(void); static void menu_display_comment(void); static bool menu_save_and_quit(void); static bool rockvoc_help( void ); static void write_line_to_array(char*,int); static void display(char*,char*,int); static int inquiry(int); static void update_box_relation(int); static void sort_cardbox(void); static char increment_box_number(char); static void draw_statistik(void); static bool line_ok(char*); static const char *browse_get_name_cb(int , void*,char*, size_t ); static bool write_configfile(void); static bool reset_file(char[MAX_PATH]); static bool read_file(char[MAX_PATH]); static bool write_file(char[MAX_PATH]); static bool load_configfile(void); static void draw_check(bool); static void run_test(void); static void cut_extension(char filename[MAX_PATH]); static void menu_colour_settings(void); static void update_lcd_settings(void); static void set_colours(int); //******************************************************************* enum plugin_status plugin_start(const void* parameter) //******************************************************************* { /* if you don't use the parameter, you can do like this to avoid the compiler warning about it */ (void)parameter; lcd_settings_old.foreground = rb->lcd_get_foreground(); lcd_settings_old.background = rb->lcd_get_background(); lcd_settings_old.backdrop = rb->lcd_get_backdrop(); // Set default values rb->strcpy( config.direction, "A -> B" ); config.display_comment=0; rb->strcpy( config.directory, "/" ); config.theme=1; load_configfile(); set_colours(config.theme); menu_main(); rb->splash(HZ*2, "Bye!"); #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(lcd_settings_old.foreground); rb->lcd_set_background(lcd_settings_old.background); rb->lcd_set_backdrop(lcd_settings_old.backdrop); #endif return PLUGIN_OK; } //******************************************************************* static void run_test(void) //******************************************************************* { bool first_call = true; if (!read_file(config.filename)) { return; } do { int card_index = 0; int box_num =rb->atoi(&(cardbox[0][3][0])); if (box_num == NUMBER_OF_BOXES-1) { rb->splash(HZ*2,"File already finished!"); if (first_call) { return; } } else { card_index = inquiry(box_num); while (card_index >= 0) // not quit { update_box_relation(card_index); sort_cardbox(); if (box_start[box_num] >= 0) { card_index = inquiry(box_num); } else { if (rb->atoi(&(cardbox[0][3][0])) == NUMBER_OF_BOXES-1) { draw_statistik(); rb->splash(HZ*2,"You have finished!"); break; } box_num = (box_num < NUMBER_OF_BOXES-2) ? (box_num+1) : (rb->atoi(&(cardbox[0][3][0]))); card_index = inquiry(box_num); } } } first_call=false; } while (!menu_save_and_quit()); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } } //******************************************************************* static void set_colours(int colour) //******************************************************************* { switch( colour ) { case 1: { lcd_settings.foreground=BLACK; lcd_settings.background=SOFTWHITE; lcd_settings.backdrop=NULL; update_lcd_settings(); config.theme=1; break; } case 2: { lcd_settings.foreground=WHITE; lcd_settings.background=BLUE; lcd_settings.backdrop=NULL; update_lcd_settings(); config.theme=2; break; } case 3: { lcd_settings.foreground=DARKRED; lcd_settings.background=AMBER; lcd_settings.backdrop=NULL; update_lcd_settings(); config.theme=3; break; } case 4: { lcd_settings.foreground=LIGHTGRAY; lcd_settings.background=SLATEGRAY; lcd_settings.backdrop=NULL; update_lcd_settings(); config.theme=4; break; } default: { lcd_settings.foreground=lcd_settings_old.foreground; lcd_settings.background=lcd_settings_old.background; lcd_settings.backdrop=lcd_settings_old.backdrop; update_lcd_settings(); config.theme=0; break; } } } //******************************************************************* static bool read_file(char file_name[MAX_PATH]) //******************************************************************* { int file = rb->open(file_name, O_RDONLY); if(file < 0) { rb->splashf(HZ*2, "%s not found",file_name); return false; } int card_index = 0; while (rb->read_line(file,line,MAX_LINE_LEN)>0 && card_indexsplash(HZ*2,"Unknown format"); return false; } if (card_index == MAX_BOX_SIZE) { rb->splash(HZ*2, "File exceeds 500 lines"); rb->close(file); return false; } rb->close(file); max_card_index=card_index-1; for (card_index=0; card_index<=max_card_index;card_index++) { if(!isdigit(cardbox[card_index][3][0])) { cardbox[card_index][3][0]='0'; } } sort_cardbox(); return true; } //******************************************************************* static bool write_file(char file_name[MAX_PATH]) //******************************************************************* { int card_index = 0; int savefile = rb->open(file_name, O_RDWR | O_CREAT); if(savefile < 0) { return false; } for (card_index=0;card_index<=max_card_index;card_index++) { rb->snprintf(line, sizeof(line),"%s;%s;%s;%s\n", cardbox[card_index][0], cardbox[card_index][1], cardbox[card_index][2], cardbox[card_index][3]); rb->write(savefile, line, rb->strlen(line)); } rb->close(savefile); return true; } //************************************************************************ static const char* browse_get_name_cb(int selected_item, void *data, char *file_buffer, size_t buffer_len) //************************************************************************ { int *indexes = (int *) data; struct entry* dc = tree->dircache; struct entry* e = &dc[indexes[selected_item]]; (void) file_buffer; (void) buffer_len; return e->name; } //************************************************************************ static bool select_file( char *selected_filename, char *selected_filename_short, char *selected_directory, int filename_size, const char *start ) //************************************************************************ { struct gui_synclist browse_list; int item_count = 0, selected, button; struct tree_context backup; struct entry *dc; bool reload = true; int dirfilter = SHOW_ALL; int *indexes = (int *) file_buffer.clipboard; char *a; rb->strcpy( bbuf, start ); a = bbuf+rb->strlen(bbuf)-1; if( *a != '/' ) { a[1] = '/'; a[2] = '\0'; } bbuf_s[0] = '\0'; rb->gui_synclist_init(&browse_list, browse_get_name_cb, (void*) indexes, false, 1, NULL); tree = rb->tree_get_context(); backup = *tree; dc = tree->dircache; a = backup.currdir+rb->strlen(backup.currdir)-1; if( *a != '/' ) { *++a = '/'; *++a = '\0'; } rb->strcpy( a, dc[tree->selected_item].name ); tree->dirfilter = &dirfilter; while( 1 ) { if( reload ) { int i; rb->set_current_file(bbuf); item_count = 0; selected = 0; for( i = 0; i < tree->filesindir ; i++) { if( !rb->strcmp( dc[i].name, bbuf_s ) ) { selected = item_count; } indexes[item_count++] = i; } rb->gui_synclist_set_nb_items(&browse_list,item_count); rb->gui_synclist_select_item(&browse_list, selected); rb->gui_synclist_set_title(&browse_list, bbuf, NOICON); rb->gui_synclist_draw(&browse_list); reload = false; } button = rb->get_action(CONTEXT_LIST,TIMEOUT_BLOCK); if (rb->gui_synclist_do_button(&browse_list,&button, LIST_WRAP_UNLESS_HELD)) continue; switch( button ) { case ACTION_STD_CANCEL: if( !rb->strcmp( bbuf, "/" ) ) { *tree = backup; rb->set_current_file( backup.currdir ); return false; } rb->strcpy( bbuf_s, ".." ); case ACTION_STD_OK: if( button == ACTION_STD_OK ) { selected = rb->gui_synclist_get_sel_pos( &browse_list ); if( selected < 0 || selected >= item_count ) break; struct entry* e = &dc[indexes[selected]]; rb->strlcpy( bbuf_s, e->name, sizeof( bbuf_s ) ); if( !( e->attr & ATTR_DIRECTORY ) ) { *tree = backup; rb->set_current_file( backup.currdir ); rb->snprintf(selected_filename_short,filename_size, "%s",bbuf_s); rb->snprintf(selected_filename,filename_size, "%s%s",bbuf,bbuf_s); rb->snprintf(selected_directory,filename_size, "%s",bbuf); rb->strlcpy( vocfile_dir, bbuf, sizeof( bbuf ) ); return true; } } if( !rb->strcmp( bbuf_s, "." ) ) break; a = bbuf+rb->strlen(bbuf); if( !rb->strcmp( bbuf_s, ".." ) ) { a--; if( a == bbuf ) break; if( *a == '/' ) a--; while( *a != '/' ) a--; rb->strcpy( bbuf_s, ++a ); /* select parent directory */ bbuf_s[rb->strlen(bbuf_s)-1] = '\0'; *a = '\0'; reload = true; break; } rb->snprintf( a, bbuf+sizeof(bbuf)-a, "%s/", bbuf_s ); reload = true; break; case ACTION_STD_MENU: *tree = backup; rb->set_current_file( backup.currdir ); return false; } } } //************************************************************************ static bool write_configfile(void) //************************************************************************ { char newline[MAX_LINE_LEN]; int configfile=rb->open(CONFIG_FILE, O_CREAT|O_WRONLY|O_TRUNC ); if(configfile < 0) { return false; } rb->snprintf(newline,MAX_LINE_LEN,":%s\n",config.filename); rb->write(configfile,newline, rb->strlen(newline)); rb->snprintf(newline,MAX_LINE_LEN,":%s\n",config.directory); rb->write(configfile,newline, rb->strlen(newline)); rb->snprintf(newline,MAX_LINE_LEN,":%s\n",config.direction); rb->write(configfile,newline, rb->strlen(newline)); rb->snprintf(newline,MAX_LINE_LEN,":%d\n", config.display_comment); rb->write(configfile,newline, rb->strlen(newline)); rb->snprintf(newline,MAX_LINE_LEN,":%d\n",config.theme); rb->write(configfile,newline, rb->strlen(newline)); rb->close(configfile); return true; } //************************************************************************ static bool load_configfile(void) //************************************************************************ { int configfile = rb->open(CONFIG_FILE, O_RDONLY); static char config_line[MAX_PATH]; char *identifier, *value, *end, *token, *t_end; if(configfile < 0) { return false; } while (rb->read_line(configfile, config_line, MAX_LINE_LEN)>0 ) { identifier= rb->strtok_r(config_line,":",&end); value = rb->strtok_r(NULL,":",&end); if (identifier != NULL && value != NULL ) { if (rb->strcmp(identifier,"") == 0 ) { rb->strcpy(config.filename,value); token = rb->strtok_r(value,"/",&t_end); while (token != NULL) { rb->strcpy(config.filename_short,token); token = rb->strtok_r(NULL, "/",&t_end); } } else if ( rb->strcmp(identifier,"") == 0 ) { rb->strcpy(config.direction,value); } else if ( rb->strcmp(identifier,"") == 0 ) { config.display_comment=rb->atoi(value); } else if ( rb->strcmp(identifier,"") == 0 ) { rb->strcpy(config.directory,value); } else if ( rb->strcmp(identifier,"") == 0 ) { config.theme = rb->atoi(value); } } } return true; } //************************************************************************ static void cut_extension(char work_filename[MAX_PATH]) //************************************************************************ { char *file_token, *file_t_end, *p, new_filename[MAX_PATH]; bool first_token=true; if ((p=rb->strchr(work_filename, '.'))!=NULL) { char old_token[MAX_PATH]; file_token = rb->strtok_r(work_filename,".",&file_t_end); while (file_token != NULL) { rb->strcpy(old_token,file_token); file_token = rb->strtok_r(NULL, ".", &file_t_end); if (file_token != NULL) { if (first_token) { rb->strcpy(new_filename,old_token); first_token=false; } else { rb->strcat(new_filename,"."); rb->strcat(new_filename,old_token); } } } rb->strcpy(work_filename,new_filename); } } //************************************************************************ static void menu_main(void) //************************************************************************ { int selection = 0; bool menu_quit = false; struct gui_synclist; char start_dir[MAX_PATH]; int checkfile; MENUITEM_STRINGLIST(menu, "Rockvoc Menu", NULL, "Start Test", "Select File", "Options", "Help", "Quit"); while (!menu_quit) { switch(rb->do_menu(&menu, &selection, NULL, false)) { case 0: checkfile = rb->open(config.filename, O_RDONLY); if(checkfile < 0) { rb->splash(HZ*2, "Select File first."); } else // filename found { rb->close(checkfile); run_test(); } break; case 1: rb->strcpy( start_dir,config.directory); if ( select_file(config.filename,config.filename_short, config.directory, MAX_PATH, start_dir)) { run_test(); } break; case 2: menu_options(); break; case 3: rockvoc_help(); break; case 4: menu_quit=true; break; default: break; } } } //************************************************************************ static bool menu_save_and_quit(void) //************************************************************************ { int selection = 0; bool menu_quit = false, return_value = true; struct gui_synclist; MENUITEM_STRINGLIST(menu, "Test Quit Menu", NULL, "Save Statistik & Quit", "Quit Without Saving", "Resume Test"); while (!menu_quit) { switch(rb->do_menu(&menu, &selection, NULL, false)) { case 0: if (!write_file(config.filename)) { rb->splashf(HZ*2,"Can't write: %s",config.filename); } menu_quit=true; break; case 1: menu_quit=true; break; case 2: menu_quit=true; return_value = false; break; default: break; } } return return_value; } //************************************************************************ static void menu_options(void) //************************************************************************ { int selection = 0; bool menu_quit = false; struct gui_synclist; char start_dir[MAX_PATH]; MENUITEM_STRINGLIST(menu, "Rockvoc Options", NULL, "Change Direction", "Reset File", "Display Comment", "Colour Settings","Quit Rockvoc Options"); while (!menu_quit) { switch(rb->do_menu(&menu, &selection, NULL, false)) { case 0: menu_change_direction(); break; case 1: rb->strcpy( start_dir,config.directory); if (select_file(config.filename,config.filename_short, config.directory,MAX_PATH,start_dir)) { if (!reset_file(config.filename)) { rb->splashf(HZ*2,"Reset for %s failed",config.filename); } else { rb->splashf(HZ*2,"%s reset",config.filename); } } break; case 2: menu_display_comment(); break; case 3: menu_colour_settings(); break; case 4: menu_quit=true; break; default: menu_quit=true; break; } } } //************************************************************************ static void menu_change_direction(void) //************************************************************************ { int direction_selection = 0; bool direction_menu_quit = false; struct direction_gui_synclist; MENUITEM_STRINGLIST(direction_menu, "Rockvoc Change Direction", NULL, "Display Direction", "Set A -> B", "Set B -> A", "Set random", "Quit"); while (!direction_menu_quit) { switch(rb->do_menu(&direction_menu, &direction_selection, NULL, false)) { case 0: rb->splashf(HZ*2,"%s",config.direction); break; case 1: rb->strcpy( config.direction,"A -> B"); rb->splashf(HZ*2,"%s",config.direction); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } direction_menu_quit=true; break; case 2: rb->strcpy( config.direction,"B -> A"); rb->splashf(HZ*2,"%s",config.direction); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } direction_menu_quit=true; break; case 3: rb->strcpy( config.direction,"random"); rb->splashf(HZ*2,"%s",config.direction); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } direction_menu_quit=true; break; default: direction_menu_quit=true; break; } } } //************************************************************************ static void update_lcd_settings(void) //************************************************************************ { #ifdef HAVE_LCD_COLOR rb->lcd_set_background(lcd_settings.background); rb->lcd_set_foreground(lcd_settings.foreground); rb->lcd_set_backdrop(lcd_settings.backdrop); rb->lcd_update(); #endif } //************************************************************************ static void menu_colour_settings(void) //************************************************************************ { int colour_selection = 0; bool colour_menu_quit = false; struct colour_gui_synclist; MENUITEM_STRINGLIST(colour_menu, "Rockvoc Colour Settings", NULL, "Display Settings", "Black/White", "White/Blue", "Red/Amber", "Grey/Darkblue", "Default Colour Settings", "Quit"); while (!colour_menu_quit) { switch(rb->do_menu(&colour_menu, &colour_selection, NULL, false)) { case 0: switch(config.theme) { case 1: rb->splash(HZ*2,"Black/White"); break; case 2: rb->splash(HZ*2,"White/Blue"); break; case 3: rb->splash(HZ*2,"Red/Amber"); break; case 4: rb->splash(HZ*2,"Grey/Darkblue"); break; default: rb->splash(HZ*2,"Default colours"); } break; case 1: set_colours(1); rb->splash(HZ*2,"Colour set to Black/White"); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } colour_menu_quit=true; break; case 2: set_colours(2); rb->splash(HZ*2,"Colour set to White/Blue"); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } colour_menu_quit=true; break; case 3: set_colours(3); rb->splash(HZ*2,"Colours set to Red/Amber"); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } colour_menu_quit=true; break; case 4: set_colours(4); rb->splash(HZ*2,"Colours set to Grey/Darkblue"); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } colour_menu_quit=true; break; case 5: set_colours(0); rb->splash(HZ*2,"Colours set to default"); if (!write_configfile()) { rb->splashf(HZ*2,"Can't write: %s",CONFIG_FILE); } colour_menu_quit=true; break; default: colour_menu_quit=true; break; } } } //************************************************************************ static void menu_display_comment(void) //************************************************************************ { int comment_selection = 0; bool comment_menu_quit = false; struct comment_gui_synclist; MENUITEM_STRINGLIST(comment_menu, "Rockvoc Display Comment", NULL, "On", "Off", "Quit"); while (!comment_menu_quit) { switch(rb->do_menu(&comment_menu, &comment_selection, NULL, false)) { case 0: config.display_comment=1; rb->splash(HZ*2,"Display Comment ON"); comment_menu_quit=true; break; case 1: config.display_comment=0; rb->splash(HZ*2,"Display Comment OFF"); comment_menu_quit=true; break; default: comment_menu_quit=true; break; } } } //************************************************************************ static bool reset_file(char selected_file[MAX_PATH]) //************************************************************************ { int i; if (!read_file(selected_file)) { return false; } for (i=0;i<=max_card_index;i++) { rb->strcpy(cardbox[i][3],"0"); } if (!write_file(selected_file)) { return false; } return true; } //************************************************************************ static bool rockvoc_help( void ) //************************************************************************ { #define WORDS (sizeof help_text / sizeof (char*)) static char *help_text[] = { "Rockvoc", "", "", "Rockvoc","is","a","vocabulary","trainer","which", "is","working", "with", "cardboxes.", "", "Known", "cards", "will", "be", "moved", "to", "the", "next", "box," , "unknown", "to", "the", "first.","", "You", "have", "finished", "when", "all", "cards", "are", "in", "the", "last", "box.","","", "Sequence:", "", "1.","Word","is","displayed.","", "2.","You", "can", "think", "about", "the", "solution.","", "3.","Press", "button", "for", "showing", "translation.","", "4.","Decide", "if", "you", "was", "right", "or", "not.","","", "Controls", "", H_ROCKVOC_NEXT, ":", "Show translation", "", H_ROCKVOC_OK, ":", "Known", "", H_ROCKVOC_NOK, ":", "Not", "known", "", "", "Vocabulary files:","", "Vocabulary", "files", "must", "be", "of", "format:","", "Word1;Word2;Comment","(optional)","", "For","example:","", "lernen;to learn;verb","","", "Maximum","length","of","words:","50","", "Maximum","number","of","lines:","500","", "File", "format:", "UTF-8", }; static struct style_text formation[]= { { 0, TEXT_CENTER|TEXT_UNDERLINE }, { 41, TEXT_UNDERLINE }, { 73, TEXT_UNDERLINE }, { 89, TEXT_UNDERLINE }, }; int button; rb->lcd_setfont(FONT_UI); if (display_text(WORDS, help_text, formation, NULL)) return true; do { button = rb->button_get(true); if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { return true; } } while( ( button == BUTTON_NONE )||( button&(BUTTON_REL|BUTTON_REPEAT))); return false; } //************************************************************************ static bool line_ok(char inputline[]) //************************************************************************ { char *delim_position, *delim_ptr; delim_ptr=delim; delim_position=rb->strchr(inputline, *delim_ptr); if (!delim_position) { return false; } else { return true; } } //************************************************************************ static void write_line_to_array(char inputline[],int line_number) //************************************************************************ { char *token, *end; int i=0; token = rb->strtok_r(inputline,delim,&end); while (token != NULL) { rb->strcpy(cardbox[line_number][i],token); token = rb->strtok_r(NULL, delim,&end); i++; } if (i==3 && rb->strlen(cardbox[line_number][2])==1) { rb->strcpy(cardbox[line_number][3],cardbox[line_number][2]); rb->strcpy(cardbox[line_number][2]," "); } } //************************************************************************ static void display(char* word, char* attrib, int num) //************************************************************************ { int witdth, height; char file_and_size[MAX_PATH]; // calculate positon of word rb->lcd_getstringsize(word, &witdth, &height); int x_pos_att = 0, y_pos_att, y_pos_word1, y_pos_word2; int x_pos_word = (witdth < LCD_WIDTH-2)? ((LCD_WIDTH-witdth)/2) :0; float lines_f=((float)LCD_HEIGHT*4/5)/(float)height; int lines = (int)lines_f; if (attrib != NULL) { // calculate x positon of comment rb->lcd_getstringsize(attrib, &witdth, &height); x_pos_att = (witdth < LCD_WIDTH)? ((LCD_WIDTH-witdth)/2) :0; } // calculate x positon of filename char filename_without_extension[MAX_PATH]; rb->strcpy(filename_without_extension,config.filename_short); cut_extension(filename_without_extension); rb->snprintf(file_and_size,sizeof(file_and_size),"%s (%d)", filename_without_extension,max_card_index+1); rb->lcd_getstringsize(file_and_size, &witdth, &height); int x_pos_filename = (witdth < LCD_WIDTH-2)? ((LCD_WIDTH-witdth)/2) :0; //calculate y positions depending on screensize if (lines > 8) { y_pos_word1 = 3; y_pos_att = 5; y_pos_word2 = 7; } else if(lines > 7) { y_pos_word1 = 2; y_pos_att = 4; y_pos_word2 = 6; } else if (lines > 5) { y_pos_word1 = 2; y_pos_att = 3; y_pos_word2 = 4; } else { y_pos_word1 = 0; y_pos_att = 1; y_pos_word2 = 2; } if (num==1) //first item { rb->lcd_clear_display(); draw_statistik(); if (lines > 5) { if (x_pos_filename > 0 ) { rb->lcd_putsxy(x_pos_filename,0,file_and_size); } else { rb->lcd_puts_scroll(1,0,file_and_size); } } if (x_pos_word >0) { rb->lcd_putsxy(x_pos_word,y_pos_word1*height,word); } else { rb->lcd_puts_scroll(1,y_pos_word1,word); } if (config.display_comment == 1) { if (attrib == NULL ) { attrib = "-"; x_pos_att = LCD_WIDTH/2; } if (x_pos_att > 0) { rb->lcd_putsxy(x_pos_att,y_pos_att*height,attrib); } else { rb->lcd_puts_scroll(1,y_pos_att,attrib); } } } else // second item (translation) { if (x_pos_word > 0) { rb->lcd_putsxy(x_pos_word,y_pos_word2*height,word); } else { rb->lcd_puts_scroll(0,y_pos_word2,word); } } rb->lcd_update(); } //************************************************************************ static int inquiry(int box) //************************************************************************ { char item1[MAX_WORD_LEN], item2[MAX_WORD_LEN], item3[MAX_WORD_LEN]; int card_index, max_index, min_index, x; min_index = box_start[box]; max_index = max_card_index; for (x=box+1;x0) { max_index = box_start[x]-1; break; } } rb->srand(*rb->current_tick); card_index= min_index + rb->rand()%(max_index-(min_index-1)); if (rb->strcmp(config.direction, "B -> A")==0) { rb->snprintf(item1,MAX_WORD_LEN,"%s",cardbox[card_index][1]); rb->snprintf(item2,MAX_WORD_LEN,"%s",cardbox[card_index][0]); } else if (rb->strcmp(config.direction, "random")==0) { rb->srand(*rb->current_tick); x = rb->rand()%(2); if (x==0) { rb->snprintf(item1,MAX_WORD_LEN,"%s",cardbox[card_index][0]); rb->snprintf(item2,MAX_WORD_LEN,"%s",cardbox[card_index][1]); } else { rb->snprintf(item1,MAX_WORD_LEN,"%s",cardbox[card_index][1]); rb->snprintf(item2,MAX_WORD_LEN,"%s",cardbox[card_index][0]); } } else // default A -> B { rb->snprintf(item1,MAX_WORD_LEN,"%s",cardbox[card_index][0]); rb->snprintf(item2,MAX_WORD_LEN,"%s",cardbox[card_index][1]); } rb->snprintf(item3,MAX_WORD_LEN,"%s",cardbox[card_index][2]); if (rb->strlen(item3)<= 1 || config.display_comment != 1) { display(item1,NULL,1); } else { display(item1,item3,1); } do { button=rb->button_get(true); switch(button) { case ROCKVOC_NEXT: display(item2,NULL,2); break; case ROCKVOC_QUIT: return -1; break; } } while (button != ROCKVOC_NEXT ); while (button!=ROCKVOC_OK && button!=ROCKVOC_NOK && button!=ROCKVOC_QUIT) { button=rb->button_get(true); } if (button != ROCKVOC_QUIT) { return card_index; } else { return -1; } } //************************************************************************ static void update_box_relation(int update_index) //************************************************************************ { do { switch(button) { case ROCKVOC_OK: draw_check(true); cardbox[update_index][3][0] = increment_box_number(cardbox[update_index][3][0]); break; case ROCKVOC_NOK: draw_check(false); cardbox[update_index][3][0] = '0'; break; case ROCKVOC_QUIT: break; default: button=rb->button_get(true); break; } }while (button!=ROCKVOC_OK && button!=ROCKVOC_NOK && button!=ROCKVOC_QUIT); } //************************************************************************ static void sort_cardbox(void) //************************************************************************ { int x=0,y=0,z; char temp_element[4][MAX_WORD_LEN]; bool swaped; int card_index; z=max_card_index; do { swaped=false; for (x=0;x cardbox[x+1][3][0]) { for (y=0;y<4;y++) rb->snprintf(temp_element[y],MAX_WORD_LEN,"%s", cardbox[x][y]); for (y=0;y<4;y++) rb->snprintf(cardbox[x][y],MAX_WORD_LEN,"%s", cardbox[x+1][y]); for (y=0;y<4;y++) rb->snprintf(cardbox[x+1][y],MAX_WORD_LEN,"%s", temp_element[y]); swaped=true; } } } while(z-->0 && swaped); // reset box start points for (x=0; xatoi(&cardbox[0][3][0]); // init with first boxnumber int box_number_tmp; box_start[box_number]=0; for( card_index=0; card_index<= max_card_index; card_index++ ) { box_number_tmp=rb->atoi(&cardbox[card_index][3][0]); if (box_number_tmp > box_number && box_number_tmp <= NUMBER_OF_BOXES-1) { box_start[box_number_tmp]=card_index; box_number = box_number_tmp; } } } //************************************************************************ static char increment_box_number(char box) //************************************************************************ { int num_of_boxes=NUMBER_OF_BOXES; char char_num_of_boxes=(char)num_of_boxes+48; if (box>='0' && box < char_num_of_boxes-1) { box++; } return box; } //************************************************************************ static void draw_statistik(void) //************************************************************************ { float box_width_f = (float)LCD_WIDTH/15; float box_high_f = (float)LCD_HEIGHT/5, box_gap_f = box_width_f/2; int box_width,box_high, box_gap,i, j; box_width = (int)box_width_f; box_high = (int)box_high_f; box_gap = (int)box_gap_f; float xframe, yframe, xframe_first, yfilling, filling_high,percent; float with_all_frames = box_width*NUMBER_OF_BOXES + box_gap*(NUMBER_OF_BOXES-1); xframe_first = (LCD_WIDTH-with_all_frames)/2; yframe = LCD_HEIGHT-(box_high+8); int box_end=max_card_index; for (i=0;ilcd_drawrect((int)xframe, (int)yframe,box_width,box_high); if (i= 0) { box_end=box_start[j]-1; break; } box_end=max_card_index; } } else { box_end=max_card_index; } if (box_start[i] >=0) { percent=(((float)box_end+1)-(float)box_start[i])/ (((float)max_card_index+1)/100); } else { percent = 0; } yfilling = yframe + (100-percent)*((float)box_high/100); filling_high = ((float)box_high/100)*percent; rb->lcd_fillrect((int)xframe, (int)yfilling, box_width, (int)filling_high); } rb->lcd_update(); } //************************************************************************ static void draw_check(bool ok) //************************************************************************ { int sign_width = 20, sign_high = 20; int corner_right_top_x = LCD_WIDTH - (sign_width+25); int corner_right_top_y = LCD_HEIGHT - (sign_high+25); int unit_x = sign_width/4; int unit_y = sign_high/4; if (ok) { #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(GREEN); #endif rb->lcd_drawline(corner_right_top_x+unit_x, corner_right_top_y+sign_high-unit_y, corner_right_top_x+2*unit_x, corner_right_top_y + sign_high); rb->lcd_drawline(corner_right_top_x+unit_x+1, corner_right_top_y+sign_high-unit_y, corner_right_top_x+2*unit_x+1, corner_right_top_y + sign_high); rb->lcd_drawline(corner_right_top_x+2*unit_x, corner_right_top_y + sign_high, corner_right_top_x+sign_width, corner_right_top_y ); rb->lcd_drawline(corner_right_top_x+2*unit_x+1, corner_right_top_y + sign_high, corner_right_top_x+sign_width+1, corner_right_top_y ); } else { #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(RED); #endif rb->lcd_drawline(corner_right_top_x, corner_right_top_y, corner_right_top_x+sign_width, corner_right_top_y+sign_high); rb->lcd_drawline(corner_right_top_x+1, corner_right_top_y, corner_right_top_x+sign_width+1, corner_right_top_y+sign_high); rb->lcd_drawline(corner_right_top_x, corner_right_top_y+sign_high, corner_right_top_x+sign_width, corner_right_top_y); rb->lcd_drawline(corner_right_top_x+1, corner_right_top_y+sign_high, corner_right_top_x+sign_width+1, corner_right_top_y); } rb->lcd_update(); update_lcd_settings(); rb->splash(HZ*2, ""); }