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
This commit is contained in:
Yves Rizoud 2010-02-19 02:09:50 +00:00
parent f05906f99b
commit 14464fef39
8 changed files with 156 additions and 41 deletions

View File

@ -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;

View File

@ -24,6 +24,8 @@
* The brush factory allows you to generate brushes with Lua code.
*/
#include <math.h>
#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<nb_settings; setting++)
{
label[setting] = lua_tostring(L,setting*4+2);
label[setting] = lua_tostring(L,setting*args_per_setting+2);
if (strlen(label[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; setting<nb_settings; setting++)
lua_pushinteger(L, current_value[setting]);
lua_pushnumber(L, current_value[setting]);
return 1 + nb_settings;
}

View File

@ -1488,7 +1488,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
strcpy(bookmark_label, Config.Bookmark_label[clicked_button-10]);
if (bookmark_label[7]==ELLIPSIS_CHARACTER)
bookmark_label[7]='\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))
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();

9
misc.c
View File

@ -24,6 +24,7 @@
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <math.h>
#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)

7
misc.h
View File

@ -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);

View File

@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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<size; i++)
{
if (str[i]=='.')
{
int j;
for (j=0; i+j<size && j<decimal_places && str[i+j]!='.'; j++)
{
// advance
}
str[i+j]='\0';
size = i+j;
break; // end of process
}
}
*/
// Recompute updated size
size = strlen(str);
if (size<=visible_size)
Print_in_window(x_pos+((visible_size-size)<<3),y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
else
Print_in_window_limited(x_pos,y_pos,str,visible_size,TEXT_COLOR,BACKGROUND_COLOR);
}
else
{
Print_in_window_limited(x_pos,y_pos,str,visible_size,TEXT_COLOR,BACKGROUND_COLOR);

View File

@ -41,6 +41,7 @@ byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type
/// @param str The original string value (will be modified, unless user cancels.
/// @param visible_size Number of characters visible.
/// @param max_size Number of characters editable.
/// @param input_type 0=string, 1=number, 2=filename (255 editable characters)
/// @param input_type 0=string, 1=integer, 2=filename (255 editable characters) 3=decimal
/// @param decimal_places Number of decimal places (used only with decimal type)
/// @return 0 if user cancelled (esc), 1 if accepted (return)
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);

31
scripts/settings.lua Normal file
View File

@ -0,0 +1,31 @@
-- Test LUA inputbox
-- this script only resizes the brush
w, h = getbrushsize()
--[[
messagebox(
"Forecolor: " .. getforecolor() .. "\n" ..
"Backcolor: " .. getbackcolor() .. "\n" ..
"Transparent color: " .. gettranscolor() .. "\n" ..
"Brush dimensions: " .. w .. "x" .. h
)
]]
ok, w, h = inputbox("Modify brush",
"Width", w, -100.0,100.0, 0,
"Height", h, -200.0,100.0, 0,
"X Flip", 0, 0, 1, 0,
"Y Flip", 0, 0, 1, 0
);
if ok == true then
setbrushsize(w,h)
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
putbrushpixel(x,y,1);
end
end
end