GUI: All controls are now 'sticky', ie. when you're dragging a slider/scroller and you move the mouse too far, it no longer activate other buttons. (Issue 191)

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@918 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2009-07-13 19:10:48 +00:00
parent 7bde7d90ce
commit 77728125fb
3 changed files with 151 additions and 62 deletions

194
engine.c
View File

@ -2334,6 +2334,59 @@ short Window_normal_button_onclick(word x_pos, word y_pos, word width, word heig
}
}
// Returns true if the mouse cursor sits inside the boundary of control.
short Window_click_in_control(short control)
{
T_Normal_button * temp1;
T_Palette_button * temp2;
T_Scroller_button * temp3;
T_Special_button * temp4;
T_Dropdown_button * temp5;
for (temp1=Window_normal_button_list; temp1; temp1=temp1->Next)
{
if (temp1->Number == control)
return Window_click_in_rectangle(temp1->Pos_X,temp1->Pos_Y,temp1->Pos_X+temp1->Width-1,temp1->Pos_Y+temp1->Height-1);
}
for (temp2=Window_palette_button_list; temp2; temp2=temp2->Next)
{
if (temp2->Number == control)
return Window_click_in_rectangle(temp2->Pos_X+5,temp2->Pos_Y+3,temp2->Pos_X+160,temp2->Pos_Y+82);
}
for (temp3=Window_scroller_button_list; temp3; temp3=temp3->Next)
{
if (temp3->Number == (control & 1023))
{
// top scroller arrow
if (control & 1024)
return Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y,temp3->Pos_X+10,temp3->Pos_Y+10);
// bottom scroller arrow
if (control & 2048)
return Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y+temp3->Height-11,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-1);
// middle slider
return Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y+12,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-13);
}
}
// Test du click sur une zone spéciale
for (temp4=Window_special_button_list; temp4; temp4=temp4->Next)
{
if (temp4->Number == control)
return Window_click_in_rectangle(temp4->Pos_X,temp4->Pos_Y,temp4->Pos_X+temp4->Width-1,temp4->Pos_Y+temp4->Height-1);
}
// Test du click sur une dropdown
for (temp5=Window_dropdown_button_list; temp5; temp5=temp5->Next)
{
if (temp5->Number == control)
return Window_click_in_rectangle(temp5->Pos_X,temp5->Pos_Y,temp5->Pos_X+temp5->Width-1,temp5->Pos_Y+temp5->Height-1);
}
return 0;
}
// --- Renvoie le numéro du bouton clicke (-1:hors de la fenêtre, 0:aucun) ---
short Window_get_clicked_button(void)
{
@ -2352,6 +2405,7 @@ short Window_get_clicked_button(void)
{
if (Window_click_in_rectangle(temp1->Pos_X,temp1->Pos_Y,temp1->Pos_X+temp1->Width-1,temp1->Pos_Y+temp1->Height-1))
{
Input_sticky_control = temp1->Number;
if (temp1->Repeatable)
{
Hide_cursor();
@ -2372,6 +2426,7 @@ short Window_get_clicked_button(void)
{
if (Window_click_in_rectangle(temp2->Pos_X+5,temp2->Pos_Y+3,temp2->Pos_X+160,temp2->Pos_Y+82))
{
Input_sticky_control = temp2->Number;
// On stocke dans Attribut2 le numero de couleur cliqué
Window_attribute2 = (((Mouse_X-Window_pos_X)/Menu_factor_X)-(temp2->Pos_X+2)) / 10 * 16 +
(((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-(temp2->Pos_Y+3)) / 5;
@ -2387,6 +2442,7 @@ short Window_get_clicked_button(void)
// Button flèche Haut
if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y,temp3->Pos_X+10,temp3->Pos_Y+10))
{
Input_sticky_control = temp3->Number | 1024;
Hide_cursor();
Window_select_normal_button(temp3->Pos_X,temp3->Pos_Y,11,11);
@ -2412,6 +2468,7 @@ short Window_get_clicked_button(void)
// Button flèche Bas
if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y+temp3->Height-11,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-1))
{
Input_sticky_control = temp3->Number | 2048;
Hide_cursor();
Window_select_normal_button(temp3->Pos_X,temp3->Pos_Y+temp3->Height-11,11,11);
@ -2437,6 +2494,7 @@ short Window_get_clicked_button(void)
// Jauge
if (Window_click_in_rectangle(temp3->Pos_X,temp3->Pos_Y+12,temp3->Pos_X+10,temp3->Pos_Y+temp3->Height-13))
{
Input_sticky_control = temp3->Number;
if (temp3->Nb_elements>temp3->Nb_visibles)
{
// S'il y a la place de faire scroller le curseur:
@ -2488,7 +2546,10 @@ short Window_get_clicked_button(void)
for (temp4=Window_special_button_list; temp4; temp4=temp4->Next)
{
if (Window_click_in_rectangle(temp4->Pos_X,temp4->Pos_Y,temp4->Pos_X+temp4->Width-1,temp4->Pos_Y+temp4->Height-1))
return temp4->Number;
{
Input_sticky_control = temp4->Number;
return temp4->Number;
}
}
// Test du click sur une dropdown
@ -2496,6 +2557,7 @@ short Window_get_clicked_button(void)
{
if (Window_click_in_rectangle(temp5->Pos_X,temp5->Pos_Y,temp5->Pos_X+temp5->Width-1,temp5->Pos_Y+temp5->Height-1))
{
Input_sticky_control = temp5->Number;
if (Mouse_K & temp5->Active_button)
return Window_dropdown_on_click(temp5);
else
@ -2587,71 +2649,81 @@ short Window_clicked_button(void)
if ((Mouse_X<Window_pos_X) || (Mouse_Y<Window_pos_Y)
|| (Mouse_X>=Window_pos_X+(Window_width*Menu_factor_X))
|| (Mouse_Y>=Window_pos_Y+(Window_height*Menu_factor_Y)))
return -1;
else
{
if (Mouse_Y < Window_pos_Y+(12*Menu_factor_Y))
Move_window(Mouse_X-Window_pos_X,Mouse_Y-Window_pos_Y);
if (Input_sticky_control == 0 || Input_sticky_control == -1)
{
Input_sticky_control = -1;
return -1;
}
else
{
short clicked_button;
T_List_button * list;
// Check which controls was clicked (by rectangular area)
clicked_button = Window_get_clicked_button();
// Check if it's part of a list control
for (list=Window_list_button_list; list!=NULL; list=list->Next)
{
if (list->Entry_button->Number == clicked_button)
{
// Click in the textual part of a list.
short clicked_line;
clicked_line = (((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-list->Entry_button->Pos_Y)>>3;
if (clicked_line == list->Cursor_position || // Same as before
clicked_line >= list->Scroller->Nb_elements) // Below last line
return 0;
Hide_cursor();
// Redraw one item as disabled
if (list->Cursor_position>=0 && list->Cursor_position<list->Scroller->Nb_visibles)
list->Draw_list_item(
list->Entry_button->Pos_X,
list->Entry_button->Pos_Y + list->Cursor_position * 8,
list->List_start + list->Cursor_position,
0);
list->Cursor_position = clicked_line;
// Redraw one item as enabled
if (list->Cursor_position>=0 && list->Cursor_position<list->Scroller->Nb_visibles)
list->Draw_list_item(
list->Entry_button->Pos_X,
list->Entry_button->Pos_Y + list->Cursor_position * 8,
list->List_start + list->Cursor_position,
1);
Display_cursor();
// Store the selected value as attribute2
Window_attribute2=list->List_start + list->Cursor_position;
// Return the control ID of the list.
return list->Number;
}
else if (list->Scroller->Number == clicked_button)
{
// Click in the scroller part of a list
if (list->List_start == list->Scroller->Position)
return 0; // Didn't actually move
// Update scroller indices
list->Cursor_position += list->List_start;
list->List_start = list->Scroller->Position;
list->Cursor_position -= list->List_start;
// Need to redraw all
Hide_cursor();
Window_redraw_list(list);
Display_cursor();
}
}
return clicked_button;
return 0;
}
}
if (Mouse_Y < Window_pos_Y+(12*Menu_factor_Y))
{
Move_window(Mouse_X-Window_pos_X,Mouse_Y-Window_pos_Y);
}
else
{
short clicked_button;
T_List_button * list;
// Check which controls was clicked (by rectangular area)
clicked_button = Window_get_clicked_button();
// Check if it's part of a list control
for (list=Window_list_button_list; list!=NULL; list=list->Next)
{
if (list->Entry_button->Number == clicked_button)
{
// Click in the textual part of a list.
short clicked_line;
clicked_line = (((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-list->Entry_button->Pos_Y)>>3;
if (clicked_line == list->Cursor_position || // Same as before
clicked_line >= list->Scroller->Nb_elements) // Below last line
return 0;
Hide_cursor();
// Redraw one item as disabled
if (list->Cursor_position>=0 && list->Cursor_position<list->Scroller->Nb_visibles)
list->Draw_list_item(
list->Entry_button->Pos_X,
list->Entry_button->Pos_Y + list->Cursor_position * 8,
list->List_start + list->Cursor_position,
0);
list->Cursor_position = clicked_line;
// Redraw one item as enabled
if (list->Cursor_position>=0 && list->Cursor_position<list->Scroller->Nb_visibles)
list->Draw_list_item(
list->Entry_button->Pos_X,
list->Entry_button->Pos_Y + list->Cursor_position * 8,
list->List_start + list->Cursor_position,
1);
Display_cursor();
// Store the selected value as attribute2
Window_attribute2=list->List_start + list->Cursor_position;
// Return the control ID of the list.
return ((Input_sticky_control = list->Number));
}
else if (list->Scroller->Number == clicked_button)
{
// Click in the scroller part of a list
if (list->List_start == list->Scroller->Position)
return 0; // Didn't actually move
// Update scroller indices
list->Cursor_position += list->List_start;
list->List_start = list->Scroller->Position;
list->Cursor_position -= list->List_start;
// Need to redraw all
Hide_cursor();
Window_redraw_list(list);
Display_cursor();
}
}
return clicked_button;
}
}
// Intercept keys

12
input.c
View File

@ -31,6 +31,8 @@
void Handle_window_resize(SDL_ResizeEvent event);
void Handle_window_exit(SDL_QuitEvent event);
int Input_sticky_control = 0;
byte Directional_up;
byte Directional_up_right;
byte Directional_right;
@ -155,8 +157,14 @@ int Move_cursor_with_constraints()
(Input_new_mouse_Y != Mouse_Y) ||
(Input_new_mouse_K != Mouse_K))
{
// On every change of mouse state
if ((Input_new_mouse_K != Mouse_K))
feedback=1;
{
feedback=1;
if (Input_new_mouse_K == 0)
Input_sticky_control = 0;
}
Hide_cursor(); // On efface le curseur AVANT de le déplacer...
if (Input_new_mouse_X != Mouse_X || Input_new_mouse_Y != Mouse_Y)
{
@ -298,6 +306,8 @@ int Handle_mouse_release(SDL_MouseButtonEvent event)
Input_new_mouse_K &= ~2;
break;
}
Input_sticky_control = -1;
return Move_cursor_with_constraints();
}

View File

@ -40,3 +40,10 @@ int Is_shortcut(word Key, word function);
void Adjust_mouse_sensitivity(word fullscreen);
void Set_mouse_position(void);
///
/// This holds the ID of the GUI control that the mouse
/// is manipulating. The input system will reset it to zero
/// when mouse button is released, but it's the engine
/// that will record and retrieve a real control ID.
extern int Input_sticky_control;