From 061eba29deac01e5ccd8c3369cb658978b51d1c9 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Sat, 24 Jul 2010 16:51:56 +0000 Subject: [PATCH] Lua scripts can have individual keyboard shortcuts (Issue 344) git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1532 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/const.h | 11 +++ src/engine.c | 13 ++++ src/factory.c | 125 ++++++++++++++++++++++++++++---- src/factory.h | 9 +++ src/help.c | 189 ++++++++++++++++++++++++++----------------------- src/help.h | 12 ++++ src/helpfile.h | 10 +++ src/hotkeys.c | 90 +++++++++++++++++++++++ src/hotkeys.h | 2 +- src/init.c | 79 ++++++++++++++++++++- src/input.c | 28 ++++++++ src/input.h | 3 + src/readini.c | 2 + src/struct.h | 2 +- 14 files changed, 470 insertions(+), 105 deletions(-) diff --git a/src/const.h b/src/const.h index a5a5fd4c..1b24f278 100644 --- a/src/const.h +++ b/src/const.h @@ -255,6 +255,7 @@ enum CHUNKS_CFG CHUNK_QUICK_SHADE = 8, ///< QShade effect settings CHUNK_GRID = 9, ///< Grid settings CHUNK_BRUSH =10, ///< Paintbrushes + CHUNK_SCRIPTS =11, ///< Callable scripts CHUNK_MAX }; @@ -469,6 +470,16 @@ enum SPECIAL_ACTIONS SPECIAL_LAYER8_SELECT, SPECIAL_LAYER8_TOGGLE, SPECIAL_REPEAT_SCRIPT, + SPECIAL_RUN_SCRIPT_1, + SPECIAL_RUN_SCRIPT_2, + SPECIAL_RUN_SCRIPT_3, + SPECIAL_RUN_SCRIPT_4, + SPECIAL_RUN_SCRIPT_5, + SPECIAL_RUN_SCRIPT_6, + SPECIAL_RUN_SCRIPT_7, + SPECIAL_RUN_SCRIPT_8, + SPECIAL_RUN_SCRIPT_9, + SPECIAL_RUN_SCRIPT_10, NB_SPECIAL_SHORTCUTS ///< Number of special shortcuts }; diff --git a/src/engine.c b/src/engine.c index 42459970..753836a4 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1238,6 +1238,19 @@ void Main_handler(void) Repeat_script(); action++; break; + case SPECIAL_RUN_SCRIPT_1: + case SPECIAL_RUN_SCRIPT_2: + case SPECIAL_RUN_SCRIPT_3: + case SPECIAL_RUN_SCRIPT_4: + case SPECIAL_RUN_SCRIPT_5: + case SPECIAL_RUN_SCRIPT_6: + case SPECIAL_RUN_SCRIPT_7: + case SPECIAL_RUN_SCRIPT_8: + case SPECIAL_RUN_SCRIPT_9: + case SPECIAL_RUN_SCRIPT_10: + Run_numbered_script(key_index-SPECIAL_RUN_SCRIPT_1); + action++; + break; } } } // End of special keys diff --git a/src/factory.c b/src/factory.c index 3d694267..64758f60 100644 --- a/src/factory.c +++ b/src/factory.c @@ -43,6 +43,9 @@ #include "input.h" // Is_shortcut() #include "help.h" // Window_help() +/// Lua scripts bound to shortcut keys. +char * Bound_script[10]; + #ifdef __ENABLE_LUA__ #include @@ -55,6 +58,8 @@ /// Number of characters for name in fileselector. /// Window is adjusted according to it. #define NAME_WIDTH 34 +/// Number of characters for the description block +#define DESC_WIDTH ((NAME_WIDTH+2)*8/6) /// Position of fileselector top, in window space #define FILESEL_Y 18 @@ -826,11 +831,12 @@ void Draw_script_information(T_Fileselector_item * script_item) { FILE *script_file; char full_name[MAX_PATH_CHARACTERS]; - char text_block[3][NAME_WIDTH+3]; + char text_block[3][DESC_WIDTH+1]; int x, y; + int i; // Blank the target area - Window_rectangle(7, FILESEL_Y + 89, (NAME_WIDTH+2)*8+2, 3*8, MC_Black); + Window_rectangle(7, FILESEL_Y + 89, DESC_WIDTH*6+2, 4*8, MC_Black); if (script_item && script_item->Full_name && script_item->Full_name[0]!='\0') { @@ -865,7 +871,7 @@ void Draw_script_information(T_Fileselector_item * script_item) } else { - if (x < NAME_WIDTH+4) + if (x < DESC_WIDTH+2) { // Adding character text_block[y][x-2] = (c<32 || c>255) ? ' ' : c; @@ -879,12 +885,31 @@ void Draw_script_information(T_Fileselector_item * script_item) fclose(script_file); } - Print_in_window(7, FILESEL_Y + 89 , text_block[0], MC_Light, MC_Black); - Print_in_window(7, FILESEL_Y + 89+ 8, text_block[1], MC_Light, MC_Black); - Print_in_window(7, FILESEL_Y + 89+16, text_block[2], MC_Light, MC_Black); + Print_help(8, FILESEL_Y + 89 , text_block[0], 'N', 0, 0); + Print_help(8, FILESEL_Y + 89+ 8, text_block[1], 'N', 0, 0); + Print_help(8, FILESEL_Y + 89+16, text_block[2], 'N', 0, 0); + // Display a line with the keyboard shortcut + Print_help(8, FILESEL_Y + 89+24, "Key:", 'N', 0, 0); + for (i=0; i<10; i++) + if (Bound_script[i]!=NULL && !strcmp(Bound_script[i], script_item->Full_name)) + break; + + if (i<10) + { + const char *shortcut; + shortcut=Keyboard_shortcut_value(SPECIAL_RUN_SCRIPT_1+i); + Print_help(8+4*6, FILESEL_Y + 89+24, shortcut, 'K', 0, strlen(shortcut)); + } + else + { + Print_help(8+4*6, FILESEL_Y + 89+24, "None", 'K', 0, 4); + } } - Update_window_area(7, FILESEL_Y + 89, (NAME_WIDTH+2)*8+2, 3*8); + + + + Update_window_area(8, FILESEL_Y + 89, DESC_WIDTH*6+2, 4*8); } @@ -1044,6 +1069,23 @@ void Run_script(char *scriptdir) Display_cursor(); } +void Run_numbered_script(byte index) +{ + char scriptdir[MAX_PATH_CHARACTERS]; + + if (index>=10) + return; + if (Bound_script[index]==NULL) + return; + + strcpy(scriptdir, Data_directory); + strcat(scriptdir, "scripts/"); + + strcpy(selected_script, Bound_script[index]); + + Run_script(scriptdir); +} + void Repeat_script(void) { char scriptdir[MAX_PATH_CHARACTERS]; @@ -1061,6 +1103,58 @@ void Repeat_script(void) Run_script(scriptdir); } +void Set_script_shortcut(T_Fileselector_item * script_item) +{ + int i; + char full_name[MAX_PATH_CHARACTERS]; + + if (script_item && script_item->Full_name && script_item->Full_name[0]!='\0') + { + strcpy(full_name, Data_directory); + strcat(full_name, "scripts/"); + strcat(full_name, script_item->Full_name); + + // Find if it already has a shortcut + for (i=0; i<10; i++) + if (Bound_script[i]!=NULL && !strcmp(Bound_script[i], script_item->Full_name)) + break; + if (i<10) + { + // Existing shortcut + } + else + { + // Try to find a "free" one. + for (i=0; i<10; i++) + if (Bound_script[i]==NULL + || !Has_shortcut(SPECIAL_RUN_SCRIPT_1+i) + || !File_exists(full_name)) + break; + if (i<10) + { + free(Bound_script[i]); + Bound_script[i]=strdup(script_item->Full_name); + } + else + { + Warning_message("Already 10 scripts have shortcuts."); + return; + } + } + Window_set_shortcut(SPECIAL_RUN_SCRIPT_1+i); + if (!Has_shortcut(SPECIAL_RUN_SCRIPT_1+i)) + { + // User cancelled or deleted all shortcuts + free(Bound_script[i]); + Bound_script[i]=NULL; + } + // Refresh display + Hide_cursor(); + Draw_script_information(script_item); + Display_cursor(); + } +} + void Button_Brush_Factory(void) { short clicked_button; @@ -1068,7 +1162,7 @@ void Button_Brush_Factory(void) T_Scroller_button* scriptscroll; char scriptdir[MAX_PATH_CHARACTERS]; - Open_window(33+8*NAME_WIDTH, 162, "Brush Factory"); + Open_window(33+8*NAME_WIDTH, 180, "Brush Factory"); // Here we use the same data container as the fileselectors. // Reinitialize the list @@ -1080,7 +1174,7 @@ void Button_Brush_Factory(void) // Sort it Sort_list_of_files(&Scripts_list); - Window_set_normal_button(85, 141, 67, 14, "Cancel", 0, 1, KEY_ESC); // 1 + Window_set_normal_button(85, 149, 67, 14, "Cancel", 0, 1, KEY_ESC); // 1 Window_display_frame_in(6, FILESEL_Y - 2, NAME_WIDTH*8+4, 84); // File selector scriptlist = Window_set_list_button( @@ -1091,10 +1185,11 @@ void Button_Brush_Factory(void) Scripts_list.Nb_elements,10, 0)), // 3 Draw_script_name); // 4 - Window_set_normal_button(10, 141, 67, 14, "Run", 0, Scripts_list.Nb_elements!=0, SDLK_RETURN); // 5 + Window_set_normal_button(10, 149, 67, 14, "Run", 0, Scripts_list.Nb_elements!=0, SDLK_RETURN); // 5 - Window_display_frame_in(6, FILESEL_Y + 88, (NAME_WIDTH+2)*8+4, 3*8+2); // Descr. - + Window_display_frame_in(6, FILESEL_Y + 88, DESC_WIDTH*6+4, 4*8+2); // Descr. + Window_set_special_button(7, FILESEL_Y + 89+24,DESC_WIDTH*6,8); // 6 + // Update position Highlight_script(&Scripts_list, scriptlist, selected_script); // Update the scroller position @@ -1125,7 +1220,11 @@ void Button_Brush_Factory(void) scriptlist->List_start + scriptlist->Cursor_position)); Display_cursor(); break; - + + case 6: + Set_script_shortcut(Get_item_by_index(&Scripts_list, + scriptlist->List_start + scriptlist->Cursor_position)); + break; default: break; diff --git a/src/factory.h b/src/factory.h index 5e033974..3a1a54f5 100644 --- a/src/factory.h +++ b/src/factory.h @@ -2,3 +2,12 @@ */ void Button_Brush_Factory(void); void Repeat_script(void); + +/// Lua scripts bound to shortcut keys. +extern char * Bound_script[10]; + +/// +/// Run a lua script linked to a shortcut, 0-9. +/// Before: Cursor hidden +/// After: Cursor shown +void Run_numbered_script(byte index); diff --git a/src/help.c b/src/help.c index 1fee8884..b55c805c 100644 --- a/src/help.c +++ b/src/help.c @@ -233,22 +233,102 @@ void Window_set_shortcut(int action_id) Display_cursor(); } -// -- Menu d'aide ----------------------------------------------------------- - -void Display_help(void) +/// +/// Print a line with the 'help' (6x8) font. +short Print_help(short x_pos, short y_pos, const char *line, char line_type, short link_position, short link_size) { + short width; // Largeur physique d'une ligne de texte short x; // Indices d'affichage d'un caractère short y; short x_position; // Parcours de remplissage du buffer de ligne - short line_index; // 0-15 (16 lignes de textes) short char_index; // Parcours des caractères d'une ligne - short start_line=Help_position; + byte * char_pixel; short repeat_menu_x_factor; short repeat_menu_y_factor; short real_x_pos; short real_y_pos; - byte * char_pixel; - short width; // Largeur physique d'une ligne de texte + + real_x_pos=ToWinX(x_pos); + real_y_pos=ToWinY(y_pos); + + // Calcul de la taille + width=strlen(line); + // Les lignes de titres prennent plus de place + if (line_type == 'T' || line_type == '-') + width = width*2; + + // Pour chaque ligne dans la fenêtre: + for (y=0;y<8;y++) + { + x_position=0; + // On crée une nouvelle ligne à splotcher + for (char_index=0;char_index'_' || line[char_index/2]<' ') + char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré + else if (char_index & 1) + char_pixel=&(Gfx->Help_font_t2[(unsigned char)(line[char_index/2])-' '][0][0]); + else + char_pixel=&(Gfx->Help_font_t1[(unsigned char)(line[char_index/2])-' '][0][0]); + } + else if (line_type=='-') + { + if (line[char_index/2]>'_' || line[char_index/2]<' ') + char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré + else if (char_index & 1) + char_pixel=&(Gfx->Help_font_t4[(unsigned char)(line[char_index/2])-' '][0][0]); + else + char_pixel=&(Gfx->Help_font_t3[(unsigned char)(line[char_index/2])-' '][0][0]); + } + else if (line_type=='S') + char_pixel=&(Gfx->Bold_font[(unsigned char)(line[char_index])][0][0]); + else if (line_type=='N' || line_type=='K') + char_pixel=&(Gfx->Help_font_norm[(unsigned char)(line[char_index])][0][0]); + else + char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Un garde-fou en cas de probleme + + for (x=0;x<6;x++) + for (repeat_menu_x_factor=0;repeat_menu_x_factor=link_position + && char_index<(link_position+link_size)) + { + if (color == MC_Light) + color=MC_White; + else if (color == MC_Dark) + color=MC_Light; + else if (y<7) + color=MC_Dark; + } + Horizontal_line_buffer[x_position++]=color; + while (repetition--) + Horizontal_line_buffer[x_position++]=color; + } + } + // On la splotche + for (repeat_menu_y_factor=0;repeat_menu_y_factor= Help_section[Current_help_section].Length) { - Block (real_x_pos, - real_y_pos, - 44*6*Menu_factor_X, + Window_rectangle (x_pos, + y_pos, + 44*6, // 44 = Nb max de char (+1 pour éviter les plantages en mode X // causés par une largeur = 0) - (Menu_factor_Y<<3) * (16 - line_index), + (16 - line_index)*8, MC_Black); break; } @@ -309,83 +387,16 @@ void Display_help(void) line = buffer; } - // Calcul de la taille - width=strlen(line); - // Les lignes de titres prennent plus de place - if (line_type == 'T' || line_type == '-') - width = width*2; - - // Pour chaque ligne dans la fenêtre: - for (y=0;y<8;y++) - { - x_position=0; - // On crée une nouvelle ligne à splotcher - for (char_index=0;char_index'_' || line[char_index/2]<' ') - char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré - else if (char_index & 1) - char_pixel=&(Gfx->Help_font_t2[(unsigned char)(line[char_index/2])-' '][0][0]); - else - char_pixel=&(Gfx->Help_font_t1[(unsigned char)(line[char_index/2])-' '][0][0]); - } - else if (line_type=='-') - { - if (line[char_index/2]>'_' || line[char_index/2]<' ') - char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré - else if (char_index & 1) - char_pixel=&(Gfx->Help_font_t4[(unsigned char)(line[char_index/2])-' '][0][0]); - else - char_pixel=&(Gfx->Help_font_t3[(unsigned char)(line[char_index/2])-' '][0][0]); - } - else if (line_type=='S') - char_pixel=&(Gfx->Bold_font[(unsigned char)(line[char_index])][0][0]); - else if (line_type=='N' || line_type=='K') - char_pixel=&(Gfx->Help_font_norm[(unsigned char)(line[char_index])][0][0]); - else - char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Un garde-fou en cas de probleme - - for (x=0;x<6;x++) - for (repeat_menu_x_factor=0;repeat_menu_x_factor=link_position - && char_index<(link_position+link_size)) - { - if (color == MC_Light) - color=MC_White; - else if (color == MC_Dark) - color=MC_Light; - else if (y<7) - color=MC_Dark; - } - Horizontal_line_buffer[x_position++]=color; - while (repetition--) - Horizontal_line_buffer[x_position++]=color; - } - } - // On la splotche - for (repeat_menu_y_factor=0;repeat_menu_y_factor -#define NB_SHORTCUTS 187 ///< Number of actions that can have a key combination associated to it. +#define NB_SHORTCUTS 197 ///< Number of actions that can have a key combination associated to it. /*** Types definitions and structs ***/ diff --git a/src/init.c b/src/init.c index 4cd99434..57b355ee 100644 --- a/src/init.c +++ b/src/init.c @@ -2125,6 +2125,49 @@ int Load_CFG(int reload_all) goto Erreur_lecture_config; } break; + + + case CHUNK_SCRIPTS: + if (reload_all) + { + int current_size=0; + int current_script=0; + + while(current_size=10) + break; + } + + + } + break; + default: // Chunk inconnu goto Erreur_lecture_config; } @@ -2348,7 +2391,7 @@ int Save_CFG(void) { long total_size=0; int index; - // Compute size: normal paintbrushes + // Compute size: monochrome paintbrushes for (index=0; indexRight_click_colorpick=(values[0]!=0); } + + fclose(file); diff --git a/src/struct.h b/src/struct.h index 2cbdcb89..ee80a30a 100644 --- a/src/struct.h +++ b/src/struct.h @@ -321,7 +321,7 @@ typedef struct word Double_click_speed; ///< Maximum delay for double-click, in ms. word Double_key_speed; ///< Maximum delay for double-keypress, in ms. byte Grid_XOR_color; ///< XOR value to apply for grid color. - byte Right_click_colorpick; ///< Boolean, true to enable a "tablet" mode, where RMB acts as instant colorpicker + byte Right_click_colorpick; ///< Boolean, true to enable a "tablet" mode, where RMB acts as instant colorpicker } T_Config; // Structures utilisées pour les descriptions de pages et de liste de pages.