From 7f3fd42f770e6c1aa65bdf070c6365b2708f2813 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Wed, 17 Jun 2009 23:49:56 +0000 Subject: [PATCH] Started implementing generic 'List' controls. Currently in Text window, it's WIP, misses the initial display, no kb shortcuts, and untested with lists smaller than display area. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@878 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- buttons.c | 69 ++++++++++++++-------------- engine.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++--- engine.h | 1 + global.h | 5 ++ struct.h | 15 ++++++ 5 files changed, 184 insertions(+), 39 deletions(-) diff --git a/buttons.c b/buttons.c index 1493153c..b16f8687 100644 --- a/buttons.c +++ b/buttons.c @@ -5420,14 +5420,10 @@ void Button_Effects(void) Display_cursor(); } -// Affiche tout le selecteur de fontes -void Draw_font_selector(short x, short y, short list_start, short cursor_position, short nb_visibles) +// Callback to display a font name in the list +void Draw_one_font_name(word x, word y, word index, byte highlighted) { - int index; - for (index=0; index < nb_visibles; index++) - { - Print_in_window(x,y+index*8,Font_label(index+list_start), MC_Black, (cursor_position==index)?MC_Dark:MC_Light); - } + Print_in_window(x,y,Font_label(index), MC_Black, (highlighted)?MC_Dark:MC_Light); } void Button_Text() @@ -5437,6 +5433,7 @@ void Button_Text() static int antialias=1; static short list_start=0; // index de le premiere fonte dans le selector static short cursor_position=0; // index de la ligne active dans le selector + static short selected_font_index=0; static short is_bold=0; static short is_italic=0; @@ -5449,10 +5446,12 @@ void Button_Text() T_Special_button * input_size_button; T_Special_button * input_text_button; T_Special_button * preview_button; + T_Special_button * font_list_button; T_Scroller_button * font_scroller; + T_List_button * font_list; + byte redraw_is_needed=1; byte preview_is_needed=1; - short temp; Open_window(288,180,"Text"); @@ -5476,7 +5475,7 @@ void Button_Text() // Scroller des fontes font_scroller = Window_set_scroller_button(165,35,NB_FONTS*8,Nb_fonts,NB_FONTS,list_start); // 5 // Liste des fontes disponibles - Window_set_special_button(8,35,152,NB_FONTS*8); // 6 + font_list_button = Window_set_special_button(8,35,152,NB_FONTS*8); // 6 Window_display_frame_in(7, 33, 154, NB_FONTS*8+4); // Taille texte @@ -5490,6 +5489,13 @@ void Button_Text() Window_set_normal_button(8,160,40,14,"OK",0,1,SDLK_RETURN); // 11 Window_set_normal_button(54,160,60,14,"Cancel",0,1,KEY_ESC); // 12 + + // List of fonts + font_list = Window_set_list_button(font_list_button, font_scroller, Draw_one_font_name); // 13 + // Restore its settings from last passage in screen + font_list->List_start = list_start; + font_list->Cursor_position = cursor_position; + Update_window_area(0,0,Window_width, Window_height); // str texte @@ -5505,8 +5511,6 @@ void Button_Text() // Taille Num2str(font_size,size_buffer,3); Window_input_content(input_size_button,size_buffer); - // Selecteur de fonte - Draw_font_selector(8, 35, list_start, cursor_position, NB_FONTS); } if (preview_is_needed) { @@ -5518,7 +5522,7 @@ void Button_Text() free(new_brush); } Window_rectangle(8, 106, 273, 50,Back_color); - new_brush = Render_text(preview_string, cursor_position+list_start, font_size, antialias, is_bold, is_italic, &new_width, &new_height); + new_brush = Render_text(preview_string, selected_font_index, font_size, antialias, is_bold, is_italic, &new_width, &new_height); if (new_brush) { Display_brush( @@ -5547,7 +5551,7 @@ void Button_Text() clicked_button=Window_clicked_button(); if (clicked_button==0) - { + {/* if (Key==SDLK_UP && (cursor_position+list_start)>0) { Key=0; @@ -5687,6 +5691,7 @@ void Button_Text() font_scroller->Position=list_start; Window_draw_slider(font_scroller); } + */ if (Is_shortcut(Key,0x100+BUTTON_HELP)) Window_help(BUTTON_TEXT, NULL); } @@ -5719,29 +5724,19 @@ void Button_Text() break; case 5: // Scroller des fontes - if (list_start!=Window_attribute2) - { - cursor_position+=list_start; - list_start=Window_attribute2; - cursor_position-=list_start; - // On affiche à nouveau la liste - Hide_cursor(); - redraw_is_needed=1; - } + /* Cannot happen, event is catched by the list control */ break; case 6: // Selecteur de fonte - temp=(((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-35)>>3; - if (temp!=cursor_position && temp < Nb_fonts) - { - cursor_position=temp; - // On affiche à nouveau la liste - Hide_cursor(); - redraw_is_needed=1; - preview_is_needed=1; - } + /* Cannot happen, event is catched by the list control */ break; - + + case 13: // Font selection + selected_font_index = Window_attribute2; + Hide_cursor(); + preview_is_needed=1; + break; + case 7: // Taille du texte (nombre) Readline(222,45,size_buffer,3,1); font_size=atoi(size_buffer); @@ -5780,6 +5775,10 @@ void Button_Text() case 11: // OK + // Save the selector settings + list_start = font_list->List_start; + cursor_position = font_list->Cursor_position; + if (!new_brush) { // Si echec de rendu @@ -5803,7 +5802,7 @@ void Button_Text() // On passe en brosse: Display_cursor(); - if (antialias || !TrueType_font(cursor_position+list_start)) + if (antialias || !TrueType_font(selected_font_index)) Change_paintbrush_shape(PAINTBRUSH_SHAPE_COLOR_BRUSH); else Change_paintbrush_shape(PAINTBRUSH_SHAPE_MONO_BRUSH); @@ -5819,6 +5818,10 @@ void Button_Text() return; case 12: // Cancel + // Save the selector settings + list_start = font_list->List_start; + cursor_position = font_list->Cursor_position; + if (new_brush) free(new_brush); Close_window(); diff --git a/engine.c b/engine.c index 2a7f3546..240501b6 100644 --- a/engine.c +++ b/engine.c @@ -1178,6 +1178,7 @@ void Close_window(void) T_Scroller_button * temp3; T_Special_button * temp4; T_Dropdown_button * temp5; + T_List_button * temp6; Hide_cursor(); @@ -1212,6 +1213,12 @@ void Close_window(void) free(Window_dropdown_button_list); Window_dropdown_button_list=temp5; } + while (Window_list_button_list) + { + temp6=Window_list_button_list->Next; + free(Window_list_button_list); + Window_list_button_list=temp6; + } if (Windows_open != 1) { @@ -1659,6 +1666,29 @@ void Window_dropdown_clear_items(T_Dropdown_button * dropdown) } } +//----------------------- Create a List control ----------------------- +// These controls are special. They work over two controls previously created: +// - entry_button is the textual area where the list values will be printed. +// - scroller is a scroller button attached to it + +T_List_button * Window_set_list_button(T_Special_button * entry_button, T_Scroller_button * scroller, Func_draw_list_item draw_list_item) +{ + T_List_button *temp; + + temp=(T_List_button *)malloc(sizeof(T_List_button)); + temp->Number =++Window_nb_buttons; + temp->List_start = 0; + temp->Cursor_position = 0; + temp->Entry_button = entry_button; + temp->Scroller = scroller; + temp->Draw_list_item = draw_list_item; + + temp->Next=Window_list_button_list; + Window_list_button_list=temp; + return temp; +} + + //----------------------- Ouverture d'un pop-up ----------------------- void Open_popup(word x_pos, word y_pos, word width,word height) @@ -1722,7 +1752,8 @@ void Close_popup(void) T_Palette_button * temp2; T_Scroller_button * temp3; T_Special_button * temp4; - T_Dropdown_button * temp5; + T_Dropdown_button * temp5; + T_List_button * temp6; Hide_cursor(); @@ -1757,7 +1788,13 @@ void Close_popup(void) free(Window_dropdown_button_list); Window_dropdown_button_list=temp5; } - + while (Window_list_button_list) + { + temp6=Window_list_button_list->Next; + free(Window_list_button_list); + Window_list_button_list=temp6; + } + if (Windows_open != 1) { // Restore de ce que la fenêtre cachait @@ -2500,7 +2537,25 @@ short Window_get_button_shortcut(void) temp=temp->Next; } } - + + // Handle arrow keys, end/home, and mouse wheel that have + // a certain behavior if a list control is present. + if (Window_list_button_list) + { + T_List_button *list = Window_list_button_list; + // If there's more than one of such control, only capture + // events if the mouse cursor is over it. + if (list->Next) + { + // to do + } + + + + + + + } return 0; } @@ -2510,7 +2565,7 @@ short Window_clicked_button(void) if(!Get_input())SDL_Delay(20); - // Gestion des clicks + // Handle clicks if (Mouse_K) { if ((Mouse_XNext) + { + 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_positionScroller->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_positionScroller->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) + { + short i; + + // 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(); + for (i=Min(list->Scroller->Nb_visibles-1, list->Scroller->Nb_elements-1); i>=0; i--) + { + list->Draw_list_item( + list->Entry_button->Pos_X, + list->Entry_button->Pos_Y + i * 8, + list->List_start + i, + i == list->Cursor_position); + } + Display_cursor(); + } + } + return clicked_button; + } } } - // Gestion des touches + // Intercept keys if (Key) { Button=Window_get_button_shortcut(); diff --git a/engine.h b/engine.h index 43c639c9..d47b8675 100644 --- a/engine.h +++ b/engine.h @@ -71,6 +71,7 @@ T_Special_button * Window_set_input_button(word x_pos,word y_pos,word width_in_c T_Dropdown_button * Window_set_dropdown_button(word x_pos,word y_pos,word width,word height,word dropdown_width,const char *label,byte display_choice,byte display_centered,byte display_arrow,byte active_button); void Window_dropdown_add_item(T_Dropdown_button * dropdown, word btn_number, const char *label); void Window_dropdown_clear_items(T_Dropdown_button * dropdown); +T_List_button * Window_set_list_button(T_Special_button * entry_button, T_Scroller_button * scroller, Func_draw_list_item draw_list_item); byte Window_click_in_rectangle(short start_x,short start_y,short end_x,short end_y); short Wait_click_in_palette(T_Palette_button * button); void Get_color_behind_window(byte * color, byte * click); diff --git a/global.h b/global.h index 1e4b6150..3980a64b 100644 --- a/global.h +++ b/global.h @@ -527,6 +527,11 @@ 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] +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] + + GFX2_GLOBAL int Window_stack_attribute1[8]; /// diff --git a/struct.h b/struct.h index 1f98599c..879bf44d 100644 --- a/struct.h +++ b/struct.h @@ -61,6 +61,7 @@ typedef void (* Func_display_zoom) (word,word,word,byte *); typedef void (* Func_display_brush_color_zoom) (word,word,word,word,word,word,byte,word,byte *); typedef void (* Func_display_brush_mono_zoom) (word,word,word,word,word,word,byte,byte,word,byte *); typedef void (* Func_draw_brush) (byte *,word,word,word,word,word,word,byte,word); +typedef void (* Func_draw_list_item) (word,word,word,byte); /// A set of RGB values. typedef struct @@ -157,6 +158,20 @@ typedef struct T_Fileselector_item struct T_Fileselector_item * Previous;///< Pointer to previous item of the current fileselector. } T_Fileselector_item; +typedef struct T_List_button +{ + short Number; ///< Unique identifier for all controls + short List_start; ///< Index of the font to appear as first line + short Cursor_position; ///< Index of the selected line (0=top) + + T_Special_button * Entry_button; ///< Pointer to the associated selection control. + T_Scroller_button * Scroller; ///< Pointer to the associated scroller + + Func_draw_list_item Draw_list_item; ///< + + struct T_List_button * Next; ///< Pointer to the next list button of current window. +} T_List_button; + /// 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.