From 14464fef393e1a2efc8a4acc3bae1de2b20c8822 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Fri, 19 Feb 2010 02:09:50 +0000 Subject: [PATCH] Lua inputbox: Allow negative values and floating point input. Unfinished, has problems of display (mouse cursor cleaning, display cleaning and alignment, removing redundant digits like in 15.000) git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1354 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- buttons.c | 2 +- factory.c | 83 ++++++++++++++++++++++++++------------------ filesel.c | 2 +- misc.c | 9 +++++ misc.h | 7 ++++ readline.c | 58 +++++++++++++++++++++++++++++-- readline.h | 5 +-- scripts/settings.lua | 31 +++++++++++++++++ 8 files changed, 156 insertions(+), 41 deletions(-) create mode 100644 scripts/settings.lua diff --git a/buttons.c b/buttons.c index b377eeea..d6d13c2e 100644 --- a/buttons.c +++ b/buttons.c @@ -4443,7 +4443,7 @@ void Button_Text() switch(clicked_button) { case 1: // Texte saisi - Readline_ex(50,20,str,29,250,0); + Readline_ex(50,20,str,29,250,0,0); preview_is_needed=1; break; diff --git a/factory.c b/factory.c index 80ab810f..b2e92829 100644 --- a/factory.c +++ b/factory.c @@ -24,6 +24,8 @@ * The brush factory allows you to generate brushes with Lua code. */ +#include + #include "brush.h" #include "buttons.h" #include "engine.h" @@ -367,9 +369,11 @@ int L_GetTransColor(lua_State* L) int L_InputBox(lua_State* L) { const int max_settings = 9; - int min_value[max_settings]; - int max_value[max_settings]; - int current_value[max_settings]; + const int args_per_setting = 5; + double min_value[max_settings]; + double max_value[max_settings]; + byte decimal_places[max_settings]; + double current_value[max_settings]; const char * label[max_settings]; unsigned short control[max_settings*3+1]; // Each value has at most 3 widgets. enum CONTROL_TYPE { @@ -389,20 +393,20 @@ int L_InputBox(lua_State* L) unsigned int max_label_length; int setting; short clicked_button; - char str[5]; + char str[40]; short close_window = 0; nb_args = lua_gettop (L); - if (nb_args < 5) + if (nb_args < 6) { - return luaL_error(L, "InputBox: Less than 5 arguments"); + return luaL_error(L, "InputBox: Less than 6 arguments"); } - if ((nb_args - 1) % 4) + if ((nb_args - 1) % args_per_setting) { return luaL_error(L, "InputBox: Wrong number of arguments"); } - nb_settings = (nb_args-1)/4; + nb_settings = (nb_args-1)/args_per_setting; if (nb_settings > max_settings) { return luaL_error(L, "InputBox: Too many settings, limit reached"); @@ -418,17 +422,23 @@ int L_InputBox(lua_State* L) for (setting=0; setting max_label_length) max_label_length = strlen(label[setting]); - current_value[setting] = lua_tonumber(L,setting*4+3); - min_value[setting] = lua_tonumber(L,setting*4+4); - max_value[setting] = lua_tonumber(L,setting*4+5); - if (max_value[setting] > 9999) - max_value[setting] = 9999; - + current_value[setting] = lua_tonumber(L,setting*args_per_setting+3); + min_value[setting] = lua_tonumber(L,setting*args_per_setting+4); + /*if (min_value[setting] < -999999999999999.0) + min_value[setting] = -999999999999999.0;*/ + max_value[setting] = lua_tonumber(L,setting*args_per_setting+5); + /*if (max_value[setting] > 999999999999999.0) + max_value[setting] = 999999999999999.0;*/ + decimal_places[setting] = lua_tonumber(L,setting*args_per_setting+6); + if (decimal_places[setting]>15) + decimal_places[setting]=15; // Keep current value in range + current_value[setting] = Fround(current_value[setting], decimal_places[setting]); + if (current_value[setting] < min_value[setting]) current_value[setting] = min_value[setting]; else if (current_value[setting] > max_value[setting]) @@ -439,7 +449,7 @@ int L_InputBox(lua_State* L) max_label_length=25; Hide_cursor(); - Open_window(91+max_label_length*8,44+nb_settings*17,window_caption); + Open_window(115+max_label_length*8,44+nb_settings*17,window_caption); // OK Window_set_normal_button( 7, 25 + 17 * nb_settings, 51,14,"OK" , 0,1,SDLK_RETURN); @@ -455,7 +465,7 @@ int L_InputBox(lua_State* L) if (min_value[setting]==0 && max_value[setting]==1) { // Checkbox - Window_set_normal_button(12+max_label_length*8+30, 19+setting*17, 15,13,current_value[setting]?"X":"", 0,1,KEY_NONE); + Window_set_normal_button(12+max_label_length*8+42, 19+setting*17, 15,13,current_value[setting]?"X":"", 0,1,KEY_NONE); control[Window_nb_buttons] = CONTROL_CHECKBOX | setting; } else @@ -465,16 +475,15 @@ int L_InputBox(lua_State* L) control[Window_nb_buttons] = CONTROL_INPUT_MINUS | setting; // Numeric input field - Window_display_frame_in(12+max_label_length*8+21, 20+setting*17,35, 11); - Window_set_input_button(12+max_label_length*8+21, 20+setting*17,4); + Window_set_input_button(12+max_label_length*8+21, 20+setting*17,7); // Print editable value - Num2str(current_value[setting],str,4); - Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 4,MC_Black,MC_Light); + Dec2str(current_value[setting],str,decimal_places[setting]); + Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 7,MC_Black,MC_Light); // control[Window_nb_buttons] = CONTROL_INPUT | setting; // + Button - Window_set_repeatable_button(12+max_label_length*8+60, 20+setting*17, 13,11,"+" , 0,1,KEY_NONE); + Window_set_repeatable_button(12+max_label_length*8+84, 20+setting*17, 13,11,"+" , 0,1,KEY_NONE); control[Window_nb_buttons] = CONTROL_INPUT_PLUS | setting; } } @@ -501,9 +510,9 @@ int L_InputBox(lua_State* L) break; case CONTROL_INPUT: - Num2str(current_value[setting],str,4); - Readline(12+max_label_length*8+23, 22+setting*17,str,4,1); - current_value[setting]=atoi(str); + Dec2str(current_value[setting],str,decimal_places[setting]); + Readline_ex(12+max_label_length*8+23, 22+setting*17,str,7,40,3,decimal_places[setting]); + current_value[setting]=atof(str); if (current_value[setting] < min_value[setting]) current_value[setting] = min_value[setting]; @@ -511,8 +520,8 @@ int L_InputBox(lua_State* L) current_value[setting] = max_value[setting]; Hide_cursor(); // Print editable value - Num2str(current_value[setting],str,4); - Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 4,MC_Black,MC_Light); + Dec2str(current_value[setting],str,decimal_places[setting]); + Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 7,MC_Black,MC_Light); // Display_cursor(); @@ -522,10 +531,13 @@ int L_InputBox(lua_State* L) if (current_value[setting] > min_value[setting]) { current_value[setting]--; + if (current_value[setting] < min_value[setting]) + current_value[setting] = min_value[setting]; + Hide_cursor(); // Print editable value - Num2str(current_value[setting],str,4); - Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 4,MC_Black,MC_Light); + Dec2str(current_value[setting],str,decimal_places[setting]); + Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 7,MC_Black,MC_Light); // Display_cursor(); } @@ -535,19 +547,22 @@ int L_InputBox(lua_State* L) if (current_value[setting] < max_value[setting]) { current_value[setting]++; + if (current_value[setting] > max_value[setting]) + current_value[setting] = max_value[setting]; + Hide_cursor(); // Print editable value - Num2str(current_value[setting],str,4); - Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 4,MC_Black,MC_Light); + Dec2str(current_value[setting],str,decimal_places[setting]); + Print_in_window_limited(12+max_label_length*8+23, 22+setting*17, str, 7,MC_Black,MC_Light); // Display_cursor(); } break; case CONTROL_CHECKBOX: - current_value[setting] = !current_value[setting]; + current_value[setting] = (current_value[setting]<0.5); Hide_cursor(); - Print_in_window(12+max_label_length*8+34, 22+setting*17, current_value[setting]?"X":" ",MC_Black,MC_Light); + Print_in_window(12+max_label_length*8+46, 22+setting*17, current_value[setting]?"X":" ",MC_Black,MC_Light); Display_cursor(); break; } @@ -566,7 +581,7 @@ int L_InputBox(lua_State* L) // One value per control for (setting=0; settingPos_X+3+10,bookmark_dropdown[clicked_button-10]->Pos_Y+2,bookmark_label,8,8,0)) + if (Readline_ex(bookmark_dropdown[clicked_button-10]->Pos_X+3+10,bookmark_dropdown[clicked_button-10]->Pos_Y+2,bookmark_label,8,8,0,0)) strcpy(Config.Bookmark_label[clicked_button-10],bookmark_label); Display_bookmark(bookmark_dropdown[clicked_button-10],clicked_button-10); Display_cursor(); diff --git a/misc.c b/misc.c index cf960bea..d48cf531 100644 --- a/misc.c +++ b/misc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "struct.h" #include "sdlscreen.h" #include "global.h" @@ -811,6 +812,14 @@ int Max(int a,int b) return (a>b)?a:b; } +/* Round number n to d decimal points */ +double Fround(double n, unsigned d) +{ + double exp; + exp = pow(10.0, d); + return floor(n * exp + 0.5) / exp; +} + // Fonction retournant le libellé d'une mode (ex: " 320x200") char * Mode_label(int mode) diff --git a/misc.h b/misc.h index 4a6010e5..523f143d 100644 --- a/misc.h +++ b/misc.h @@ -150,9 +150,16 @@ unsigned long Memory_free(void); #define Num2str(a,b,c) sprintf(b,"%*lu",c,(long)(a)) +#define Dec2str(a,b,c) sprintf(b,"%.*f",c,(double)(a)) + short Round(float value); short Round_div_max(short numerator,short divisor); +/* round number n to d decimal points */ +double Fround(double n, unsigned d); + + + int Min(int a,int b); int Max(int a,int b); diff --git a/readline.c b/readline.c index 80a895cf..0c9c0759 100644 --- a/readline.c +++ b/readline.c @@ -27,6 +27,7 @@ #include #include +#include #include "const.h" #include "struct.h" @@ -120,18 +121,19 @@ byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type max_size = 255; else max_size = visible_size; - return Readline_ex(x_pos,y_pos,str,visible_size,max_size,input_type); + return Readline_ex(x_pos,y_pos,str,visible_size,max_size,input_type,0); } /**************************************************************************** * Enhanced super scanf deluxe pro plus giga mieux :-) * ****************************************************************************/ -byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type) +byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type, byte decimal_places) // Paramètres: // x_pos, y_pos : Coordonnées de la saisie dans la fenêtre // str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale) // max_size : Nombre de caractères logeant dans la zone de saisie -// input_type : 0=Chaîne, 1=Nombre, 2=Nom de fichier +// input_type : 0=String, 1=Unsigned int, 2=Filename 3=Signed Double +// decimal_places: Number of decimal places for a double // Sortie: // 0: Sortie par annulation (Esc.) / 1: sortie par acceptation (Return) { @@ -149,6 +151,8 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz str[0]='\0'; else if (input_type==1) snprintf(str,10,"%d",atoi(str)); // On tasse la chaine à gauche + else if (input_type==3) + sprintf(str,"%.*f",decimal_places, atof(str)); // On tasse la chaine à gauche Wait_end_of_click(); Keyboard_click_allowed = 0; @@ -286,6 +290,14 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz if ( (input_key>='0') && (input_key<='9') ) is_authorized=1; break; + case 3: // Decimal number + if ( (input_key>='0') && (input_key<='9') ) + is_authorized=1; + else if (input_key=='-' && position==0 && str[0]!='-') + is_authorized=1; + else if (input_key=='.') + is_authorized=1; + break; default : // Nom de fichier // On regarde si la touche est autorisée if ( Valid_character(input_key)) @@ -344,6 +356,46 @@ affichage: } Print_in_window(x_pos+((max_size-size)<<3),y_pos,str,TEXT_COLOR,BACKGROUND_COLOR); } + else if (input_type==3) + { + double value; + int i; + unsigned int str_length; + + value = atof(str); + + // Remove extraneous decimal places: + // From number + value = Fround(value, decimal_places); + + // From display + sprintf(str,"%.*f",decimal_places, atof(str)); + // Remove extraneous zeroes + /* + for (i=0; i