Virtual keyboard for string input

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1636 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2010-10-02 19:05:30 +00:00
parent b78bae876b
commit 5fd72996c3
4 changed files with 227 additions and 57 deletions

View File

@ -1555,6 +1555,8 @@ void Open_window(word width,word height, const char * title)
Window_pos_Y=(Screen_height-(height*Menu_factor_Y))>>1;
Window_draggable=1;
// Sauvegarde de ce que la fenêtre remplace
Save_background(&(Window_background[Windows_open-1]), Window_pos_X, Window_pos_Y, width, height);
@ -2225,6 +2227,7 @@ void Open_popup(word x_pos, word y_pos, word width,word height)
Window_height=height;
Window_pos_X=x_pos;
Window_pos_Y=y_pos;
Window_draggable=0;
// Sauvegarde de ce que la fenêtre remplace
Save_background(&(Window_background[Windows_open-1]), Window_pos_X, Window_pos_Y, width, height);
@ -3148,7 +3151,7 @@ short Window_clicked_button(void)
}
}
if (!Input_sticky_control && Mouse_Y < Window_pos_Y+(12*Menu_factor_Y))
if (!Input_sticky_control && Window_draggable && Mouse_Y < Window_pos_Y+(12*Menu_factor_Y))
{
Move_window(Mouse_X-Window_pos_X,Mouse_Y-Window_pos_Y);
}
@ -3419,17 +3422,17 @@ void Remap_window_backgrounds(byte * conversion_table, int Min_Y, int Max_Y)
EDI = Window_background[window_index];
// Pour chaque ligne
for(dx=0; dx<Window_stack_height[window_index]*Menu_factor_Y;dx++)
for(dx=0; dx<Window_stack[window_index].Height*Menu_factor_Y;dx++)
{
if (dx+Window_stack_pos_Y[window_index]>Max_Y)
if (dx+Window_stack[window_index].Pos_Y>Max_Y)
return;
if (dx+Window_stack_pos_Y[window_index]<Min_Y)
if (dx+Window_stack[window_index].Pos_Y<Min_Y)
{
EDI += Window_stack_width[window_index]*Menu_factor_X*Pixel_width;
EDI += Window_stack[window_index].Width*Menu_factor_X*Pixel_width;
}
else
// Pour chaque pixel
for(cx=Window_stack_width[window_index]*Menu_factor_X*Pixel_width;cx>0;cx--)
for(cx=Window_stack[window_index].Width*Menu_factor_X*Pixel_width;cx>0;cx--)
{
*EDI = conversion_table[*EDI];
EDI ++;

View File

@ -508,71 +508,59 @@ GFX2_GLOBAL word Menu_Y_before_window;
/// Backup of ::Paintbrush_hidden, used to store it while a window is open.
GFX2_GLOBAL byte Paintbrush_hidden_before_window;
GFX2_GLOBAL word Window_stack_pos_X[8];
/// The global stack of editor screens.
GFX2_GLOBAL T_Window Window_stack[8];
/// Position of the left border of the topmost window (in screen coordinates)
#define Window_pos_X Window_stack_pos_X[Windows_open-1]
#define Window_pos_X Window_stack[Windows_open-1].Pos_X
GFX2_GLOBAL word Window_stack_pos_Y[8];
/// Position of the top border of the topmost window (in screen coordinates)
#define Window_pos_Y Window_stack_pos_Y[Windows_open-1]
#define Window_pos_Y Window_stack[Windows_open-1].Pos_Y
GFX2_GLOBAL word Window_stack_width[8];
///
/// Width of the topmost window, in "window pixels"
/// (multiply by ::Menu_factor_X to get screen pixels)
#define Window_width Window_stack_width[Windows_open-1]
#define Window_width Window_stack[Windows_open-1].Width
GFX2_GLOBAL word Window_stack_height[8];
///
/// Height of the topmost window, in "window pixels"
/// (multiply by ::Menu_factor_Y to get screen pixels)
#define Window_height Window_stack_height[Windows_open-1]
#define Window_height Window_stack[Windows_open-1].Height
GFX2_GLOBAL word Window_stack_nb_buttons[8];
/// Total number of buttons/controls in the topmost window.
#define Window_nb_buttons Window_stack_nb_buttons[Windows_open-1]
#define Window_nb_buttons Window_stack[Windows_open-1].Nb_buttons
GFX2_GLOBAL T_Normal_button * Window_stack_normal_button_list[8];
/// List of normal buttons in the topmost window.
#define Window_normal_button_list Window_stack_normal_button_list[Windows_open-1]
#define Window_normal_button_list Window_stack[Windows_open-1].Normal_button_list
GFX2_GLOBAL T_Palette_button * Window_stack_palette_button_list[8];
/// List of "palette" buttons in the topmost window.
#define Window_palette_button_list Window_stack_palette_button_list[Windows_open-1]
#define Window_palette_button_list Window_stack[Windows_open-1].Palette_button_list
GFX2_GLOBAL T_Scroller_button * Window_stack_scroller_button_list[8];
/// List of sliders (scrollers) in the topmost window.
#define Window_scroller_button_list Window_stack_scroller_button_list[Windows_open-1]
#define Window_scroller_button_list Window_stack[Windows_open-1].Scroller_button_list
GFX2_GLOBAL T_Special_button * Window_stack_special_button_list[8];
/// List of special buttons in the topmost window.
#define Window_special_button_list Window_stack_special_button_list[Windows_open-1]
#define Window_special_button_list Window_stack[Windows_open-1].Special_button_list
GFX2_GLOBAL T_Dropdown_button * Window_stack_dropdown_button_list[8];
/// List of dropdown buttons in the topmost window.
#define Window_dropdown_button_list Window_stack_dropdown_button_list[Windows_open-1]
#define Window_dropdown_button_list Window_stack[Windows_open-1].Dropdown_button_list
GFX2_GLOBAL T_List_button * Window_stack_list_button_list[8];
/// List of list buttons in the topmost window.
#define Window_list_button_list Window_stack_list_button_list[Windows_open-1]
#define Window_list_button_list Window_stack[Windows_open-1].List_button_list
GFX2_GLOBAL int Window_stack_attribute1[8];
///
/// The function ::Window_clicked_button() set this to ::LEFT_SIDE or ::RIGHT_SIDE
/// after a button is activated through left or right mouse click.
#define Window_attribute1 Window_stack_attribute1[Windows_open-1]
#define Window_attribute1 Window_stack[Windows_open-1].Attribute1
GFX2_GLOBAL int Window_stack_attribute2[8];
///
/// The function ::Window_clicked_button() set this to return extra information:
/// - When a scroller was clicked: the scroller position (0-n)
/// - When a palette was clicked: the color index (0-255)
/// - When a dropdown was used: the selected item's number T_Dropdown_choice::Number
#define Window_attribute2 Window_stack_attribute2[Windows_open-1]
#define Window_attribute2 Window_stack[Windows_open-1].Attribute2
#define Window_draggable Window_stack[Windows_open-1].Draggable
/// Definition of the menu (toolbox)

View File

@ -98,8 +98,12 @@ int Valid_character(int c)
void Display_whole_string(word x_pos,word y_pos,char * str,byte position)
{
Print_in_window(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
Print_char_in_window(x_pos+(position<<3),y_pos,str[position],CURSOR_COLOR,CURSOR_BACKGROUND_COLOR);
char cursor[2];
Print_general(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
cursor[0]=str[position] ? str[position] : ' ';
cursor[1]='\0';
Print_general(x_pos+(position<<3)*Menu_factor_X,y_pos,cursor,CURSOR_COLOR,CURSOR_BACKGROUND_COLOR);
}
/****************************************************************************
@ -143,6 +147,24 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
byte size;
word input_key=0;
byte is_authorized;
word window_x=Window_pos_X;
word window_y=Window_pos_Y;
// Virtual keyboard
byte use_virtual_keyboard=0;
static byte caps_lock=0;
word keymapping[] =
{
SDLK_CLEAR,SDLK_BACKSPACE,SDLK_RETURN,KEY_ESC,
'0','1','2','3','4','5','6','7','8','9','.',',',
'Q','W','E','R','T','Y','U','I','O','P',
'A','S','D','F','G','H','J','K','L',
SDLK_CAPSLOCK,'Z','X','C','V','B','N','M',' ',
'-','+','*','/','|','\\',
'(',')','{','}','[',']',
'_','=','<','>','%','@',
':',';','`','\'','"','~',
'!','?','^','&','#','$'
};
byte offset=0; // index du premier caractère affiché
@ -161,14 +183,100 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
// Nothing. The caller should have initialized a valid hexa number.
}
Wait_end_of_click();
// Virtual keyboards
if (input_type == INPUT_TYPE_STRING || input_type == INPUT_TYPE_FILENAME )
{
// Full keyboard
const int keyboard_width=320;
const int keyboard_height=87;
int h_pos;
int x,y;
h_pos= Window_pos_X+(keyboard_width-Window_width)/-2;
if (h_pos<0)
h_pos=0;
else if (h_pos+keyboard_width>Screen_width)
h_pos=Screen_width-keyboard_width;
use_virtual_keyboard=1;
Hide_cursor();
Open_popup(h_pos,Window_pos_Y+(y_pos+9)*Menu_factor_Y,keyboard_width,keyboard_height);
Window_rectangle(0,0,Window_width, Window_height-2, MC_Light);
Window_rectangle(2,Window_height-3,Window_width, 2, MC_Black);
// The order is important, see the array
Window_set_normal_button( 7,67,43,15,"Clr", 0,1,KEY_NONE);
Window_set_normal_button( 51,67,43,15,"Del", 0,1,KEY_NONE);
Window_set_normal_button( 95,67,43,15,"OK", 0,1,KEY_NONE);
Window_set_normal_button(139,67,43,15,"Esc", 0,1,KEY_NONE);
Window_display_frame_in(5,65,179,19);
Window_set_normal_button(193,63,17,19,"0", 0,1,KEY_NONE);
Window_set_normal_button(193,43,17,19,"1", 0,1,KEY_NONE);
Window_set_normal_button(211,43,17,19,"2", 0,1,KEY_NONE);
Window_set_normal_button(229,43,17,19,"3", 0,1,KEY_NONE);
Window_set_normal_button(193,23,17,19,"4", 0,1,KEY_NONE);
Window_set_normal_button(211,23,17,19,"5", 0,1,KEY_NONE);
Window_set_normal_button(229,23,17,19,"6", 0,1,KEY_NONE);
Window_set_normal_button(193, 3,17,19,"7", 0,1,KEY_NONE);
Window_set_normal_button(211, 3,17,19,"8", 0,1,KEY_NONE);
Window_set_normal_button(229, 3,17,19,"9", 0,1,KEY_NONE);
Window_set_normal_button(211,63,17,19,".", 0,1,KEY_NONE);
Window_set_normal_button(229,63,17,19,",", 0,1,KEY_NONE);
Window_set_normal_button( 3, 3,18,19,"Q", 0,1,KEY_NONE);
Window_set_normal_button( 22, 3,18,19,"W", 0,1,KEY_NONE);
Window_set_normal_button( 41, 3,18,19,"E", 0,1,KEY_NONE);
Window_set_normal_button( 60, 3,18,19,"R", 0,1,KEY_NONE);
Window_set_normal_button( 79, 3,18,19,"T", 0,1,KEY_NONE);
Window_set_normal_button( 98, 3,18,19,"Y", 0,1,KEY_NONE);
Window_set_normal_button(117, 3,18,19,"U", 0,1,KEY_NONE);
Window_set_normal_button(136, 3,18,19,"I", 0,1,KEY_NONE);
Window_set_normal_button(155, 3,18,19,"O", 0,1,KEY_NONE);
Window_set_normal_button(174, 3,18,19,"P", 0,1,KEY_NONE);
Window_set_normal_button( 12,23,18,19,"A", 0,1,KEY_NONE);
Window_set_normal_button( 31,23,18,19,"S", 0,1,KEY_NONE);
Window_set_normal_button( 50,23,18,19,"D", 0,1,KEY_NONE);
Window_set_normal_button( 69,23,18,19,"F", 0,1,KEY_NONE);
Window_set_normal_button( 88,23,18,19,"G", 0,1,KEY_NONE);
Window_set_normal_button(107,23,18,19,"H", 0,1,KEY_NONE);
Window_set_normal_button(126,23,18,19,"J", 0,1,KEY_NONE);
Window_set_normal_button(145,23,18,19,"K", 0,1,KEY_NONE);
Window_set_normal_button(164,23,18,19,"L", 0,1,KEY_NONE);
Window_set_normal_button( 3,43,18,19,caps_lock?"\036":"\037", 0,1,KEY_NONE);
Window_set_normal_button( 22,43,18,19,"Z", 0,1,KEY_NONE);
Window_set_normal_button( 41,43,18,19,"X", 0,1,KEY_NONE);
Window_set_normal_button( 60,43,18,19,"C", 0,1,KEY_NONE);
Window_set_normal_button( 79,43,18,19,"V", 0,1,KEY_NONE);
Window_set_normal_button( 98,43,18,19,"B", 0,1,KEY_NONE);
Window_set_normal_button(117,43,18,19,"N", 0,1,KEY_NONE);
Window_set_normal_button(136,43,18,19,"M", 0,1,KEY_NONE);
Window_set_normal_button(155,43,18,19," ", 0,1,KEY_NONE);
for (y=0; y<5; y++)
{
for (x=0; x<6; x++)
{
char label[2]=" ";
label[0]=keymapping[x+y*6+44];
Window_set_normal_button(247+x*12, 3+y*16,11,15,label, 0,1,KEY_NONE);
}
}
Update_window_area(0,0,Window_width, Window_height);
Display_cursor();
}
Keyboard_click_allowed = 0;
Hide_cursor();
// Effacement de la chaîne
Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
// Mise à jour des variables se rapportant à la chaîne en fonction de la chaîne initiale
@ -186,19 +294,56 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
if (visible_size + offset + 1 < size )
display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER;
Display_whole_string(x_pos,y_pos,display_string,position - offset);
Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
Flush_update();
while ((input_key!=SDLK_RETURN) && (input_key!=KEY_ESC) && Mouse_K == 0)
if (Mouse_K)
{
Display_cursor();
Wait_end_of_click();
Hide_cursor();
}
while ((input_key!=SDLK_RETURN) && (input_key!=KEY_ESC))
{
Display_cursor();
if (use_virtual_keyboard)
{
int clicked_button;
clicked_button=Window_clicked_button();
input_key=Key_ANSI;
if (clicked_button==-1)
input_key=SDLK_RETURN;
else if (clicked_button>0)
{
input_key=keymapping[clicked_button-1];
if (input_key==SDLK_CAPSLOCK)
{
// toggle uppercase
caps_lock=!caps_lock;
Hide_cursor();
Print_in_window(8, 49,caps_lock?"\036":"\037", MC_Black,MC_Light);
Display_cursor();
}
else if (input_key>='A' && input_key<='Z' && !caps_lock)
{
input_key+='a'-'A';
}
}
}
else
{
do
{
Get_input(20);
input_key=Key_ANSI;
} while(input_key==0 && Mouse_K == 0);
if (Mouse_K)
input_key=SDLK_RETURN;
} while(input_key==0);
}
Hide_cursor();
switch (input_key)
{
@ -209,7 +354,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
size--;
// Effacement de la chaîne
Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
goto affichage;
}
@ -219,7 +364,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
{
// Effacement de la chaîne
if (position==size)
Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
position--;
if (offset > 0 && (position == 0 || position < (offset + 1)))
@ -243,7 +388,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
{
// Effacement de la chaîne
if (position==size)
Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
position = 0;
offset = 0;
@ -269,11 +414,18 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
Remove_character(str,position);
size--;
// Effacement de la chaîne
Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
goto affichage;
}
break;
case SDLK_CLEAR : // Clear
str[0]='\0';
position=offset=0;
// Effacement de la chaîne
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
goto affichage;
case SDLK_RETURN :
break;
@ -349,17 +501,25 @@ affichage:
if (visible_size + offset + 0 < size )
display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER;
Display_whole_string(x_pos,y_pos,display_string,position - offset);
Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
} // End du "switch(input_key)"
Flush_update();
} // End du "while"
Keyboard_click_allowed = 1;
if (use_virtual_keyboard)
{
byte old_mouse_k = Mouse_K;
Close_popup();
Mouse_K=old_mouse_k;
Input_sticky_control=0;
}
// Effacement de la chaîne
Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
// On raffiche la chaine correctement
if (input_type==INPUT_TYPE_INTEGER)
@ -389,10 +549,10 @@ affichage:
{
Print_in_window_limited(x_pos,y_pos,str,visible_size,TEXT_COLOR,BACKGROUND_COLOR);
}
Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
return (input_key==SDLK_RETURN || Mouse_K != 0);
return (input_key==SDLK_RETURN);
}
void Sprint_double(char *str, double value, byte decimal_places, byte min_positions)

View File

@ -203,6 +203,25 @@ typedef struct T_List_button
struct T_List_button * Next; ///< Pointer to the next list button of current window.
} T_List_button;
/// A stackable window (editor screen)
typedef struct
{
word Pos_X;
word Pos_Y;
word Width;
word Height;
word Nb_buttons;
T_Normal_button *Normal_button_list;
T_Palette_button *Palette_button_list;
T_Scroller_button *Scroller_button_list;
T_Special_button *Special_button_list;
T_Dropdown_button *Dropdown_button_list;
T_List_button *List_button_list;
int Attribute1;
int Attribute2;
byte Draggable;
} T_Window;
/// Data for one line of the "Help" screens.
typedef struct {
char Line_type; ///< Kind of line: 'N' for normal line, 'S' for a bold line, 'K' for a line with keyboard shortcut, 'T' and '-' for upper and lower titles.