diff --git a/4coder_API/types.h b/4coder_API/types.h index a4efffda..86c8879e 100644 --- a/4coder_API/types.h +++ b/4coder_API/types.h @@ -685,8 +685,6 @@ STRUCT View_Summary{ GUI_Scroll_Vars scroll_vars; }; -GLOBAL_VAR View_Summary null_view_summary = {0}; - /* DOC(Query_Bar is a struct used to store information in the user's control that will be displayed as a drop down bar durring an interactive command.) */ STRUCT Query_Bar{ @@ -703,6 +701,44 @@ STRUCT Event_Message{ int32_t type; }; +ENUM(int32_t, UI_Item_Type){ + UIType_Option, + UIType_TextField, +}; + +ENUM(int32_t, UI_Activation_Level){ + UIActivation_None, + UIActivation_Hover, + UIActivation_Active, +}; + +STRUCT UI_Item{ + UI_Item_Type type; + String query; + String string; + String status; + void *user_data; + UI_Activation_Level activation_level; + i32_Rect rectangle; +}; + +STRUCT UI_Item_Node{ + UI_Item_Node *next; + UI_Item_Node *prev; + UI_Item fixed; +}; + +STRUCT UI_List{ + UI_Item_Node *first; + UI_Item_Node *last; + int32_t count; +}; + +STRUCT UI_Control{ + UI_Item *items; + int32_t count; +}; + /* DOC(Theme_Color stores a style tag/color pair, for the purpose of setting and getting colors in the theme.) DOC_SEE(Style_Tag) diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp index 4f8e0b35..c0b876ae 100644 --- a/4coder_base_commands.cpp +++ b/4coder_base_commands.cpp @@ -1497,17 +1497,16 @@ CUSTOM_DOC("Opens the 4coder colors and fonts selector menu.") //////////////////////////////// -#if 0 CUSTOM_COMMAND_SIG(interactive_switch_buffer_DUMMY_API_EXPLORATION) CUSTOM_DOC("Interactively switch to an open buffer.") { Partition *scratch = &global_part; View_Summary view = get_active_view(app, AccessAll); - view_start_list_mode(app, &view); + view_start_ui_mode(app, &view); int32_t x0 = 0; int32_t x1 = view.view_region.x1 - view.view_region.x0; - int32_t line_height = view.line_height; + int32_t line_height = (int32_t)view.line_height; int32_t block_height = line_height*2; Temp_Memory temp = begin_temp_memory(scratch); @@ -1518,13 +1517,13 @@ CUSTOM_DOC("Interactively switch to an open buffer.") int32_t y_pos = line_height; - List_Control list = {0}; - List_Item *highlighted_item = 0; + UI_List list = {0}; + UI_Item *highlighted_item = 0; for (Buffer_Summary buffer = get_buffer_first(app, AccessAll); buffer.exists; get_buffer_next(app, &buffer, AccessAll)){ String buffer_name = make_string(buffer.buffer_name, buffer.buffer_name_len); - if (has_substr(buffer_name, text_field)){ + if (text_field.size == 0 || has_substr(buffer_name, text_field)){ i32_Rect item_rect = {0}; item_rect.x0 = x0; item_rect.y0 = y_pos; @@ -1532,23 +1531,25 @@ CUSTOM_DOC("Interactively switch to an open buffer.") item_rect.y1 = y_pos + block_height; y_pos = item_rect.y1; - List_Item *item = push_array(scratch, List_Item, 1); - memset(item, 0, sizeof(*item)); - item->type = ListItemType_Option; - item->string = push_string_copy(scratch, buffer_name); + UI_Item item = {0}; + item.type = UIType_Option; + item.string = push_string_copy(scratch, buffer_name); char *status = ""; switch (buffer.dirty){ case DirtyState_UnsavedChanges: status = " *"; break; case DirtyState_UnloadedChanges: status = " !"; break; } - item->status = push_string_copy(scratch, status); - item->user_data = (void*)buffer.buffer_id; - item->highlighted = false; - item->rectangle = item_rect; - - list_control_add_item(&list, item); + item.status = push_string_copy(scratch, status); + item.user_data = (void*)buffer.buffer_id; + item.activation_level = UIActivation_None; + item.rectangle = item_rect; if (highlighted_item == 0){ - highlighted_item = item; + item.activation_level = UIActivation_Hover; + UI_Item *item_ptr = ui_list_add_item(scratch, &list, item); + highlighted_item = item_ptr; + } + else{ + ui_list_add_item(scratch, &list, item); } } } @@ -1561,23 +1562,24 @@ CUSTOM_DOC("Interactively switch to an open buffer.") item_rect.y1 = line_height; y_pos = item_rect.y1; - List_Item *item = push_array(scratch, List_Item, 1); - memset(item, 0, sizeof(*item)); - item->type = ListItemType_TextField; - item->query = push_string_copy(scratch, "Switch: "); - item->string = text_field; - item->user_data = 0; - item->rectangle = item_rect; + UI_Item item = {0}; + item.type = UIType_TextField; + item.query = push_string_copy(scratch, "Switch: "); + item.string = text_field; + item.user_data = 0; + item.rectangle = item_rect; + ui_list_add_item(scratch, &list, item); } - view_set_list(app, &view, &list); + UI_Control control = ui_list_to_ui_control(scratch, &list); + view_set_ui(app, &view, &control); User_Input in = get_user_input(app, EventAll, EventOnEsc); if (in.abort){ goto done; } - List_Item *activated_item = 0; + UI_Item *activated_item = 0; switch (in.type){ case UserInputKey: { @@ -1601,7 +1603,7 @@ CUSTOM_DOC("Interactively switch to an open buffer.") if (in.mouse.press_l){ int32_t mx = in.mouse.x - view.view_region.x0; int32_t my = in.mouse.y - view.view_region.y0; - activated_item = list_control_get_mouse_hit(&list, mx, my); + activated_item = ui_control_get_mouse_hit(&control, mx, my); } }break; } @@ -1614,10 +1616,9 @@ CUSTOM_DOC("Interactively switch to an open buffer.") } done:; - view_end_list_mode(app, &view); + view_end_ui_mode(app, &view); end_temp_memory(temp); } -#endif //////////////////////////////// diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index 623649fe..e0974b16 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -37,6 +37,7 @@ #include "4coder_default_framework_variables.cpp" #include "4coder_buffer_seek_constructors.cpp" +#include "4coder_ui_helper.cpp" #include "4coder_helper.cpp" #include "4coder_font_helper.cpp" #include "4coder_config.cpp" diff --git a/4coder_generated/app_functions.h b/4coder_generated/app_functions.h index 37fce504..61783cdd 100644 --- a/4coder_generated/app_functions.h +++ b/4coder_generated/app_functions.h @@ -52,6 +52,9 @@ struct Application_Links; #define CREATE_VIEW_VARIABLE_SIG(n) int32_t n(Application_Links *app, char *null_terminated_name, uint64_t default_value) #define VIEW_SET_VARIABLE_SIG(n) bool32 n(Application_Links *app, View_Summary *view, int32_t location, uint64_t value) #define VIEW_GET_VARIABLE_SIG(n) bool32 n(Application_Links *app, View_Summary *view, int32_t location, uint64_t *value_out) +#define VIEW_START_UI_MODE_SIG(n) int32_t n(Application_Links *app, View_Summary *view) +#define VIEW_END_UI_MODE_SIG(n) int32_t n(Application_Links *app, View_Summary *view) +#define VIEW_SET_UI_SIG(n) bool32 n(Application_Links *app, View_Summary *view, UI_Control *control) #define GET_USER_INPUT_SIG(n) User_Input n(Application_Links *app, Input_Type_Flag get_type, Input_Type_Flag abort_type) #define GET_COMMAND_INPUT_SIG(n) User_Input n(Application_Links *app) #define GET_MOUSE_STATE_SIG(n) Mouse_State n(Application_Links *app) @@ -141,6 +144,9 @@ typedef VIEW_POST_FADE_SIG(View_Post_Fade_Function); typedef CREATE_VIEW_VARIABLE_SIG(Create_View_Variable_Function); typedef VIEW_SET_VARIABLE_SIG(View_Set_Variable_Function); typedef VIEW_GET_VARIABLE_SIG(View_Get_Variable_Function); +typedef VIEW_START_UI_MODE_SIG(View_Start_UI_Mode_Function); +typedef VIEW_END_UI_MODE_SIG(View_End_UI_Mode_Function); +typedef VIEW_SET_UI_SIG(View_Set_UI_Function); typedef GET_USER_INPUT_SIG(Get_User_Input_Function); typedef GET_COMMAND_INPUT_SIG(Get_Command_Input_Function); typedef GET_MOUSE_STATE_SIG(Get_Mouse_State_Function); @@ -232,6 +238,9 @@ View_Post_Fade_Function *view_post_fade; Create_View_Variable_Function *create_view_variable; View_Set_Variable_Function *view_set_variable; View_Get_Variable_Function *view_get_variable; +View_Start_UI_Mode_Function *view_start_ui_mode; +View_End_UI_Mode_Function *view_end_ui_mode; +View_Set_UI_Function *view_set_ui; Get_User_Input_Function *get_user_input; Get_Command_Input_Function *get_command_input; Get_Mouse_State_Function *get_mouse_state; @@ -322,6 +331,9 @@ View_Post_Fade_Function *view_post_fade_; Create_View_Variable_Function *create_view_variable_; View_Set_Variable_Function *view_set_variable_; View_Get_Variable_Function *view_get_variable_; +View_Start_UI_Mode_Function *view_start_ui_mode_; +View_End_UI_Mode_Function *view_end_ui_mode_; +View_Set_UI_Function *view_set_ui_; Get_User_Input_Function *get_user_input_; Get_Command_Input_Function *get_command_input_; Get_Mouse_State_Function *get_mouse_state_; @@ -420,6 +432,9 @@ app_links->view_post_fade_ = View_Post_Fade;\ app_links->create_view_variable_ = Create_View_Variable;\ app_links->view_set_variable_ = View_Set_Variable;\ app_links->view_get_variable_ = View_Get_Variable;\ +app_links->view_start_ui_mode_ = View_Start_UI_Mode;\ +app_links->view_end_ui_mode_ = View_End_UI_Mode;\ +app_links->view_set_ui_ = View_Set_UI;\ app_links->get_user_input_ = Get_User_Input;\ app_links->get_command_input_ = Get_Command_Input;\ app_links->get_mouse_state_ = Get_Mouse_State;\ @@ -510,6 +525,9 @@ static inline bool32 view_post_fade(Application_Links *app, View_Summary *view, static inline int32_t create_view_variable(Application_Links *app, char *null_terminated_name, uint64_t default_value){return(app->create_view_variable(app, null_terminated_name, default_value));} static inline bool32 view_set_variable(Application_Links *app, View_Summary *view, int32_t location, uint64_t value){return(app->view_set_variable(app, view, location, value));} static inline bool32 view_get_variable(Application_Links *app, View_Summary *view, int32_t location, uint64_t *value_out){return(app->view_get_variable(app, view, location, value_out));} +static inline int32_t view_start_ui_mode(Application_Links *app, View_Summary *view){return(app->view_start_ui_mode(app, view));} +static inline int32_t view_end_ui_mode(Application_Links *app, View_Summary *view){return(app->view_end_ui_mode(app, view));} +static inline bool32 view_set_ui(Application_Links *app, View_Summary *view, UI_Control *control){return(app->view_set_ui(app, view, control));} static inline User_Input get_user_input(Application_Links *app, Input_Type_Flag get_type, Input_Type_Flag abort_type){return(app->get_user_input(app, get_type, abort_type));} static inline User_Input get_command_input(Application_Links *app){return(app->get_command_input(app));} static inline Mouse_State get_mouse_state(Application_Links *app){return(app->get_mouse_state(app));} @@ -600,6 +618,9 @@ static inline bool32 view_post_fade(Application_Links *app, View_Summary *view, static inline int32_t create_view_variable(Application_Links *app, char *null_terminated_name, uint64_t default_value){return(app->create_view_variable_(app, null_terminated_name, default_value));} static inline bool32 view_set_variable(Application_Links *app, View_Summary *view, int32_t location, uint64_t value){return(app->view_set_variable_(app, view, location, value));} static inline bool32 view_get_variable(Application_Links *app, View_Summary *view, int32_t location, uint64_t *value_out){return(app->view_get_variable_(app, view, location, value_out));} +static inline int32_t view_start_ui_mode(Application_Links *app, View_Summary *view){return(app->view_start_ui_mode_(app, view));} +static inline int32_t view_end_ui_mode(Application_Links *app, View_Summary *view){return(app->view_end_ui_mode_(app, view));} +static inline bool32 view_set_ui(Application_Links *app, View_Summary *view, UI_Control *control){return(app->view_set_ui_(app, view, control));} static inline User_Input get_user_input(Application_Links *app, Input_Type_Flag get_type, Input_Type_Flag abort_type){return(app->get_user_input_(app, get_type, abort_type));} static inline User_Input get_command_input(Application_Links *app){return(app->get_command_input_(app));} static inline Mouse_State get_mouse_state(Application_Links *app){return(app->get_mouse_state_(app));} diff --git a/4coder_generated/command_metadata.h b/4coder_generated/command_metadata.h index 4153f37e..2635b215 100644 --- a/4coder_generated/command_metadata.h +++ b/4coder_generated/command_metadata.h @@ -2,7 +2,7 @@ #define command_id(c) (fcoder_metacmd_ID_##c) #define command_metadata(c) (&fcoder_metacmd_table[command_id(c)]) #define command_metadata_by_id(id) (&fcoder_metacmd_table[id]) -#define command_one_past_last_id 184 +#define command_one_past_last_id 185 #if defined(CUSTOM_COMMAND_SIG) #define PROC_LINKS(x,y) x #else @@ -77,6 +77,7 @@ CUSTOM_COMMAND_SIG(interactive_new); CUSTOM_COMMAND_SIG(interactive_open); CUSTOM_COMMAND_SIG(interactive_open_or_new); CUSTOM_COMMAND_SIG(interactive_switch_buffer); +CUSTOM_COMMAND_SIG(interactive_switch_buffer_DUMMY_API_EXPLORATION); CUSTOM_COMMAND_SIG(kill_buffer); CUSTOM_COMMAND_SIG(left_adjust_view); CUSTOM_COMMAND_SIG(list_all_functions_current_buffer); @@ -204,7 +205,7 @@ char *source_name; int32_t source_name_len; int32_t line_number; }; -static Command_Metadata fcoder_metacmd_table[184] = { +static Command_Metadata fcoder_metacmd_table[185] = { { PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\4coder_default_framework.cpp", 43, 191 }, { PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 37, 722 }, { PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 37, 733 }, @@ -273,6 +274,7 @@ static Command_Metadata fcoder_metacmd_table[184] = { { PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1450 }, { PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1456 }, { PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1462 }, +{ PROC_LINKS(interactive_switch_buffer_DUMMY_API_EXPLORATION, 0), "interactive_switch_buffer_DUMMY_API_EXPLORATION", 47, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1500 }, { PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1486 }, { PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 135 }, { PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\4coder_function_list.cpp", 39, 318 }, @@ -305,7 +307,7 @@ static Command_Metadata fcoder_metacmd_table[184] = { { PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 42, 1062 }, { PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1492 }, { PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1339 }, -{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1624 }, +{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 1625 }, { PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 49, 58 }, { PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 49, 74 }, { PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 49, 66 }, @@ -458,120 +460,121 @@ static int32_t fcoder_metacmd_ID_interactive_new = 64; static int32_t fcoder_metacmd_ID_interactive_open = 65; static int32_t fcoder_metacmd_ID_interactive_open_or_new = 66; static int32_t fcoder_metacmd_ID_interactive_switch_buffer = 67; -static int32_t fcoder_metacmd_ID_kill_buffer = 68; -static int32_t fcoder_metacmd_ID_left_adjust_view = 69; -static int32_t fcoder_metacmd_ID_list_all_functions_current_buffer = 70; -static int32_t fcoder_metacmd_ID_list_all_locations = 71; -static int32_t fcoder_metacmd_ID_list_all_locations_case_insensitive = 72; -static int32_t fcoder_metacmd_ID_list_all_locations_of_identifier = 73; -static int32_t fcoder_metacmd_ID_list_all_locations_of_identifier_case_insensitive = 74; -static int32_t fcoder_metacmd_ID_list_all_locations_of_selection = 75; -static int32_t fcoder_metacmd_ID_list_all_locations_of_selection_case_insensitive = 76; -static int32_t fcoder_metacmd_ID_list_all_locations_of_type_definition = 77; -static int32_t fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier = 78; -static int32_t fcoder_metacmd_ID_list_all_substring_locations = 79; -static int32_t fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 80; -static int32_t fcoder_metacmd_ID_load_project = 81; -static int32_t fcoder_metacmd_ID_make_directory_query = 82; -static int32_t fcoder_metacmd_ID_move_down = 83; -static int32_t fcoder_metacmd_ID_move_down_10 = 84; -static int32_t fcoder_metacmd_ID_move_down_textual = 85; -static int32_t fcoder_metacmd_ID_move_left = 86; -static int32_t fcoder_metacmd_ID_move_line_down = 87; -static int32_t fcoder_metacmd_ID_move_line_up = 88; -static int32_t fcoder_metacmd_ID_move_right = 89; -static int32_t fcoder_metacmd_ID_move_up = 90; -static int32_t fcoder_metacmd_ID_move_up_10 = 91; -static int32_t fcoder_metacmd_ID_newline_or_goto_position_direct = 92; -static int32_t fcoder_metacmd_ID_newline_or_goto_position_same_panel_direct = 93; -static int32_t fcoder_metacmd_ID_newline_or_goto_position_same_panel_sticky = 94; -static int32_t fcoder_metacmd_ID_newline_or_goto_position_sticky = 95; -static int32_t fcoder_metacmd_ID_open_all_code = 96; -static int32_t fcoder_metacmd_ID_open_all_code_recursive = 97; -static int32_t fcoder_metacmd_ID_open_color_tweaker = 98; -static int32_t fcoder_metacmd_ID_open_file_in_quotes = 99; -static int32_t fcoder_metacmd_ID_open_in_other = 100; -static int32_t fcoder_metacmd_ID_open_long_braces = 101; -static int32_t fcoder_metacmd_ID_open_long_braces_break = 102; -static int32_t fcoder_metacmd_ID_open_long_braces_semicolon = 103; -static int32_t fcoder_metacmd_ID_open_matching_file_cpp = 104; -static int32_t fcoder_metacmd_ID_open_panel_hsplit = 105; -static int32_t fcoder_metacmd_ID_open_panel_vsplit = 106; -static int32_t fcoder_metacmd_ID_page_down = 107; -static int32_t fcoder_metacmd_ID_page_up = 108; -static int32_t fcoder_metacmd_ID_paste = 109; -static int32_t fcoder_metacmd_ID_paste_and_indent = 110; -static int32_t fcoder_metacmd_ID_paste_next = 111; -static int32_t fcoder_metacmd_ID_paste_next_and_indent = 112; -static int32_t fcoder_metacmd_ID_place_in_scope = 113; -static int32_t fcoder_metacmd_ID_project_fkey_command = 114; -static int32_t fcoder_metacmd_ID_project_go_to_root_directory = 115; -static int32_t fcoder_metacmd_ID_query_replace = 116; -static int32_t fcoder_metacmd_ID_query_replace_identifier = 117; -static int32_t fcoder_metacmd_ID_query_replace_selection = 118; -static int32_t fcoder_metacmd_ID_redo = 119; -static int32_t fcoder_metacmd_ID_remap_interactive = 120; -static int32_t fcoder_metacmd_ID_rename_file_query = 121; -static int32_t fcoder_metacmd_ID_reopen = 122; -static int32_t fcoder_metacmd_ID_replace_in_range = 123; -static int32_t fcoder_metacmd_ID_reverse_search = 124; -static int32_t fcoder_metacmd_ID_reverse_search_identifier = 125; -static int32_t fcoder_metacmd_ID_save = 126; -static int32_t fcoder_metacmd_ID_save_all_dirty_buffers = 127; -static int32_t fcoder_metacmd_ID_save_to_query = 128; -static int32_t fcoder_metacmd_ID_scope_absorb_down = 129; -static int32_t fcoder_metacmd_ID_search = 130; -static int32_t fcoder_metacmd_ID_search_identifier = 131; -static int32_t fcoder_metacmd_ID_seek_alphanumeric_left = 132; -static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_left = 133; -static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_right = 134; -static int32_t fcoder_metacmd_ID_seek_alphanumeric_right = 135; -static int32_t fcoder_metacmd_ID_seek_beginning_of_line = 136; -static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 137; -static int32_t fcoder_metacmd_ID_seek_end_of_line = 138; -static int32_t fcoder_metacmd_ID_seek_end_of_textual_line = 139; -static int32_t fcoder_metacmd_ID_seek_token_left = 140; -static int32_t fcoder_metacmd_ID_seek_token_right = 141; -static int32_t fcoder_metacmd_ID_seek_white_or_token_left = 142; -static int32_t fcoder_metacmd_ID_seek_white_or_token_right = 143; -static int32_t fcoder_metacmd_ID_seek_whitespace_down = 144; -static int32_t fcoder_metacmd_ID_seek_whitespace_down_end_line = 145; -static int32_t fcoder_metacmd_ID_seek_whitespace_left = 146; -static int32_t fcoder_metacmd_ID_seek_whitespace_right = 147; -static int32_t fcoder_metacmd_ID_seek_whitespace_up = 148; -static int32_t fcoder_metacmd_ID_seek_whitespace_up_end_line = 149; -static int32_t fcoder_metacmd_ID_select_all = 150; -static int32_t fcoder_metacmd_ID_set_bindings_choose = 151; -static int32_t fcoder_metacmd_ID_set_bindings_default = 152; -static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 153; -static int32_t fcoder_metacmd_ID_set_mark = 154; -static int32_t fcoder_metacmd_ID_setup_build_bat = 155; -static int32_t fcoder_metacmd_ID_setup_build_bat_and_sh = 156; -static int32_t fcoder_metacmd_ID_setup_build_sh = 157; -static int32_t fcoder_metacmd_ID_setup_new_project = 158; -static int32_t fcoder_metacmd_ID_show_filebar = 159; -static int32_t fcoder_metacmd_ID_show_scrollbar = 160; -static int32_t fcoder_metacmd_ID_snipe_token_or_word = 161; -static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 162; -static int32_t fcoder_metacmd_ID_suppress_mouse = 163; -static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 164; -static int32_t fcoder_metacmd_ID_to_lowercase = 165; -static int32_t fcoder_metacmd_ID_to_uppercase = 166; -static int32_t fcoder_metacmd_ID_toggle_filebar = 167; -static int32_t fcoder_metacmd_ID_toggle_fullscreen = 168; -static int32_t fcoder_metacmd_ID_toggle_line_wrap = 169; -static int32_t fcoder_metacmd_ID_toggle_mouse = 170; -static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 171; -static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 172; -static int32_t fcoder_metacmd_ID_undo = 173; -static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 174; -static int32_t fcoder_metacmd_ID_word_complete = 175; -static int32_t fcoder_metacmd_ID_write_and_auto_tab = 176; -static int32_t fcoder_metacmd_ID_write_block = 177; -static int32_t fcoder_metacmd_ID_write_character = 178; -static int32_t fcoder_metacmd_ID_write_hack = 179; -static int32_t fcoder_metacmd_ID_write_note = 180; -static int32_t fcoder_metacmd_ID_write_todo = 181; -static int32_t fcoder_metacmd_ID_write_underscore = 182; -static int32_t fcoder_metacmd_ID_write_zero_struct = 183; +static int32_t fcoder_metacmd_ID_interactive_switch_buffer_DUMMY_API_EXPLORATION = 68; +static int32_t fcoder_metacmd_ID_kill_buffer = 69; +static int32_t fcoder_metacmd_ID_left_adjust_view = 70; +static int32_t fcoder_metacmd_ID_list_all_functions_current_buffer = 71; +static int32_t fcoder_metacmd_ID_list_all_locations = 72; +static int32_t fcoder_metacmd_ID_list_all_locations_case_insensitive = 73; +static int32_t fcoder_metacmd_ID_list_all_locations_of_identifier = 74; +static int32_t fcoder_metacmd_ID_list_all_locations_of_identifier_case_insensitive = 75; +static int32_t fcoder_metacmd_ID_list_all_locations_of_selection = 76; +static int32_t fcoder_metacmd_ID_list_all_locations_of_selection_case_insensitive = 77; +static int32_t fcoder_metacmd_ID_list_all_locations_of_type_definition = 78; +static int32_t fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier = 79; +static int32_t fcoder_metacmd_ID_list_all_substring_locations = 80; +static int32_t fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 81; +static int32_t fcoder_metacmd_ID_load_project = 82; +static int32_t fcoder_metacmd_ID_make_directory_query = 83; +static int32_t fcoder_metacmd_ID_move_down = 84; +static int32_t fcoder_metacmd_ID_move_down_10 = 85; +static int32_t fcoder_metacmd_ID_move_down_textual = 86; +static int32_t fcoder_metacmd_ID_move_left = 87; +static int32_t fcoder_metacmd_ID_move_line_down = 88; +static int32_t fcoder_metacmd_ID_move_line_up = 89; +static int32_t fcoder_metacmd_ID_move_right = 90; +static int32_t fcoder_metacmd_ID_move_up = 91; +static int32_t fcoder_metacmd_ID_move_up_10 = 92; +static int32_t fcoder_metacmd_ID_newline_or_goto_position_direct = 93; +static int32_t fcoder_metacmd_ID_newline_or_goto_position_same_panel_direct = 94; +static int32_t fcoder_metacmd_ID_newline_or_goto_position_same_panel_sticky = 95; +static int32_t fcoder_metacmd_ID_newline_or_goto_position_sticky = 96; +static int32_t fcoder_metacmd_ID_open_all_code = 97; +static int32_t fcoder_metacmd_ID_open_all_code_recursive = 98; +static int32_t fcoder_metacmd_ID_open_color_tweaker = 99; +static int32_t fcoder_metacmd_ID_open_file_in_quotes = 100; +static int32_t fcoder_metacmd_ID_open_in_other = 101; +static int32_t fcoder_metacmd_ID_open_long_braces = 102; +static int32_t fcoder_metacmd_ID_open_long_braces_break = 103; +static int32_t fcoder_metacmd_ID_open_long_braces_semicolon = 104; +static int32_t fcoder_metacmd_ID_open_matching_file_cpp = 105; +static int32_t fcoder_metacmd_ID_open_panel_hsplit = 106; +static int32_t fcoder_metacmd_ID_open_panel_vsplit = 107; +static int32_t fcoder_metacmd_ID_page_down = 108; +static int32_t fcoder_metacmd_ID_page_up = 109; +static int32_t fcoder_metacmd_ID_paste = 110; +static int32_t fcoder_metacmd_ID_paste_and_indent = 111; +static int32_t fcoder_metacmd_ID_paste_next = 112; +static int32_t fcoder_metacmd_ID_paste_next_and_indent = 113; +static int32_t fcoder_metacmd_ID_place_in_scope = 114; +static int32_t fcoder_metacmd_ID_project_fkey_command = 115; +static int32_t fcoder_metacmd_ID_project_go_to_root_directory = 116; +static int32_t fcoder_metacmd_ID_query_replace = 117; +static int32_t fcoder_metacmd_ID_query_replace_identifier = 118; +static int32_t fcoder_metacmd_ID_query_replace_selection = 119; +static int32_t fcoder_metacmd_ID_redo = 120; +static int32_t fcoder_metacmd_ID_remap_interactive = 121; +static int32_t fcoder_metacmd_ID_rename_file_query = 122; +static int32_t fcoder_metacmd_ID_reopen = 123; +static int32_t fcoder_metacmd_ID_replace_in_range = 124; +static int32_t fcoder_metacmd_ID_reverse_search = 125; +static int32_t fcoder_metacmd_ID_reverse_search_identifier = 126; +static int32_t fcoder_metacmd_ID_save = 127; +static int32_t fcoder_metacmd_ID_save_all_dirty_buffers = 128; +static int32_t fcoder_metacmd_ID_save_to_query = 129; +static int32_t fcoder_metacmd_ID_scope_absorb_down = 130; +static int32_t fcoder_metacmd_ID_search = 131; +static int32_t fcoder_metacmd_ID_search_identifier = 132; +static int32_t fcoder_metacmd_ID_seek_alphanumeric_left = 133; +static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_left = 134; +static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_right = 135; +static int32_t fcoder_metacmd_ID_seek_alphanumeric_right = 136; +static int32_t fcoder_metacmd_ID_seek_beginning_of_line = 137; +static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 138; +static int32_t fcoder_metacmd_ID_seek_end_of_line = 139; +static int32_t fcoder_metacmd_ID_seek_end_of_textual_line = 140; +static int32_t fcoder_metacmd_ID_seek_token_left = 141; +static int32_t fcoder_metacmd_ID_seek_token_right = 142; +static int32_t fcoder_metacmd_ID_seek_white_or_token_left = 143; +static int32_t fcoder_metacmd_ID_seek_white_or_token_right = 144; +static int32_t fcoder_metacmd_ID_seek_whitespace_down = 145; +static int32_t fcoder_metacmd_ID_seek_whitespace_down_end_line = 146; +static int32_t fcoder_metacmd_ID_seek_whitespace_left = 147; +static int32_t fcoder_metacmd_ID_seek_whitespace_right = 148; +static int32_t fcoder_metacmd_ID_seek_whitespace_up = 149; +static int32_t fcoder_metacmd_ID_seek_whitespace_up_end_line = 150; +static int32_t fcoder_metacmd_ID_select_all = 151; +static int32_t fcoder_metacmd_ID_set_bindings_choose = 152; +static int32_t fcoder_metacmd_ID_set_bindings_default = 153; +static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 154; +static int32_t fcoder_metacmd_ID_set_mark = 155; +static int32_t fcoder_metacmd_ID_setup_build_bat = 156; +static int32_t fcoder_metacmd_ID_setup_build_bat_and_sh = 157; +static int32_t fcoder_metacmd_ID_setup_build_sh = 158; +static int32_t fcoder_metacmd_ID_setup_new_project = 159; +static int32_t fcoder_metacmd_ID_show_filebar = 160; +static int32_t fcoder_metacmd_ID_show_scrollbar = 161; +static int32_t fcoder_metacmd_ID_snipe_token_or_word = 162; +static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 163; +static int32_t fcoder_metacmd_ID_suppress_mouse = 164; +static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 165; +static int32_t fcoder_metacmd_ID_to_lowercase = 166; +static int32_t fcoder_metacmd_ID_to_uppercase = 167; +static int32_t fcoder_metacmd_ID_toggle_filebar = 168; +static int32_t fcoder_metacmd_ID_toggle_fullscreen = 169; +static int32_t fcoder_metacmd_ID_toggle_line_wrap = 170; +static int32_t fcoder_metacmd_ID_toggle_mouse = 171; +static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 172; +static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 173; +static int32_t fcoder_metacmd_ID_undo = 174; +static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 175; +static int32_t fcoder_metacmd_ID_word_complete = 176; +static int32_t fcoder_metacmd_ID_write_and_auto_tab = 177; +static int32_t fcoder_metacmd_ID_write_block = 178; +static int32_t fcoder_metacmd_ID_write_character = 179; +static int32_t fcoder_metacmd_ID_write_hack = 180; +static int32_t fcoder_metacmd_ID_write_note = 181; +static int32_t fcoder_metacmd_ID_write_todo = 182; +static int32_t fcoder_metacmd_ID_write_underscore = 183; +static int32_t fcoder_metacmd_ID_write_zero_struct = 184; #endif diff --git a/4coder_generated/remapping.h b/4coder_generated/remapping.h index fd3422b2..c50ac671 100644 --- a/4coder_generated/remapping.h +++ b/4coder_generated/remapping.h @@ -10,7 +10,7 @@ bind(context, 'n', MDFR_CTRL, interactive_new); bind(context, 'o', MDFR_CTRL, interactive_open_or_new); bind(context, 'o', MDFR_ALT, open_in_other); bind(context, 'k', MDFR_CTRL, interactive_kill_buffer); -bind(context, 'i', MDFR_CTRL, interactive_switch_buffer); +bind(context, 'i', MDFR_CTRL, interactive_switch_buffer_DUMMY_API_EXPLORATION); bind(context, 'h', MDFR_CTRL, project_go_to_root_directory); bind(context, 'S', MDFR_CTRL, save_all_dirty_buffers); bind(context, 'c', MDFR_ALT, open_color_tweaker); @@ -344,7 +344,7 @@ static Meta_Key_Bind fcoder_binds_for_default_mapid_global[45] = { {0, 111, 1, "interactive_open_or_new", 23, LINK_PROCS(interactive_open_or_new)}, {0, 111, 2, "open_in_other", 13, LINK_PROCS(open_in_other)}, {0, 107, 1, "interactive_kill_buffer", 23, LINK_PROCS(interactive_kill_buffer)}, -{0, 105, 1, "interactive_switch_buffer", 25, LINK_PROCS(interactive_switch_buffer)}, +{0, 105, 1, "interactive_switch_buffer_DUMMY_API_EXPLORATION", 47, LINK_PROCS(interactive_switch_buffer_DUMMY_API_EXPLORATION)}, {0, 104, 1, "project_go_to_root_directory", 28, LINK_PROCS(project_go_to_root_directory)}, {0, 83, 1, "save_all_dirty_buffers", 22, LINK_PROCS(save_all_dirty_buffers)}, {0, 99, 2, "open_color_tweaker", 18, LINK_PROCS(open_color_tweaker)}, diff --git a/4coder_helper.cpp b/4coder_helper.cpp index de131962..1141b7ad 100644 --- a/4coder_helper.cpp +++ b/4coder_helper.cpp @@ -613,7 +613,7 @@ get_view_last(Application_Links *app, uint32_t access){ view.exists = true; get_view_prev(app, &view, access); if (view.view_id < 1 || view.view_id > 16){ - view = null_view_summary; + memset(&view, 0, sizeof(view)); } return(view); } diff --git a/4coder_ui_helper.cpp b/4coder_ui_helper.cpp new file mode 100644 index 00000000..0de844a2 --- /dev/null +++ b/4coder_ui_helper.cpp @@ -0,0 +1,42 @@ +/* + * Helpers for ui data structures. + */ + +// TOP + +static UI_Item* +ui_list_add_item(Partition *arena, UI_List *list, UI_Item item){ + UI_Item_Node *node = push_array(arena, UI_Item_Node, 1); + zdll_push_back(list->first, list->last, node); + list->count += 1; + node->fixed = item; + return(&node->fixed); +} + +static UI_Control +ui_list_to_ui_control(Partition *arena, UI_List *list){ + UI_Control control = {0}; + control.items = push_array(arena, UI_Item, list->count); + for (UI_Item_Node *node = list->first; + node != 0; + node = node->next){ + control.items[control.count++] = node->fixed; + } + return(control); +} + +static UI_Item* +ui_control_get_mouse_hit(UI_Control *control, int32_t mx, int32_t my){ + int32_t count = control->count; + UI_Item *item = control->items + count - 1; + for (int32_t i = 0; i < count; ++i, item -= 1){ + i32_Rect r = item->rectangle; + if (r.x0 <= mx && mx < r.x1 && r.y0 <= my && my < r.y1){ + return(item); + } + } + return(0); +} + +// BOTTOM + diff --git a/4ed.cpp b/4ed.cpp index 9352a4c7..3c7c1cc0 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -232,21 +232,15 @@ COMMAND_DECL(redo){ } COMMAND_DECL(interactive_new){ - USE_MODELS(models); - USE_VIEW(view); - view_show_interactive(system, view, models, IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); + } COMMAND_DECL(interactive_open){ - USE_MODELS(models); - USE_VIEW(view); - view_show_interactive(system, view, models, IAct_Open, IInt_Sys_File_List,make_lit_string("Open: ")); + } COMMAND_DECL(interactive_open_or_new){ - USE_MODELS(models); - USE_VIEW(view); - view_show_interactive(system, view, models, IAct_OpenOrNew, IInt_Sys_File_List,make_lit_string("Open: ")); + } // TODO(allen): Improvements to reopen @@ -335,15 +329,11 @@ COMMAND_DECL(save){ } COMMAND_DECL(interactive_switch_buffer){ - USE_MODELS(models); - USE_VIEW(view); - view_show_interactive(system, view, models, IAct_Switch, IInt_Live_File_List, make_lit_string("Switch Buffer: ")); + } COMMAND_DECL(interactive_kill_buffer){ - USE_MODELS(models); - USE_VIEW(view); - view_show_interactive(system, view, models, IAct_Kill, IInt_Live_File_List, make_lit_string("Kill Buffer: ")); + } COMMAND_DECL(kill_buffer){ @@ -387,13 +377,7 @@ case_change_range(System_Functions *system, Models *models, View *view, Editing_ } COMMAND_DECL(open_color_tweaker){ - USE_VIEW(view); - view->transient.map = mapid_ui; - view->transient.showing_ui = VUI_Theme; - view->transient.color_mode = CV_Mode_Library; - view->transient.color = super_color_create(0xFF000000); - view->transient.current_color_editing = 0; - view->transient.changed_context_in_step = true; + } COMMAND_DECL(user_callback){ @@ -1683,7 +1667,9 @@ App_Step_Sig(app_step){ view = panel->view; } +#if 0 view_show_interactive(system, view, models, IAct_Sure_To_Close, IInt_Sure_To_Close, make_lit_string("Are you sure?")); +#endif models->command_coroutine = command_coroutine; } @@ -1884,18 +1870,6 @@ App_Step_Sig(app_step){ view->transient.changed_context_in_step = 0; - View_Step_Result result = step_view(system, view, models, active_view, summary); - - if (result.animating){ - app_result.animating = 1; - } - if (result.consume_keys){ - consume_input(&vars->available_input, Input_AnyKey, "file view step"); - } - if (result.consume_keys || result.consume_esc){ - consume_input(&vars->available_input, Input_Esc, "file view step"); - } - if (view->transient.changed_context_in_step == 0){ active = (panel == active_panel); summary = (active)?(active_input):(dead_input); @@ -1903,20 +1877,17 @@ App_Step_Sig(app_step){ summary.mouse = mouse_state; } - b32 file_scroll = false; - GUI_Scroll_Vars *scroll_vars = &view->transient.gui_scroll; - if (view->transient.showing_ui == VUI_None){ - Assert(view->transient.file_data.file != 0); - scroll_vars = &view->transient.edit_pos->scroll; - file_scroll = true; - } + b32 file_scroll = true; + GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos->scroll; i32 max_y = 0; - if (view->transient.showing_ui == VUI_None){ + if (view->transient.ui_mode_counter == 0){ max_y = view_compute_max_target_y(view); } else{ +#if 0 max_y = view->transient.gui_max_y; +#endif } Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->inner, active, &summary, *scroll_vars, view->transient.scroll_region, max_y); @@ -1931,11 +1902,7 @@ App_Step_Sig(app_step){ consume_input(&vars->available_input, Input_MouseRightButton, "file view step"); } - if (ip_result.has_max_y_suggestion){ - view->transient.gui_max_y = ip_result.max_y; - } - - if (!gui_scroll_eq(scroll_vars, &ip_result.vars)){ + if (memcmp(scroll_vars, &ip_result.vars, sizeof(*scroll_vars)) != 0){ if (file_scroll){ view_set_scroll(system, view, ip_result.vars); } @@ -2198,12 +2165,11 @@ App_Step_Sig(app_step){ panel != &models->layout.used_sentinel; panel = panel->next){ View *view = panel->view; - GUI_Scroll_Vars *scroll_vars = &view->transient.gui_scroll; if (view->transient.edit_pos != 0){ - scroll_vars = &view->transient.edit_pos->scroll; + GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos->scroll; + scroll_vars->scroll_x = (f32)scroll_vars->target_x; + scroll_vars->scroll_y = (f32)scroll_vars->target_y; } - scroll_vars->scroll_x = (f32)scroll_vars->target_x; - scroll_vars->scroll_y = (f32)scroll_vars->target_y; } } @@ -2236,13 +2202,7 @@ App_Step_Sig(app_step){ u32 back_color = style->main.back_color; draw_rectangle(target, full, back_color); - b32 file_scroll = false; - GUI_Scroll_Vars *scroll_vars = &view->transient.gui_scroll; - if (view->transient.showing_ui == VUI_None){ - Assert(view->transient.file_data.file != 0); - scroll_vars = &view->transient.edit_pos->scroll; - file_scroll = true; - } + GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos->scroll; do_render_file_view(system, view, models, scroll_vars, active_view, panel->inner, active, target, &dead_input); diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index d1f4ff66..bafbd4c3 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -67,7 +67,7 @@ internal void fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ File_Viewing_Data *data = &vptr->transient.file_data; - *view = null_view_summary; + memset(view, 0, sizeof(*view)); if (vptr->transient.in_use){ view->exists = true; @@ -1523,11 +1523,11 @@ internal_get_view_next(Command_Data *cmd, View_Summary *view){ fill_view_summary(system, view, panel->view, live_set, &cmd->models->working_set); } else{ - *view = null_view_summary; + memset(view, 0, sizeof(*view)); } } else{ - *view = null_view_summary; + memset(view, 0, sizeof(*view)); } } @@ -1598,7 +1598,7 @@ DOC_SEE(Access_Flag) View *vptr = live_set->views + view_id; fill_view_summary(system, &view, vptr, live_set, &cmd->models->working_set); if (!access_test(view.lock_flags, access)){ - view = null_view_summary; + memset(&view, 0, sizeof(view)); } } @@ -1623,7 +1623,7 @@ DOC_SEE(Access_Flag) View_Summary view = {0}; fill_view_summary(system, &view, panel->view, &models->live_set, &models->working_set); if (!access_test(view.lock_flags, access)){ - view = null_view_summary; + memset(&view, 0, sizeof(view)); } return(view); } @@ -2185,6 +2185,69 @@ View_Get_Variable(Application_Links *app, View_Summary *view, int32_t location, return(result); } +API_EXPORT int32_t +View_Start_UI_Mode(Application_Links *app, View_Summary *view){ + Command_Data *cmd = (Command_Data*)app->cmd_context; + View *vptr = imp_get_view(cmd, view); + if (vptr != 0){ + vptr->transient.ui_mode_counter = clamp_bottom(0, vptr->transient.ui_mode_counter); + vptr->transient.ui_mode_counter += 1; + return(vptr->transient.ui_mode_counter); + } + else{ + return(0); + } +} + +API_EXPORT int32_t +View_End_UI_Mode(Application_Links *app, View_Summary *view){ + Command_Data *cmd = (Command_Data*)app->cmd_context; + View *vptr = imp_get_view(cmd, view); + if (vptr != 0){ + vptr->transient.ui_mode_counter = clamp_bottom(0, vptr->transient.ui_mode_counter); + if (vptr->transient.ui_mode_counter > 0){ + vptr->transient.ui_mode_counter -= 1; + return(vptr->transient.ui_mode_counter + 1); + } + else{ + return(0); + } + } + else{ + return(0); + } +} + +API_EXPORT bool32 +View_Set_UI(Application_Links *app, View_Summary *view, UI_Control *control){ + Command_Data *cmd = (Command_Data*)app->cmd_context; + View *vptr = imp_get_view(cmd, view); + Models *models = cmd->models; + General_Memory *general = &models->mem.general; + if (vptr != 0){ + if (vptr->transient.ui_control.items != 0){ + general_memory_free(general, vptr->transient.ui_control.items); + } + vptr->transient.ui_control.count = 0; + if (control->count > 0){ + i32 memory_size = sizeof(UI_Item)*control->count; + vptr->transient.ui_control.items = (UI_Item*)general_memory_allocate(general, memory_size); + if (vptr->transient.ui_control.items != 0){ + vptr->transient.ui_control.count = control->count; + memcpy(vptr->transient.ui_control.items, control->items, memory_size); + } + else{ + return(false); + } + } + else{ + vptr->transient.ui_control.items = 0; + } + return(true); + } + return(false); +} + API_EXPORT User_Input Get_User_Input(Application_Links *app, Input_Type_Flag get_type, Input_Type_Flag abort_type) /* diff --git a/4ed_gui.cpp b/4ed_gui.cpp index fc588d32..5a0894a2 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -9,14 +9,6 @@ // TOP -internal GUI_id -gui_id(u64 a, u64 b){ - GUI_id id; - id.id[0] = a; - id.id[1] = b; - return(id); -} - internal void init_query_set(Query_Set *set){ Query_Slot *slot = set->slots; @@ -60,1124 +52,5 @@ free_query_slot(Query_Set *set, Query_Bar *match_bar){ } } -internal Super_Color -super_color_create(u32 packed){ - Super_Color result = {}; - result.rgba = unpack_color4(packed); - result.hsla = rgba_to_hsla(result.rgba); - return result; -} - -internal void -super_color_post_hsla(Super_Color *color, Vec4 hsla){ - color->hsla = hsla; - if (hsla.h == 1.f) - hsla.h = 0.f; - color->rgba = hsla_to_rgba(hsla); - *color->out = pack_color4(color->rgba); -} - -internal void -super_color_post_rgba(Super_Color *color, Vec4 rgba){ - color->rgba = rgba; - color->hsla = rgba_to_hsla(rgba); - *color->out = pack_color4(rgba); -} - -internal void -super_color_post_packed(Super_Color *color, u32 packed){ - color->rgba = unpack_color4(packed); - color->hsla = rgba_to_hsla(color->rgba); - *color->out = packed; -} - -u32 super_color_clear_masks[] = {0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00}; -u32 super_color_shifts[] = {16, 8, 0}; - -internal u32 -super_color_post_byte(Super_Color *color, i32 channel, u8 byte){ - u32 packed = *color->out; - packed &= super_color_clear_masks[channel]; - packed |= (byte << super_color_shifts[channel]); - super_color_post_packed(color, packed); - return packed; -} - -inline b32 -gui_id_eq(GUI_id id1, GUI_id id2){ - b32 result = (id1.id[0] == id2.id[0] && id1.id[1] == id2.id[1]); - return(result); -} - -inline b32 -gui_id_is_null(GUI_id id){ - b32 result = (id.id[0] == 0 && id.id[1] == 0); - return(result); -} - -internal i32 -gui_active_level(GUI_Target *target, GUI_id id){ - i32 level = 0; - if (gui_id_eq(target->active, id)){ - level = 4; - } - else if (gui_id_eq(target->auto_hot, id)){ - level = 3; - } - else if (gui_id_eq(target->mouse_hot, id)){ - if (gui_id_eq(target->hover, id)){ - level = 3; - } - else{ - level = 2; - } - } - else if (gui_id_eq(target->hover, id) && gui_id_is_null(target->mouse_hot)){ - level = 1; - } - return(level); -} - -internal void -gui_rollback(GUI_Target *target, GUI_Item_Update *update){ - target->push.pos = update->partition_point; -} - -internal void -gui_fill_update(GUI_Item_Update *update, GUI_Target *target, GUI_Header *h){ - if (update){ - update->partition_point = (i32)((char*)h - (char*)target->push.base); - update->has_adjustment = 0; - update->has_index_position = 0; - } -} - -internal void -gui_update_adjustment(GUI_Item_Update *update, i32 adjustment_value){ - if (update){ - update->has_adjustment = 1; - update->adjustment_value = adjustment_value; - } -} - -internal void -gui_update_position(GUI_Item_Update *update, i32_Rect position){ - if (update){ - update->has_index_position = 1; - update->index_position = position; - } -} - -internal void* -gui_push_item(GUI_Target *target, void *item, i32 size){ - void *dest = 0; - if (size == 0){ - dest = partition_current(&target->push); - } - else{ - dest = partition_allocate(&target->push, size); - if (dest && item){ - memcpy(dest, item, size); - } - } - return(dest); -} - -internal void* -gui_align(GUI_Target *target){ - void *ptr; - partition_align(&target->push, 8); - ptr = partition_current(&target->push); - return(ptr); -} - -internal void* -gui_align(GUI_Target *target, GUI_Header *h){ - void *ptr; - partition_align(&target->push, 8); - ptr = partition_current(&target->push); - h->size = (i32)((char*)ptr - (char*)h); - return(ptr); -} - -internal void* -advance_to_alignment(void *ptr){ - u64 p = (u64)ptr; - p = (p + 7) & (~7); - return (void*)p; -} - -internal void* -gui_push_aligned_item(GUI_Target *target, GUI_Header *h, void *item, i32 size){ - char *ptr = (char*)partition_allocate(&target->push, size); - if (ptr && item){ - memcpy(ptr, item, size); - } - gui_align(target, h); - return(ptr); -} - -internal void* -gui_push_item(GUI_Target *target, GUI_Header *h, void *item, i32 size){ - void *ptr; - ptr = (char*)partition_allocate(&target->push, size); - if (ptr && item){ - memcpy(ptr, item, size); - } - h->size += size; - return(ptr); -} - -internal GUI_Header* -gui_push_simple_command(GUI_Target *target, i32 type){ - GUI_Header *result = 0; - GUI_Header item; - item.type = type; - item.size = sizeof(item); - result = (GUI_Header*)gui_push_item(target, &item, sizeof(item)); - return(result); -} - -internal GUI_Edit* -gui_push_string_edit_command(GUI_Target *target, i32 type, GUI_id id, void *out){ - GUI_Edit *result = 0; - GUI_Edit item; - item.h.type = type; - item.h.size = sizeof(item); - item.id = id; - item.out = out; - result = (GUI_Edit*)gui_push_item(target, &item, sizeof(item)); - return(result); -} - -internal GUI_Interactive* -gui_push_button_command(GUI_Target *target, i32 type, GUI_id id){ - GUI_Interactive *result = 0; - GUI_Interactive item; - item.h.type = type; - item.h.size = sizeof(item); - item.id = id; - result = (GUI_Interactive*)gui_push_item(target, &item, sizeof(item)); - return(result); -} - -internal void -gui_push_string(GUI_Target *target, GUI_Header *h, String s, i32 extra){ - u8 *start, *end, *str_start; - i32 size; - i32 *cap; - - start = (u8*)gui_push_item(target, &s.size, sizeof(s.size)); - cap = (i32*)gui_push_item(target, 0, sizeof(i32)); - str_start = (u8*)gui_push_item(target, s.str, s.size); - if (extra) gui_push_item(target, 0, extra); - end = (u8*)gui_align(target); - size = (i32)(end - start); - *cap = (i32)(end - str_start); - h->size += size; -} - -internal void -gui_push_string(GUI_Target *target, GUI_Header *h, String s){ - gui_push_string(target, h, s, 0); -} - -internal void -gui_begin_serial_section(GUI_Target *target){ - gui_push_simple_command(target, guicom_begin_serial); -} - -internal void -gui_end_serial_section(GUI_Target *target){ - gui_push_simple_command(target, guicom_end_serial); -} - -internal void -gui_begin_top_level(GUI_Target *target, Input_Summary input){ - target->push.pos = 0; - target->has_keys = (input.keys.count > 0); - target->animating = 0; - target->did_file = 0; -} - -internal void -gui_end_top_level(GUI_Target *target){ - gui_push_simple_command(target, guicom_null); - target->has_list_index_position = 0; -} - -internal void -gui_do_top_bar(GUI_Target *target){ - gui_push_simple_command(target, guicom_top_bar); -} - -internal void -gui_do_file(GUI_Target *target){ - gui_push_simple_command(target, guicom_file); - target->did_file = 1; -} - -internal void -gui_do_text_field(GUI_Target *target, String prompt, String text){ - GUI_Header *h = gui_push_simple_command(target, guicom_text_field); - gui_push_string(target, h, prompt); - gui_push_string(target, h, text); -} - -internal b32 -gui_do_text_with_cursor(GUI_Target *target, i32 pos, String text, GUI_Item_Update *update){ - b32 result = 0; - GUI_Header *h = gui_push_simple_command(target, guicom_text_with_cursor); - gui_push_string(target, h, text); - gui_push_item(target, h, &pos, sizeof(i32)); - - result = target->has_keys; - if (result){ - gui_fill_update(update, target, h); - target->animating = 1; - } - - return(result); -} - -internal b32 -gui_do_color_button(GUI_Target *target, GUI_id id, u32 fore, u32 back, String text){ - b32 result = 0; - GUI_Interactive *b = gui_push_button_command(target, guicom_color_button, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_item(target, h, &fore, sizeof(fore)); - gui_push_item(target, h, &back, sizeof(back)); - gui_push_string(target, h, text); - - if (gui_id_eq(id, target->active)){ - result = 1; - target->animating = 1; - } - - return(result); -} - -internal b32 -gui_begin_list(GUI_Target *target, GUI_id id, i32 list_i, - b32 activate_item, b32 snap_into_view, GUI_Item_Update *update){ - b32 result = false; - b32 active = false; - - i32 list_min = 0; - i32 list_max = target->list_max; - - GUI_Interactive *b = gui_push_button_command(target, guicom_begin_list, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_item(target, h, &list_i, sizeof(list_i)); - gui_push_item(target, h, &activate_item, sizeof(activate_item)); - - result = target->has_keys || target->has_list_index_position; - if (gui_id_eq(id, target->active)){ - active = true; - result = true; - } - - if (snap_into_view){ - if (target->list_view_min > list_min){ - list_min = target->list_view_min; - } - if (target->list_view_max < list_max){ - list_max = target->list_view_max; - } - } - - if (list_max > 0){ - if (list_i < list_min || list_i >= list_max){ - result = true; - } - } - - if (result){ - gui_fill_update(update, target, h); - if (list_i < list_min){ - if (list_max > 0){ - i32 range_size = list_max - list_min; - i32 roll_down = (list_min - list_i)%range_size; - if (roll_down == 0){ - roll_down = range_size; - } - gui_update_adjustment(update, list_max - roll_down); - } - else{ - gui_update_adjustment(update, 0); - } - } - else if (list_i >= list_max){ - if (list_max > 0){ - i32 range_size = list_max - list_min; - i32 roll_over = (list_i - list_max)%range_size; - gui_update_adjustment(update, list_min + roll_over); - } - else{ - gui_update_adjustment(update, 0); - } - } - if (target->has_list_index_position){ - gui_update_position(update, target->list_index_position); - } - - target->animating = 1; - } - - return(result); -} - -internal void -gui_end_list(GUI_Target *target){ - gui_push_simple_command(target, guicom_end_list); -} - -internal b32 -gui_do_file_option(GUI_Target *target, GUI_id id, String filename, - b32 is_folder, String message){ - b32 result = 0; - GUI_Interactive *b = gui_push_button_command(target, guicom_file_option, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_item(target, h, &is_folder, sizeof(is_folder)); - gui_push_string(target, h, filename, 1); - gui_push_string(target, h, message); - - if (gui_id_eq(id, target->active)){ - result = 1; - target->animating = 1; - } - - return(result); -} - -internal b32 -gui_do_button(GUI_Target *target, GUI_id id, String message){ - b32 result = 0; - GUI_Interactive *b = gui_push_button_command(target, guicom_button, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_string(target, h, message); - gui_align(target, h); - - if (gui_id_eq(id, target->active)){ - result = 1; - target->animating = 1; - } - - return(result); -} - -internal b32 -gui_do_button(GUI_Target *target, GUI_id id, char *message){ - String str_message = make_string_slowly(message); - b32 result = gui_do_button(target, id, str_message); - return(result); -} - -internal b32 -gui_do_fixed_option(GUI_Target *target, GUI_id id, String message, char key){ - b32 result = 0; - GUI_Interactive *b = gui_push_button_command(target, guicom_fixed_option, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_string(target, h, message); - gui_push_item(target, h, &key, 1); - gui_align(target, h); - - if (gui_id_eq(id, target->active)){ - result = 1; - target->animating = 1; - } - - return(result); -} - -internal b32 -gui_do_fixed_option_checkbox(GUI_Target *target, GUI_id id, String message, char key, b8 state){ - b32 result = 0; - GUI_Interactive *b = gui_push_button_command(target, guicom_fixed_option_checkbox, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_string(target, h, message); - gui_push_item(target, h, &key, 1); - gui_push_item(target, h, &state, 1); - gui_align(target, h); - - if (gui_id_eq(id, target->active)){ - result = 1; - target->animating = 1; - } - - return(result); -} - -internal b32 -gui_do_style_preview(GUI_Target *target, GUI_id id, i32 style_index){ - b32 result = 0; - GUI_Interactive *b = gui_push_button_command(target, guicom_style_preview, id); - GUI_Header *h = (GUI_Header*)b; - gui_push_item(target, h, &style_index, sizeof(style_index)); - gui_align(target, h); - - if (gui_id_eq(id, target->active)){ - result = 1; - target->animating = 1; - } - - return(result); -} - -internal GUI_id -gui_id_scrollbar(){ - GUI_id id; - id.id[0] = 0; - id.id[1] = max_u64; - return(id); -} - -internal GUI_id -gui_id_scrollbar_top(){ - GUI_id id; - id.id[0] = 1; - id.id[1] = max_u64; - return(id); -} - -internal GUI_id -gui_id_scrollbar_slider(){ - GUI_id id; - id.id[0] = 2; - id.id[1] = max_u64; - return(id); -} - -internal GUI_id -gui_id_scrollbar_bottom(){ - GUI_id id; - id.id[0] = 3; - id.id[1] = max_u64; - return(id); -} - -internal b32 -gui_scroll_eq(GUI_Scroll_Vars *a, GUI_Scroll_Vars *b){ - b32 result = (memcmp(a, b, sizeof(*a)) == 0); - return(result); -} - -#if 0 -// TODO(allen): Rethink this a little, seems like there are two separate things we want to do here: -// Getting the updated scroll vars, and telling the user when scrolling actions occur. -internal b32 -gui_get_scroll_vars(GUI_Target *target, GUI_id scroll_context_id, i32_Rect *region_out){ - b32 result = 0; - if (gui_id_eq(scroll_context_id, target->scroll_id)){ - *region_out = target->region_updated; - - if (gui_id_eq(target->active, gui_id_scrollbar())){ - result = 1; - target->animating = 1; - } - } - return(result); -} -#endif - -internal b32 -gui_scroll_was_activated(GUI_Target *target, GUI_id scroll_context_id){ - b32 result = false; - - if (gui_id_eq(scroll_context_id, target->scroll_id)){ - if (gui_id_eq(target->active, gui_id_scrollbar())){ - result = true; - target->animating = true; - } - } - - return(result); -} - -internal void -gui_post_scroll_vars(GUI_Target *target, GUI_Scroll_Vars *vars_in, i32_Rect region_in){ - if (!rect_equal(region_in, target->region_updated)){ - target->region_updated = region_in; - target->animating = 1; - target->active = gui_id_scrollbar(); - } -} - -internal void -gui_begin_scrollable(GUI_Target *target, GUI_id scroll_context_id, GUI_Scroll_Vars scroll_vars, i32 delta, b32 show_bar){ - GUI_Header *h; - - gui_begin_serial_section(target); - - target->delta = delta; - h = gui_push_simple_command(target, guicom_scrollable); - - target->scroll_original = scroll_vars; - target->scroll_id = scroll_context_id; - - if (show_bar){ - gui_push_simple_command(target, guicom_scrollable_bar); - gui_push_simple_command(target, guicom_scrollable_top); - gui_push_simple_command(target, guicom_scrollable_slider); - gui_push_simple_command(target, guicom_scrollable_bottom); - } - else{ - gui_push_simple_command(target, guicom_scrollable_invisible); - } - gui_push_simple_command(target, guicom_begin_scrollable_section); -} - -internal void -gui_end_scrollable(GUI_Target *target){ - gui_push_simple_command(target, guicom_end_scrollable_section); - gui_end_serial_section(target); -} - -internal void -gui_activate_scrolling(GUI_Target *target){ - target->active = gui_id_scrollbar(); -} - -#define GUIScrollbarWidth 16 - -// TODO(allen): We can probably totally get rid of this now. -internal i32 -gui_session_get_eclipsed_y(GUI_Session *session){ - i32 count = session->t + 1; - i32 max_v = session->sections[count-1].top_v; - return(max_v); -} - -internal i32 -gui_session_get_current_top(GUI_Session *session){ - i32 result = session->sections[session->t].top_v; - return(result); -} - -inline GUI_Session -gui_session_zero(){ - GUI_Session session={0}; - return(session); -} - -internal void -gui_session_init(GUI_Session *session, GUI_Target *target, - i32_Rect full_rect, i32 line_height){ - GUI_Section *section; - - *session = gui_session_zero(); - session->full_rect = full_rect; - session->line_height = line_height; - - section = &session->sections[0]; - section->v = full_rect.y0; - section->max_v = full_rect.y0; - - target->list_view_min = max_i32; - target->list_view_max = min_i32; -} - -internal void -gui_section_end_item(GUI_Section *section, i32 v){ - section->v = v; - if (section->max_v < v){ - section->max_v = v; - } -} - -inline i32_Rect -gui_layout_top_bottom(GUI_Session *session, i32 y0, i32 y1){ - i32_Rect rect = {0}; - - rect.y0 = y0; - rect.y1 = y1; - rect.x0 = session->full_rect.x0; - rect.x1 = session->full_rect.x1; - - if (session->is_scrollable){ - rect.x0 = session->scroll_region.x0; - rect.x1 = session->scroll_region.x1; - } - - return(rect); -} - -inline i32_Rect -gui_layout_fixed_h(GUI_Session *session, i32 y, i32 h){ - i32_Rect rect; - rect = gui_layout_top_bottom(session, y, y + h); - return(rect); -} - -internal void -gui_scrollbar_top(i32_Rect bar, i32_Rect *top){ - i32 w = (bar.x1 - bar.x0); - top->x0 = bar.x0; - top->x1 = bar.x1; - top->y0 = bar.y0; - top->y1 = top->y0 + w; -} - -internal void -gui_scrollbar_slider(i32_Rect bar, i32_Rect *slider, f32 s, f32 *min_out, f32 *max_out, i32 target_min, i32 target_max){ - i32 h = 0, w = (bar.x1 - bar.x0); - i32 min = 0, max = 0, pos = 0; - - f32 screen_size = (f32)(bar.y1 - bar.y0); - f32 full_size = (f32)(target_max - target_min + screen_size); - f32 ratio = 1.f; - - if (full_size > screen_size){ - ratio = screen_size/full_size; - } - - h = (i32)(ratio * bar.y1 - bar.y0 - w*2); - - if (h < w){ - h = w; - } - - slider->x0 = bar.x0; - slider->x1 = bar.x1; - - min = bar.y0 + w + h/2; - max = bar.y1 - w - h/2; - - pos = lerp(min, s, max); - - slider->y0 = pos - h/2; - slider->y1 = slider->y0 + h; - - *min_out = (f32)min; - *max_out = (f32)max; -} - -internal void -gui_scrollbar_bottom(i32_Rect bar, i32_Rect *bottom){ - i32 w = (bar.x1 - bar.x0); - bottom->x0 = bar.x0; - bottom->x1 = bar.x1; - bottom->y1 = bar.y1; - bottom->y0 = bottom->y1 - w; -} - -#define NextHeader(h) ((GUI_Header*)((char*)(h) + (h)->size)) - -internal i8 -gui_read_byte(void **ptr){ - i8 result; - result = *(i8*)*ptr; - *ptr = ((char*)*ptr) + 1; - return(result); -} - -internal i32 -gui_read_integer(void **ptr){ - i32 result; - result = *(i32*)*ptr; - *ptr = ((char*)*ptr) + 4; - return(result); -} - -internal f32 -gui_read_float(void **ptr){ - f32 result; - result = *(f32*)*ptr; - *ptr = ((char*)*ptr) + 4; - return(result); -} - -internal String -gui_read_string(void **ptr){ - String result; - - result.size = *(i32*)*ptr; - *ptr = ((i32*)*ptr) + 1; - result.memory_size = *(i32*)*ptr; - *ptr = ((i32*)*ptr) + 1; - - result.str = (char*)*ptr; - *ptr = result.str + result.memory_size; - - return(result); -} - -internal void* -gui_read_out(void **ptr){ - void *result; - result = *(void**)*ptr; - *ptr = ((void**)ptr) + 1; - return(result); -} - -internal GUI_Interpret_Result -gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, - GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){ - GUI_Interpret_Result result = {0}; - GUI_Section *section = 0; - GUI_Section *new_section = 0; - GUI_Section *prev_section = 0; - GUI_Section *end_section = 0; - b32 give_to_user = 0; - b32 always_give_to_user = 0; - b32 do_layout = 1; - b32 is_list_item = 0; - i32_Rect rect = {0}; - i32 y = 0; - i32 end_v = -1; - f32 lerp_space_scroll_v = 0; - i32 scroll_v = (i32)target->scroll_original.scroll_y; - i32 target_v = (i32)vars.target_y; - - Assert(session->t < ArrayCount(session->sections)); - section = session->sections + session->t; - y = section->v; - - if (!session->is_scrollable) scroll_v = 0; - - switch (h->type){ - case guicom_null: InvalidCodePath; - - case guicom_begin_serial: - { - ++session->t; - Assert(session->t < ArrayCount(session->sections)); - new_section = &session->sections[session->t]; - new_section->v = y; - new_section->max_v = y; - new_section->top_v = y; - }break; - - case guicom_end_serial: - { - Assert(session->t > 0); - prev_section = &session->sections[--session->t]; - end_v = section->max_v; - end_section = prev_section; - }break; - - case guicom_top_bar: - { - give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height + 2); - end_v = rect.y1; - end_section = section; - }break; - - case guicom_file: - { - give_to_user = 1; - rect = gui_layout_top_bottom(session, y, session->full_rect.y1); - end_v = rect.y1; - end_section = section; - scroll_v = 0; - }break; - - case guicom_text_with_cursor: - case guicom_text_field: - { - give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height + 2); - end_v = rect.y1; - end_section = section; - }break; - - case guicom_color_button: - { - give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height + 2); - end_v = rect.y1; - end_section = section; - }break; - - case guicom_begin_list: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - i32 index = gui_read_integer(&ptr); - b32 activate = (b32)gui_read_integer(&ptr); - - Assert(session->list.in_list == 0); - session->list.in_list = 1; - session->list.index = 0; - session->list.auto_hot = index; - session->list.auto_activate = -1; - if (activate){ - session->list.auto_activate = index; - } - }break; - - case guicom_end_list: - { - Assert(session->list.in_list == 1); - session->list.in_list = 0; - target->list_max = session->list.index; - }break; - - case guicom_file_option: - case guicom_fixed_option: - case guicom_fixed_option_checkbox: - { - give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height * 2); - end_v = rect.y1; - end_section = section; - is_list_item = 1; - - if (session->list.in_list){ - if (session->list.auto_hot == session->list.index){ - result.auto_hot = 1; - if (!rect_equal(target->list_index_position, rect)){ - target->has_list_index_position = 1; - target->list_index_position = rect; - } - } - if (session->list.auto_activate == session->list.index){ - result.auto_activate = 1; - } - - ++session->list.index; - } - }break; - - case guicom_button: - { - give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height * 2); - end_v = rect.y1; - end_section = section; - }break; - - case guicom_style_preview: - { - give_to_user = 1; - rect = gui_layout_fixed_h(session, y, session->line_height * 3 + 6); - end_v = rect.y1; - end_section = section; - }break; - - case guicom_scrollable: - { - Assert(session->is_scrollable == 0); - session->is_scrollable = 1; - always_give_to_user = 1; - - i32_Rect scrollable_rect = {0}; - scrollable_rect.x0 = session->full_rect.x0; - scrollable_rect.x1 = session->full_rect.x1; - scrollable_rect.y0 = y; - scrollable_rect.y1 = session->full_rect.y1; - result.has_region = 1; - result.region = scrollable_rect; - session->scroll_region = scrollable_rect; - }break; - - case guicom_scrollable_bar: - { - Assert(session->is_scrollable); - give_to_user = 1; - rect.x1 = session->full_rect.x1; - rect.x0 = rect.x1 - GUIScrollbarWidth; - rect.y0 = y; - rect.y1 = session->full_rect.y1; - session->scroll_rect = rect; - - i32_Rect scrollable_rect = {0}; - scrollable_rect.x0 = session->full_rect.x0; - scrollable_rect.x1 = rect.x0; - scrollable_rect.y0 = y; - scrollable_rect.y1 = session->full_rect.y1; - result.has_region = 1; - result.region = scrollable_rect; - session->scroll_region = scrollable_rect; - scroll_v = 0; - }break; - - case guicom_scrollable_top: - { - Assert(session->is_scrollable); - give_to_user = 1; - gui_scrollbar_top(session->scroll_rect, &rect); - scroll_v = 0; - }break; - - case guicom_scrollable_slider: - { - Assert(session->is_scrollable); - give_to_user = 1; - - lerp_space_scroll_v = - unlerp(0, - (f32)target->scroll_original.target_y, - (f32)max_y); - - gui_scrollbar_slider(session->scroll_rect, &rect, lerp_space_scroll_v, - &session->scroll_top, &session->scroll_bottom, - 0, max_y); - scroll_v = 0; - }break; - - case guicom_scrollable_invisible: - { - Assert(session->is_scrollable); - always_give_to_user = 1; - }break; - - case guicom_scrollable_bottom: - { - Assert(session->is_scrollable); - give_to_user = 1; - gui_scrollbar_bottom(session->scroll_rect, &rect); - scroll_v = 0; - }break; - - case guicom_begin_scrollable_section: - { - always_give_to_user = 1; - session->scrollable_items_bottom = 0; - rect = gui_layout_top_bottom(session, y, session->full_rect.y1); - end_v = rect.y1; - }break; - - case guicom_end_scrollable_section: - { - always_give_to_user = 1; - session->suggested_max_y = ceil32(session->scrollable_items_bottom - (session->full_rect.y0 + session->full_rect.y1)*.5f); - if (session->suggested_max_y < 0){ - session->suggested_max_y = 0; - } - }break; - } - - if (do_layout){ - if (session->list.in_list && is_list_item){ - i32 list_i = session->list.index - 1; - - if (rect.y0 - target_v >= region.y0 && - rect.y1 - target_v <= region.y1){ - if (list_i < target->list_view_min){ - target->list_view_min = list_i; - } - if (list_i+1 > target->list_view_max){ - target->list_view_max = list_i+1; - } - } - } - - if (give_to_user){ - if (session->is_scrollable){ - session->scrollable_items_bottom = - Max(session->scrollable_items_bottom, rect.y1); - } - - rect.y0 -= scroll_v; - rect.y1 -= scroll_v; - - if (rect.y1 > session->full_rect.y0){ - session->rect = rect; - } - else{ - give_to_user = 0; - result.screen_orientation = -1; - } - } - - if (end_section){ - gui_section_end_item(end_section, end_v); - } - - // TODO(allen): Why is this here, is there a particular reason? - if (y - scroll_v >= session->full_rect.y1){ - give_to_user = 0; - result.screen_orientation = 1; - } - } - - session->clip_y = gui_session_get_eclipsed_y(session); - - result.has_info = (give_to_user || always_give_to_user); - - return(result); -} - -internal GUI_View_Jump -gui_compute_view_jump(i32_Rect scroll_region, i32_Rect position){ - GUI_View_Jump jump = {0}; - i32 region_h = scroll_region.y1 - scroll_region.y0; - jump.view_min = position.y1 - scroll_region.y0 - region_h; - jump.view_max = position.y0 - scroll_region.y0; - return(jump); -} - -internal GUI_Scroll_Vars -gui_do_jump(GUI_Target *target, GUI_View_Jump jump, GUI_Scroll_Vars vars){ - if (jump.view_max < 0){ - jump.view_max = 0; - } - if (jump.view_min < 0){ - jump.view_min = 0; - } - if (vars.target_y < jump.view_min){ - vars.target_y = jump.view_min; - } - else if (vars.target_y > jump.view_max){ - vars.target_y = jump.view_max; - } - return(vars); -} - -internal void -gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, Key_Code user_up_key, Key_Modifier user_up_key_modifier, Key_Code user_down_key, Key_Modifier user_down_key_modifier){ - if (update->has_adjustment){ - *list_i = update->adjustment_value; - } - - if (update->has_index_position){ - GUI_View_Jump jump = gui_compute_view_jump(scroll_region, update->index_position); - jump.view_min = jump.view_min + 45; - jump.view_max = jump.view_max - 45; - *vars = gui_do_jump(target, jump, *vars); - } - - i8 modifiers_up[3]; - modifiers_up[0] = ((user_up_key_modifier & MDFR_CTRL) != 0); - modifiers_up[1] = ((user_up_key_modifier & MDFR_ALT) != 0); - modifiers_up[2] = ((user_up_key_modifier & MDFR_SHIFT) != 0); - - i8 modifiers_down[3]; - modifiers_down[0] = ((user_down_key_modifier & MDFR_CTRL) != 0); - modifiers_down[1] = ((user_down_key_modifier & MDFR_ALT) != 0); - modifiers_down[2] = ((user_down_key_modifier & MDFR_SHIFT) != 0); - - b32 indirectly_activate = 0; - for (i32 j = 0; j < keys->count; ++j){ - Key_Event_Data key = keys->keys[j]; - b32 modifiers_match_up = false; - b32 modifiers_match_down = false; - - if (modifiers_up[0] == key.modifiers[MDFR_CONTROL_INDEX] && modifiers_up[1] == key.modifiers[MDFR_ALT_INDEX] && modifiers_up[2] == key.modifiers[MDFR_SHIFT_INDEX]){ - modifiers_match_up = true; - } - - if (modifiers_down[0] == key.modifiers[MDFR_CONTROL_INDEX] && modifiers_down[1] == key.modifiers[MDFR_ALT_INDEX] && modifiers_down[2] == key.modifiers[MDFR_SHIFT_INDEX]){ - modifiers_match_down = true; - } - - if (key.keycode == user_up_key && modifiers_match_up){ - --*list_i; - } - else if (key.keycode == user_down_key && modifiers_match_down){ - ++*list_i; - } - - else if (key.keycode == '\n' || key.keycode == '\t'){ - indirectly_activate = 1; - } - } - - gui_rollback(target, update); - gui_begin_list(target, id, *list_i, indirectly_activate, 0, 0); -} - // BOTTOM diff --git a/4ed_gui.h b/4ed_gui.h index d1f705b4..3a65a40f 100644 --- a/4ed_gui.h +++ b/4ed_gui.h @@ -12,10 +12,6 @@ #ifndef FRED_GUI_H #define FRED_GUI_H -struct GUI_id{ - u64 id[2]; -}; - struct Query_Slot{ Query_Slot *next; Query_Bar *query_bar; @@ -27,143 +23,6 @@ struct Query_Set{ Query_Slot *used_slot; }; -struct Super_Color{ - Vec4 hsla; - Vec4 rgba; - u32 *out; -}; - -struct GUI_Target{ - Partition push; - - GUI_id active; - GUI_id mouse_hot; - GUI_id auto_hot; - GUI_id hover; - - // TODO(allen): Can we remove original yet? - GUI_Scroll_Vars scroll_original; - i32_Rect region_original; - - //GUI_Scroll_Vars scroll_updated; - i32_Rect region_updated; - - // TODO(allen): Would rather have a way of tracking this - // for more than one list. Perhaps just throw in a hash table? - // Or maybe this only needs to be tracked for the active list. - i32 list_max; - b32 has_list_index_position; - i32_Rect list_index_position; - i32 list_view_min; - i32 list_view_max; - - GUI_id scroll_id; - // TODO(allen): is currently ignored in the wheel code, reevaluate? - i32 delta; - b32 has_keys; - b32 animating; - b32 did_file; -}; - -struct GUI_Item_Update{ - i32 partition_point; - - b32 has_adjustment; - i32 adjustment_value; - - b32 has_index_position; - i32_Rect index_position; -}; - -struct GUI_Header{ - i32 type; - i32 size; -}; - -struct GUI_Interactive{ - GUI_Header h; - GUI_id id; -}; - -struct GUI_Edit{ - GUI_Header h; - GUI_id id; - void *out; -}; - -enum GUI_Command_Type{ - guicom_null, - guicom_begin_serial, - guicom_end_serial, - guicom_top_bar, - guicom_file, - guicom_text_field, - guicom_color_button, - guicom_text_with_cursor, - guicom_begin_list, - guicom_end_list, - guicom_file_option, - guicom_fixed_option, - guicom_button, - guicom_fixed_option_checkbox, - guicom_style_preview, - guicom_scrollable, - guicom_scrollable_bar, - guicom_scrollable_top, - guicom_scrollable_slider, - guicom_scrollable_bottom, - guicom_scrollable_invisible, - guicom_begin_scrollable_section, - guicom_end_scrollable_section, -}; - -struct GUI_Section{ - i32 max_v, v, top_v; -}; - -struct GUI_List_Vars{ - b32 in_list; - i32 index; - i32 auto_hot; - i32 auto_activate; -}; - -struct GUI_Session{ - i32_Rect full_rect; - i32_Rect rect; - - i32 suggested_max_y; - i32 clip_y; - - i32 line_height; - b32 is_scrollable; - i32 scrollable_items_bottom; - - i32_Rect scroll_region; - i32_Rect scroll_rect; - f32 scroll_top, scroll_bottom; - - GUI_List_Vars list; - - GUI_Section sections[64]; - i32 t; -}; - -struct GUI_Interpret_Result{ - b32 has_info; - b32 auto_hot; - b32 auto_activate; - i32 screen_orientation; - - b32 has_region; - i32_Rect region; -}; - -struct GUI_View_Jump{ - i32 view_min; - i32 view_max; -}; - #endif // BOTTOM diff --git a/4ed_style.cpp b/4ed_style.cpp index fe8b372f..c2f4a3cd 100644 --- a/4ed_style.cpp +++ b/4ed_style.cpp @@ -20,24 +20,21 @@ style_set_colors(Style *style, Theme *theme){ internal u32 style_get_margin_color(i32 active_level, Style *style){ u32 margin = 0xFFFFFFFF; - switch (active_level){ default: + case UIActivation_None: { margin = style->main.list_item_color; }break; - - case 1: case 2: + case UIActivation_Hover: { margin = style->main.list_item_hover_color; }break; - - case 3: case 4: + case UIActivation_Active: { margin = style->main.list_item_active_color; }break; } - return(margin); } diff --git a/4ed_view.cpp b/4ed_view.cpp index 5ca75d22..d5590f87 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -30,12 +30,6 @@ live_set_alloc_view(General_Memory *general, Live_Views *live_set, Panel *panel) init_query_set(&result.view->transient.query_set); - i32 gui_mem_size = KB(512); - void *gui_mem = general_memory_allocate(general, gui_mem_size + 8); - result.view->transient.gui_mem = gui_mem; - gui_mem = advance_to_alignment(gui_mem); - result.view->transient.gui_target.push = make_part(gui_mem, gui_mem_size); - dynamic_variables_block_init(general, &result.view->transient.dynamic_vars); return(result); @@ -46,8 +40,10 @@ live_set_free_view(General_Memory *general, Live_Views *live_set, View *view){ Assert(live_set->count > 0); --live_set->count; - general_memory_free(general, view->transient.gui_mem); - view->transient.gui_mem = 0; + if (view->transient.ui_control.items != 0){ + general_memory_free(general, view->transient.ui_control.items); + } + //dll_insert(&live_set->free_sentinel, view); view->transient.next = live_set->free_sentinel.transient.next; view->transient.prev = &live_set->free_sentinel; @@ -98,7 +94,7 @@ view_get_cursor_xy(View *view){ internal f32 view_get_scroll_y(View *view){ f32 v = 0; - if (view->transient.showing_ui == VUI_None){ + if (view->transient.ui_mode_counter == 0){ File_Edit_Positions *edit_pos = view->transient.edit_pos; TentativeAssert(edit_pos != 0); if (edit_pos != 0){ @@ -106,7 +102,9 @@ view_get_scroll_y(View *view){ } } else{ +#if 0 v = view->transient.gui_scroll.scroll_y; +#endif } return(v); } @@ -158,11 +156,10 @@ inline u32 view_lock_flags(View *view){ u32 result = AccessOpen; File_Viewing_Data *data = &view->transient.file_data; - if (view->transient.showing_ui != VUI_None){ + if (view->transient.ui_mode_counter > 0){ result |= AccessHidden; } - if (data->file_locked || - (data->file && data->file->settings.read_only)){ + if (data->file_locked || (data->file && data->file->settings.read_only)){ result |= AccessProtected; } return(result); @@ -348,25 +345,6 @@ view_show_file(View *view){ Editing_File *file = view->transient.file_data.file; Assert(file != 0); view->transient.map = file->settings.base_map_id; - if (view->transient.showing_ui != VUI_None){ - view->transient.showing_ui = VUI_None; - view->transient.changed_context_in_step = 1; - } -} - -inline void -view_show_interactive(System_Functions *system, View *view, Models *models, Interactive_Action action, Interactive_Interaction interaction, String query){ - view->transient.showing_ui = VUI_Interactive; - view->transient.action = action; - view->transient.interaction = interaction; - view->transient.dest = make_fixed_width_string(view->transient.dest_); - view->transient.list_i = 0; - - view->transient.map = mapid_ui; - - hot_directory_clean_end(&models->hot_directory); - hot_directory_reload(system, &models->hot_directory); - view->transient.changed_context_in_step = true; } internal void @@ -397,7 +375,7 @@ view_set_file(System_Functions *system, Models *models, View *view, Editing_File view_cursor_move(system, view, 0); } - if (view->transient.showing_ui == VUI_None){ + if (view->transient.ui_mode_counter == 0){ view_show_file(view); } } diff --git a/4ed_view.h b/4ed_view.h index 2b7cdc63..2676c278 100644 --- a/4ed_view.h +++ b/4ed_view.h @@ -30,55 +30,6 @@ struct File_Viewing_Data{ }; global File_Viewing_Data null_file_viewing_data = {0}; -enum Interactive_Action{ - IAct_Open, - IAct_New, - IAct_OpenOrNew, - IAct_Switch, - IAct_Kill, - IAct_Sure_To_Kill, - IAct_Sure_To_Close -}; - -typedef i32 Unsaved_Changes_User_Response; -enum{ - UnsavedChangesUserResponse_Error = -1, - UnsavedChangesUserResponse_ContinueAnyway = 0, - UnsavedChangesUserResponse_Cancel = 1, - UnsavedChangesUserResponse_SaveAndContinue = 2, -}; - -typedef i32 Interactive_Interaction; -enum{ - IInt_Sys_File_List = 0, - IInt_Live_File_List = 1, - IInt_Sure_To_Kill = 2, - IInt_Sure_To_Close = 3 -}; - -typedef i32 View_UI; -enum{ - VUI_None = 0, - VUI_Theme = 1, - VUI_Interactive = 2, -}; - -typedef i32 Color_View_Mode; -enum{ - CV_Mode_Library = 0, - CV_Mode_Font = 1, - CV_Mode_Global_Font = 2, - CV_Mode_Font_Editing = 3, - CV_Mode_Global_Font_Editing = 4, - CV_Mode_Adjusting = 5, -}; - -struct Scroll_Context{ - Editing_File *file; - GUI_id scroll; - View_UI mode; -}; - struct View_Transient{ struct View *next; struct View *prev; @@ -95,37 +46,14 @@ struct View_Transient{ i32_Rect scroll_region; File_Edit_Positions *edit_pos; - View_UI showing_ui; - GUI_Target gui_target; - void *gui_mem; - GUI_Scroll_Vars gui_scroll; - i32 gui_max_y; - i32 list_i; + i32 ui_mode_counter; + UI_Control ui_control; b32 hide_scrollbar; b32 hide_file_bar; - // interactive stuff - Interactive_Interaction interaction; - Interactive_Action action; - - char dest_[256]; - String dest; - b32 changed_context_in_step; - // theme stuff - u32 *palette; - Color_View_Mode color_mode; - Face_ID font_edit_id; - Super_Color color; - b32 p4c_only; - Style_Library inspecting_styles; - b8 import_export_check[64]; - i32 import_file_id; - i32 current_color_editing; - i32 color_cursor; - // misc // TODO(allen): Can we burn line_height to the ground now? diff --git a/4ed_view_ui.cpp b/4ed_view_ui.cpp index 827e82b8..ad585546 100644 --- a/4ed_view_ui.cpp +++ b/4ed_view_ui.cpp @@ -26,133 +26,7 @@ interactive_try_kill_file(System_Functions *system, Models *models, Editing_File internal void interactive_begin_sure_to_kill(System_Functions *system, View *view, Models *models, Editing_File *file){ - view_show_interactive(system, view, models, IAct_Sure_To_Kill, IInt_Sure_To_Kill, lit("Are you sure?")); - copy(&view->transient.dest, file->unique_name.name); -} - -internal void -interactive_view_complete(System_Functions *system, View *view, Models *models, String dest, i32 user_action){ - switch (view->transient.action){ - case IAct_Open: - { - Editing_File *file = open_file(system, models, dest); - if (file != 0){ - view_set_file(system, models, view, file); - } - view_show_file(view); - }break; - - case IAct_New: - { - if (dest.size > 0 && !char_is_slash(dest.str[dest.size-1])){ - Editing_File *file = 0; - Editing_File_Name canon_name = {0}; - - if (terminate_with_null(&dest) && - get_canon_name(system, dest, &canon_name)){ - Working_Set *working_set = &models->working_set; - file = working_set_contains_canon(working_set, canon_name.name); - if (file == 0){ - Mem_Options *mem = &models->mem; - General_Memory *general = &mem->general; - Partition *part = &mem->part; - - file = working_set_alloc_always(working_set, general); - buffer_bind_file(system, general, working_set, file, canon_name.name); - buffer_bind_name(models, general, part, working_set, file, front_of_directory(dest)); - - init_normal_file(system, models, 0, 0, file); - } - else{ - edit_clear(system, models, file); - } - } - if (file != 0){ - view_set_file(system, models, view, file); - } - view_show_file(view); - if (file != 0 && models->hook_new_file != 0){ - models->hook_new_file(&models->app_links, file->id.id); - } - } - }break; - - case IAct_Switch: - { - Editing_File *file = working_set_contains_name(&models->working_set, dest); - if (file){ - view_set_file(system, models, view, file); - } - view_show_file(view); - }break; - - case IAct_Kill: - { - b32 kill_dialogue = false; - Editing_File *file = working_set_contains_name(&models->working_set, dest); - if (file != 0){ - kill_dialogue = (interactive_try_kill_file(system, models, file) == TryKill_NeedDialogue); - if (kill_dialogue){ - interactive_begin_sure_to_kill(system, view, models, file); - } - } - if (!kill_dialogue){ - view_show_file(view); - } - }break; - - case IAct_Sure_To_Close: - { - switch (user_action){ - case UnsavedChangesUserResponse_ContinueAnyway: - { - models->keep_playing = false; - }break; - - case UnsavedChangesUserResponse_Cancel: - { - view_show_file(view); - }break; - - // TODO(allen): Save all and close. - case UnsavedChangesUserResponse_SaveAndContinue: InvalidCodePath; - default: InvalidCodePath; - } - }break; - - case IAct_Sure_To_Kill: - { - switch (user_action){ - case UnsavedChangesUserResponse_ContinueAnyway: - { - Editing_File *file = working_set_contains_name(&models->working_set, dest); - if (file != 0){ - kill_file_and_update_views(system, models, file); - } - view_show_file(view); - }break; - - case UnsavedChangesUserResponse_Cancel: - { - view_show_file(view); - }break; - - case UnsavedChangesUserResponse_SaveAndContinue: - { - Editing_File *file = working_set_contains_name(&models->working_set, dest); - if (file != 0){ - save_file(system, models, file); - kill_file_and_update_views(system, models, file); - } - view_show_file(view); - }break; - - default: InvalidCodePath; - } - }break; - - case IAct_OpenOrNew: InvalidCodePath; - } + } //////////////////////////////// @@ -271,1040 +145,74 @@ global_const Style_Color_Edit colors_to_edit[] = { {Stag_Pop2, Stag_Pop2, Stag_Bar, lit("Bar Pop 2")}, }; -internal View_Step_Result -step_view(System_Functions *system, View *view, Models *models, View *active_view, Input_Summary input){ - View_Step_Result result = {0}; - GUI_Target *target = &view->transient.gui_target; - Key_Input_Data keys = input.keys; - - b32 show_scrollbar = !view->transient.hide_scrollbar; - - if (view->transient.showing_ui != VUI_None){ - b32 did_esc = false; - for (i32 i = 0; i < keys.count; ++i){ - Key_Event_Data key = keys.keys[i]; - if (key.keycode == key_esc){ - did_esc = 1; - break; - } - } - - if (did_esc){ - view_show_file(view); - result.consume_esc = true; - } - } - - gui_begin_top_level(target, input); - if (!view->transient.hide_file_bar){ - gui_do_top_bar(target); - } - - // NOTE(allen): A temporary measure... although in - // general we maybe want the user to be able to ask - // how large a particular section of the GUI turns - // out to be after layout? - i32 bar_count = 0; - for (Query_Slot *slot = view->transient.query_set.used_slot; - slot != 0; - slot = slot->next, ++bar_count){ - Query_Bar *bar = slot->query_bar; - gui_do_text_field(target, bar->prompt, bar->string); - } - view->transient.widget_height = (f32)bar_count*(view->transient.line_height + 2); - - Editing_File *file = view->transient.file_data.file; - Assert(file != 0); - Assert(view->transient.edit_pos != 0); - - switch (view->transient.showing_ui){ - case VUI_None: - { - gui_begin_serial_section(target); - - i32 delta = 9*view->transient.line_height; - GUI_id scroll_context = gui_id((u64)(file), view->transient.showing_ui); - - GUI_Scroll_Vars *scroll = &view->transient.edit_pos->scroll; - gui_begin_scrollable(target, scroll_context, *scroll, - delta, show_scrollbar); - gui_do_file(target); - gui_end_scrollable(target); - - gui_end_serial_section(target); - }break; - - case VUI_Theme: - { - u64 high_id = VUI_Theme + ((u64)view->transient.color_mode << 32); - GUI_id scroll_context = gui_id(0, high_id); - - switch (view->transient.color_mode){ - case CV_Mode_Library: - { - gui_do_text_field(target, lit("Current Theme - Click to Edit"), make_string(0, 0)); - - if (gui_do_style_preview(target, gui_id((u64)(&models->styles.styles[0]), high_id), 0)){ - view->transient.color_mode = CV_Mode_Adjusting; - } - - if (gui_do_button(target, gui_id((u64)(&file->settings.font_id), high_id), lit("Set Font"))){ - view->transient.color_mode = CV_Mode_Font; - } - - if (gui_do_button(target, gui_id((u64)(&models->global_font_id), high_id), lit("Set Global Font"))){ - view->transient.color_mode = CV_Mode_Global_Font; - } - - gui_do_text_field(target, lit("Theme Library - Click to Select"), make_string(0, 0)); - - gui_begin_scrollable(target, scroll_context, view->transient.gui_scroll, - 9*view->transient.line_height, show_scrollbar); - - Style *style = models->styles.styles + 1; - i32 count = models->styles.count; - for (i32 i = 1; i < count; ++i, ++style){ - if (gui_do_style_preview(target, gui_id((u64)(style), high_id), i)){ - style_copy(&models->styles.styles[0], style); - } - } - - gui_end_scrollable(target); - }break; - - case CV_Mode_Font: - case CV_Mode_Global_Font: - { - if (gui_do_button(target, gui_id(1, high_id), lit("Back"))){ - view->transient.color_mode = CV_Mode_Library; - } - - gui_begin_scrollable(target, scroll_context, view->transient.gui_scroll, 9*view->transient.line_height, show_scrollbar); - - Face_ID font_id = file->settings.font_id; - Face_ID new_font_id = 0; - - Face_ID largest_id = system->font.get_largest_id(); - for (Face_ID i = 1; i <= largest_id; ++i){ - Font_Pointers font = system->font.get_pointers_by_id(i); - if (font.valid){ - Font_Settings *settings = font.settings; - Font_Metrics *metrics = font.metrics; - - char space[512]; - String m = make_fixed_width_string(space); - if (i == font_id){ - append(&m, "*"); - } - - append(&m, " \""); - append(&m, make_string(metrics->name, metrics->name_len)); - append(&m, "\" "); - append_int_to_str(&m, settings->parameters.pt_size); - append(&m, " "); - append(&m, (char*)(settings->parameters.italics?"italics ":"")); - append(&m, (char*)(settings->parameters.bold?"bold ":"")); - append(&m, (char*)(settings->parameters.underline?"underline ":"")); - append(&m, (char*)(settings->parameters.use_hinting?"hinting ":"")); - - if (i == font_id){ - append(&m, "*"); - } - - if (gui_do_button(target, gui_id(i*2, high_id), m)){ - if (new_font_id == 0){ - new_font_id = i; - } - } - - if (gui_do_button(target, gui_id(i*2 + 1, high_id), lit("edit"))){ - view->transient.font_edit_id = i; - if (view->transient.color_mode == CV_Mode_Font){ - view->transient.color_mode = CV_Mode_Font_Editing; - } - else{ - view->transient.color_mode = CV_Mode_Global_Font_Editing; - } - } - } - } - - if (gui_do_button(target, gui_id(largest_id*2 + 2, high_id), lit("new face"))){ - if (new_font_id == 0){ - Font_Pointers font = system->font.get_pointers_by_id(font_id); - view->transient.font_edit_id = system->font.face_allocate_and_init(font.settings); - if (view->transient.color_mode == CV_Mode_Font){ - view->transient.color_mode = CV_Mode_Font_Editing; - } - else{ - view->transient.color_mode = CV_Mode_Global_Font_Editing; - } - } - } - - if (new_font_id != 0){ - if (view->transient.color_mode == CV_Mode_Font && new_font_id != font_id){ - file_set_font(system, models, file, new_font_id); - } - else if (new_font_id != font_id || new_font_id != models->global_font_id){ - global_set_font_and_update_files(system, models, new_font_id); - } - } - - gui_end_scrollable(target); - }break; - - case CV_Mode_Font_Editing: - case CV_Mode_Global_Font_Editing: - { - i32 low_id = 1; - if (gui_do_button(target, gui_id(low_id++, high_id), lit("Back"))){ - if (view->transient.color_mode == CV_Mode_Font_Editing){ - view->transient.color_mode = CV_Mode_Font; - } - else{ - view->transient.color_mode = CV_Mode_Global_Font; - } - } - - gui_begin_scrollable(target, scroll_context, view->transient.gui_scroll, 9*view->transient.line_height, show_scrollbar); - - Face_ID font_edit_id = view->transient.font_edit_id; - Font_Pointers font = system->font.get_pointers_by_id(font_edit_id); - Font_Settings *settings = font.settings; - Font_Metrics *metrics = font.metrics; - Font_Settings new_settings = *settings; - b32 has_new_settings = false; - - char space[128]; - String m = make_fixed_width_string(space); - copy(&m, "Size Up ("); - append_int_to_str(&m, settings->parameters.pt_size); - append(&m, ")"); - if (gui_do_button(target, gui_id(low_id++, high_id), m)){ - if (!has_new_settings){ - has_new_settings = true; - ++new_settings.parameters.pt_size; - } - } - - copy(&m, "Size Down ("); - append_int_to_str(&m, settings->parameters.pt_size); - append(&m, ")"); - if (gui_do_button(target, gui_id(low_id++, high_id), m)){ - if (!has_new_settings){ - has_new_settings = true; - --new_settings.parameters.pt_size; - } - } - - copy(&m, "Italics ["); - append(&m, (char*)(settings->parameters.italics?"+":" ")); - append(&m, "]"); - if (gui_do_button(target, gui_id(low_id++, high_id), m)){ - if (!has_new_settings){ - has_new_settings = true; - new_settings.parameters.italics = !new_settings.parameters.italics; - } - } - - copy(&m, "Bold ["); - append(&m, (char*)(settings->parameters.bold?"+":" ")); - append(&m, "]"); - if (gui_do_button(target, gui_id(low_id++, high_id), m)){ - if (!has_new_settings){ - has_new_settings = true; - new_settings.parameters.bold = !new_settings.parameters.bold; - } - } - - copy(&m, "Underline ["); - append(&m, (char*)(settings->parameters.underline?"+":" ")); - append(&m, "]"); - if (gui_do_button(target, gui_id(low_id++, high_id), m)){ - if (!has_new_settings){ - has_new_settings = true; - new_settings.parameters.underline = !new_settings.parameters.underline; - } - } - - copy(&m, "Hinting ["); - append(&m, (char*)(settings->parameters.use_hinting?"+":" ")); - append(&m, "]"); - if (gui_do_button(target, gui_id(low_id++, high_id), m)){ - if (!has_new_settings){ - has_new_settings = true; - new_settings.parameters.use_hinting = !new_settings.parameters.use_hinting; - } - } - - copy(&m, "Current Family: "); - append(&m, make_string(metrics->name, metrics->name_len)); - gui_do_button(target, gui_id(low_id++, high_id), m); - - i32 total_count = system->font.get_loadable_count(); - for (i32 i = 0; i < total_count; ++i){ - Font_Loadable_Description loadable = {0}; - system->font.get_loadable(i, &loadable); - - if (loadable.valid){ - String name = make_string(loadable.display_name, loadable.display_len); - if (gui_do_button(target, gui_id(low_id++, high_id), name)){ - if (!has_new_settings){ - has_new_settings = true; - memcpy(&new_settings.stub, &loadable.stub, sizeof(loadable.stub)); - } - } - } - } - - gui_end_scrollable(target); - - if (has_new_settings){ - alter_font_and_update_files(system, models, font_edit_id, &new_settings); - } - }break; - - case CV_Mode_Adjusting: - { - if (gui_do_button(target, gui_id(1, high_id), lit("Back"))){ - view->transient.color_mode = CV_Mode_Library; - } - - gui_begin_scrollable(target, scroll_context, view->transient.gui_scroll, 9*view->transient.line_height, show_scrollbar); - - i32 next_color_editing = view->transient.current_color_editing; - - Style *style = &models->styles.styles[0]; - for (i32 i = 0; i < ArrayCount(colors_to_edit); ++i){ - u32 *edit_color = style_index_by_tag(&style->main, colors_to_edit[i].target); - - u32 *fore = style_index_by_tag(&style->main, colors_to_edit[i].fore); - u32 *back = style_index_by_tag(&style->main, colors_to_edit[i].back); - - if (gui_do_color_button(target, gui_id((u64)(edit_color), high_id), - *fore, *back, colors_to_edit[i].text)){ - next_color_editing = i; - view->transient.color_cursor = 0; - } - - if (view->transient.current_color_editing == i){ - GUI_Item_Update update = {0}; - char text_space[7]; - String text = make_fixed_width_string(text_space); - - color_to_hexstr(&text, *edit_color); - if (gui_do_text_with_cursor(target, view->transient.color_cursor, text, &update)){ - b32 rollback = false; - - for (i32 j = 0; j < keys.count; ++j){ - Key_Code key = keys.keys[j].keycode; - b32 set_consume_keys = true; - switch (key){ - case key_left: - { - --view->transient.color_cursor; - rollback = true; - }break; - - case key_right: - { - ++view->transient.color_cursor; - rollback = true; - }break; - - case key_up: - { - --next_color_editing; - }break; - - case key_down: - { - ++next_color_editing; - }break; - - default: - { - if (char_is_hex((char)key)){ - text.str[view->transient.color_cursor] = (char)key; - rollback = true; - } - else{ - set_consume_keys = false; - } - }break; - } - result.consume_keys = result.consume_keys || set_consume_keys; - view->transient.color_cursor = clamp(0, view->transient.color_cursor, 5); - next_color_editing = clamp((i32)(0), next_color_editing, (i32)(ArrayCount(colors_to_edit) - 1)); - } - - if (rollback){ - hexstr_to_color(text, edit_color); - gui_rollback(target, &update); - gui_do_text_with_cursor(target, view->transient.color_cursor, text, 0); - } - } - } - } - - if (view->transient.current_color_editing != next_color_editing){ - view->transient.current_color_editing = next_color_editing; - view->transient.color_cursor = 0; - } - - gui_end_scrollable(target); - }break; - } - }break; - - case VUI_Interactive: - { - b32 complete = 0; - char comp_dest_space[1024]; - String comp_dest = make_fixed_width_string(comp_dest_space); - i32 comp_action = 0; - - u64 high_id = VUI_Interactive + ((u64)view->transient.interaction << 32); - GUI_id scroll_context = gui_id(0, high_id); - - Key_Code user_up_key = models->user_up_key; - Key_Code user_down_key = models->user_down_key; - Key_Modifier user_up_key_modifier = models->user_up_key_modifier; - Key_Modifier user_down_key_modifier = models->user_down_key_modifier; - - switch (view->transient.interaction){ - case IInt_Sys_File_List: - { - b32 autocomplete_with_enter = true; - b32 activate_directly = false; - - if (view->transient.action == IAct_New){ - autocomplete_with_enter = false; - } - - GUI_Item_Update update = {0}; - Hot_Directory *hdir = &models->hot_directory; - - b32 do_open_or_new = false; - for (i32 i = 0; i < keys.count; ++i){ - Key_Event_Data key = keys.keys[i]; - Single_Line_Input_Step step = app_single_file_input_step(system, &models->working_set, key, - &hdir->string, hdir); - - if (step.made_a_change){ - view->transient.list_i = 0; - result.consume_keys = true; - } - - if (key.keycode == '\n'){ - if (!autocomplete_with_enter){ - activate_directly = true; - result.consume_keys = true; - } - else if (view->transient.action == IAct_OpenOrNew){ - do_open_or_new = true; - result.consume_keys = true; - } - } - } - - { - String message = {0}; - switch (view->transient.action){ - case IAct_OpenOrNew: - case IAct_Open: - { - message = lit("Open: "); - }break; - - case IAct_New: - { - message = lit("New: "); - }break; - } - - gui_do_text_field(target, message, hdir->string); - } - - b32 snap_into_view = false; - scroll_context.id[0] = (u64)(hdir); - if (gui_scroll_was_activated(target, scroll_context)){ - snap_into_view = true; - } - gui_begin_scrollable(target, scroll_context, view->transient.gui_scroll, 9*view->transient.line_height, show_scrollbar); - - GUI_id list_id = gui_id((u64)(hdir) + 1, high_id); - if (gui_begin_list(target, list_id, - view->transient.list_i, 0, snap_into_view, &update)){ - // TODO(allen): Allow me to handle key consumption correctly here! - gui_standard_list(target, list_id, &view->transient.gui_scroll, view->transient.scroll_region, &keys, &view->transient.list_i, &update, user_up_key, user_up_key_modifier, user_down_key, user_down_key_modifier); - } - - b32 do_new_directory = false; - - Working_Set *working_set = &models->working_set; - - char full_path_space[256]; - String full_path = make_fixed_width_string(full_path_space); - copy(&full_path, hdir->canon_dir); - - char front_name_space[256]; - String front_name = make_fixed_width_string(front_name_space); - copy(&front_name, front_of_directory(hdir->string)); - - Absolutes absolutes; - get_absolutes(front_name, &absolutes, true, true); - - i32 full_path_restore = full_path.size; - - File_Info *info_ptr = hdir->file_list.infos; - i32 file_count = hdir->file_list.count; - for (i32 i = 0; i < file_count; ++i, ++info_ptr){ - - full_path.size = full_path_restore; - append(&full_path, info_ptr->filename); - terminate_with_null(&full_path); - - char *str = info_ptr->filename; - i32 len = info_ptr->filename_len; - String filename = make_string_cap(str, len, len + 1); - b32 is_folder = info_ptr->folder; - - if (wildcard_match_s(&absolutes, filename, false)){ - Editing_File *file_ptr = working_set_contains_canon(working_set, full_path); - - String message = {0}; - if (file_ptr != 0 && file_is_ready(file_ptr)){ - switch (file_ptr->state.dirty){ - case DirtyState_UpToDate: - { - message = lit(" LOADED"); - }break; - - case DirtyState_UnsavedChanges: - { - message = lit(" LOADED *"); - }break; - - case DirtyState_UnloadedChanges: - { - message = lit(" LOADED !"); - }break; - - default: InvalidCodePath; - } - } - - if (gui_do_file_option(target, gui_id((u64)(info_ptr), high_id), filename, is_folder, message)){ - if (is_folder){ - set_last_folder(&hdir->string, info_ptr->filename, '/'); - do_new_directory = true; - } - - else if (autocomplete_with_enter){ - complete = true; - copy(&comp_dest, full_path); - if (view->transient.action == IAct_OpenOrNew){ - view->transient.action = IAct_Open; - } - } - } - - if (do_open_or_new){ - do_open_or_new = false; - } - } - } - - gui_end_list(target); - - if (activate_directly || do_open_or_new){ - complete = true; - copy(&comp_dest, hdir->string); - if (do_open_or_new){ - view->transient.action = IAct_New; - } - } - - if (do_new_directory){ - hot_directory_reload(system, hdir); - } - - gui_end_scrollable(target); - }break; - - case IInt_Live_File_List: - { - Working_Set *working_set = &models->working_set; - Editing_Layout *layout = &models->layout; - GUI_Item_Update update = {0}; - - for (i32 i = 0; i < keys.count; ++i){ - Key_Event_Data key = keys.keys[i]; - Single_Line_Input_Step step = app_single_line_input_step(system, key, &view->transient.dest); - if (step.made_a_change){ - view->transient.list_i = 0; - result.consume_keys = 1; - } - } - - Absolutes absolutes = {0}; - get_absolutes(view->transient.dest, &absolutes, 1, 1); - - { - String message = {0}; - switch (view->transient.action){ - case IAct_Switch: - { - message = lit("Switch: "); - }break; - - case IAct_Kill: - { - message = lit("Kill: "); - }break; - } - gui_do_text_field(target, message, view->transient.dest); - } - - b32 snap_into_view = 0; - scroll_context.id[0] = (u64)(working_set); - if (gui_scroll_was_activated(target, scroll_context)){ - snap_into_view = 1; - } - gui_begin_scrollable(target, scroll_context, view->transient.gui_scroll, 9*view->transient.line_height, show_scrollbar); - - GUI_id list_id = gui_id((u64)(working_set) + 1, high_id); - if (gui_begin_list(target, list_id, view->transient.list_i, 0, snap_into_view, &update)){ - gui_standard_list(target, list_id, &view->transient.gui_scroll, view->transient.scroll_region, &keys, &view->transient.list_i, &update, user_up_key, user_up_key_modifier, user_down_key, user_down_key_modifier); - } - - File_Node *node = working_set->used_sentinel.next; - Assert(node != &working_set->used_sentinel); - - Partition *part = &models->mem.part; - Temp_Memory temp = begin_temp_memory(part); - partition_align(part, 8); - Editing_File **reserved_ptr = push_array(part, Editing_File*, 0); - Editing_File **reserved_end = 0; - - for (;reserved_ptr != reserved_end;){ - Editing_File *file_ptr = 0; - b32 emit_this_file = false; - - if (reserved_end == 0){ - file_ptr = (Editing_File*)node; - Assert(!file_ptr->is_dummy); - if (wildcard_match_s(&absolutes, file_ptr->unique_name.name, 0) != 0){ - if (file_is_viewed(layout, file_ptr) || file_ptr->unique_name.name.str[0] == '*'){ - Editing_File **reserved = push_array(part, Editing_File*, 1); - *reserved = file_ptr; - } - else{ - emit_this_file = true; - } - } - node = node->next; - if (node == &working_set->used_sentinel){ - reserved_end = push_array(part, Editing_File*, 0); - } - } - else{ - file_ptr = *reserved_ptr; - ++reserved_ptr; - emit_this_file = true; - } - - if (emit_this_file){ - String message = {0}; - switch (file_ptr->state.dirty){ - case DirtyState_UnsavedChanges: - { - message = lit(" *"); - }break; - - case DirtyState_UnloadedChanges: - { - message = lit(" !"); - }break; - } - if (gui_do_file_option(target, gui_id((u64)(file_ptr), high_id), file_ptr->unique_name.name, 0, message)){ - complete = true; - copy(&comp_dest, file_ptr->unique_name.name); - } - } - } - end_temp_memory(temp); - gui_end_list(target); - gui_end_scrollable(target); - }break; - - case IInt_Sure_To_Close: - { - Unsaved_Changes_User_Response response = UnsavedChangesUserResponse_Error; - - gui_do_text_field(target, lit("There are one or more files unsaved changes, close anyway?"), lit("")); - - if (gui_do_fixed_option(target, gui_id('y', high_id), lit("(Y)es"), 'y')){ - response = UnsavedChangesUserResponse_ContinueAnyway; - } - - if (gui_do_fixed_option(target, gui_id('n', high_id), lit("(N)o"), 'n')){ - response = UnsavedChangesUserResponse_Cancel; - } - - if (response != UnsavedChangesUserResponse_Error){ - complete = true; - copy(&comp_dest, view->transient.dest); - comp_action = response; - } - }break; - - case IInt_Sure_To_Kill: - { - Unsaved_Changes_User_Response response = UnsavedChangesUserResponse_Error; - - gui_do_text_field(target, lit("There are unsaved changes, close anyway?"), lit("")); - - if (gui_do_fixed_option(target, gui_id('y', high_id), lit("(Y)es"), 'y')){ - response = UnsavedChangesUserResponse_ContinueAnyway; - } - - if (gui_do_fixed_option(target, gui_id('n', high_id), lit("(N)o"), 'n')){ - response = UnsavedChangesUserResponse_Cancel; - } - - if (gui_do_fixed_option(target, gui_id('s', high_id), lit("(S)ave and kill"), 's')){ - response = UnsavedChangesUserResponse_SaveAndContinue; - } - - if (response != UnsavedChangesUserResponse_Error){ - complete = true; - copy(&comp_dest, view->transient.dest); - comp_action = response; - } - }break; - } - - if (complete){ - terminate_with_null(&comp_dest); - interactive_view_complete(system, view, models, comp_dest, comp_action); - } - }break; - } - gui_end_top_level(target); - - result.animating = target->animating; - return(result); -} - -internal b32 -click_button_input(GUI_Target *target, GUI_Session *session, b32 in_scroll, i32_Rect scroll_rect, Input_Summary *user_input, GUI_Interactive *b, b32 *is_animating){ - b32 result = false; - i32 mx = user_input->mouse.x; - i32 my = user_input->mouse.y; - - b32 in_sub_region = true; - if (in_scroll && !hit_check(mx, my, scroll_rect)){ - in_sub_region = false; - } - - if (in_sub_region && hit_check(mx, my, session->rect)){ - target->hover = b->id; - if (user_input->mouse.press_l){ - target->mouse_hot = b->id; - *is_animating = true; - result = true; - } - if (user_input->mouse.release_l && gui_id_eq(target->mouse_hot, b->id)){ - target->active = b->id; - memset(&target->mouse_hot, 0, sizeof(target->mouse_hot)); - *is_animating = true; - } - } - else if (gui_id_eq(target->hover, b->id)){ - memset(&target->hover, 0, sizeof(target->hover)); - } - - return(result); -} - -internal b32 -scroll_button_input(GUI_Target *target, GUI_Session *session, Input_Summary *user_input, GUI_id id, b32 *is_animating){ - b32 result = false; - i32 mx = user_input->mouse.x; - i32 my = user_input->mouse.y; - - if (hit_check(mx, my, session->rect)){ - target->hover = id; - if (user_input->mouse.l){ - target->mouse_hot = id; - gui_activate_scrolling(target); - *is_animating = true; - result = true; - } - } - else if (gui_id_eq(target->hover, id)){ - memset(&target->hover, 0, sizeof(target->hover)); - } - - return(result); -} - internal Input_Process_Result do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect rect, b32 is_active, Input_Summary *user_input, GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){ Input_Process_Result result = {0}; - b32 is_file_scroll = false; - - GUI_Session gui_session = {0}; - GUI_Header *h = 0; - GUI_Target *target = &view->transient.gui_target; - GUI_Interpret_Result interpret_result = {0}; vars.target_y = clamp(0, vars.target_y, max_y); result.vars = vars; result.region = region; - memset(&target->active, 0, sizeof(target->active)); + i32 line_height = view->transient.line_height; - // HACK(allen): UI sucks! Now just forcing it to - // not have the bug where it clicks buttons behind the - // header buttons before the scrollable section. - b32 in_scroll = false; - i32_Rect scroll_rect = {0}; - i32 prev_bottom = 0; + if (!view->transient.hide_file_bar){ + i32_Rect top_bar_rect = {0}; + top_bar_rect.x0 = rect.x0; + top_bar_rect.y0 = rect.y0; + top_bar_rect.x1 = rect.x1; + top_bar_rect.y1 = rect.y0 + line_height + 2; + rect.y0 = top_bar_rect.y1; + } - if (target->push.pos > 0){ - gui_session_init(&gui_session, target, rect, view->transient.line_height); + if (user_input->mouse.wheel != 0){ + result.vars.target_y += user_input->mouse.wheel; + result.vars.target_y = clamp(0, result.vars.target_y, max_y); + result.is_animating = true; + } + + if (view->transient.ui_mode_counter == 0){ + view->transient.file_region = rect; - for (h = (GUI_Header*)target->push.base; - h->type; - h = NextHeader(h)){ - interpret_result = gui_interpret(target, &gui_session, h, - result.vars, result.region, max_y); + Editing_File *file = view->transient.file_data.file; + if (view->transient.reinit_scrolling){ + view->transient.reinit_scrolling = false; + result.is_animating = true; - if (interpret_result.has_region){ - result.region = interpret_result.region; - } - - switch (h->type){ - case guicom_file_option: - case guicom_fixed_option: - case guicom_fixed_option_checkbox: - { - GUI_Interactive *b = (GUI_Interactive*)h; - - if (interpret_result.auto_activate){ - memset(&target->auto_hot, 0, sizeof(target->auto_hot)); - target->active = b->id; - result.is_animating = 1; - } - else if (interpret_result.auto_hot){ - if (!gui_id_eq(target->auto_hot, b->id)){ - target->auto_hot = b->id; - result.is_animating = 1; - } - } - }break; - } - - if (interpret_result.has_info){ - switch (h->type){ - case guicom_top_bar: break; - - case guicom_file: - { - // NOTE(allen): Set the file region first because the - // computation of view_compute_max_target_y depends on it. - view->transient.file_region = gui_session.rect; - - Editing_File *file = view->transient.file_data.file; - Assert(file != 0); - - if (view->transient.reinit_scrolling){ - view->transient.reinit_scrolling = false; - result.is_animating = true; - - i32 target_x = 0; - i32 target_y = 0; - if (file_is_ready(file)){ - Vec2 cursor = view_get_cursor_xy(view); - - f32 width = view_width(view); - f32 height = view_height(view); - - if (cursor.x >= target_x + width){ - target_x = round32(cursor.x - width*.35f); - } - - target_y = clamp_bottom(0, floor32(cursor.y - height*.5f)); - } - - result.vars.target_y = target_y; - result.vars.scroll_y = (f32)target_y; - result.vars.prev_target_y = -1000; - - result.vars.target_x = target_x; - result.vars.scroll_x = (f32)target_x; - result.vars.prev_target_x = -1000; - } - - if (!file->is_loading && file->state.paste_effect.seconds_down > 0.f){ - file->state.paste_effect.seconds_down -= user_input->dt; - result.is_animating = true; - } - - is_file_scroll = true; - }break; - - case guicom_color_button: - case guicom_button: - case guicom_file_option: - case guicom_style_preview: - { - GUI_Interactive *b = (GUI_Interactive*)h; - - if (click_button_input(target, &gui_session, in_scroll, scroll_rect, user_input, b, &result.is_animating)){ - result.consumed_l = true; - } - - prev_bottom = gui_session.rect.y1; - }break; - - case guicom_fixed_option: - case guicom_fixed_option_checkbox: - { - GUI_Interactive *b = (GUI_Interactive*)h; - - if (click_button_input(target, &gui_session, in_scroll, scroll_rect, user_input, b, &result.is_animating)){ - result.consumed_l = true; - } - - Key_Input_Data *keys = &user_input->keys; - - void *ptr = (b + 1); - String string = gui_read_string(&ptr); - AllowLocal(string); - - char activation_key = *(char*)ptr; - activation_key = char_to_upper(activation_key); - - if (activation_key != 0){ - i32 count = keys->count; - for (i32 i = 0; i < count; ++i){ - Key_Event_Data key = keys->keys[i]; - - u8 character[4]; - u32 length = 0; - if (key.character != 0){ - u32_to_utf8_unchecked(key.character, character, &length); - } - if (length == 1){ - if (char_to_upper(character[0]) == activation_key){ - target->active = b->id; - result.is_animating = 1; - break; - } - } - } - } - }break; - - case guicom_scrollable_slider: - { - GUI_id id = gui_id_scrollbar_slider(); - i32 mx = user_input->mouse.x; - i32 my = user_input->mouse.y; - f32 v = 0; - - if (hit_check(mx, my, gui_session.rect)){ - target->hover = id; - if (user_input->mouse.press_l){ - target->mouse_hot = id; - result.is_animating = 1; - result.consumed_l = 1; - } - } - else if (gui_id_eq(target->hover, id)){ - memset(&target->hover, 0, sizeof(target->hover)); - } - - if (gui_id_eq(target->mouse_hot, id)){ - v = unlerp(gui_session.scroll_top, (f32)my, - gui_session.scroll_bottom); - v = clamp(0.f, v, 1.f); - result.vars.target_y = round32(lerp(0.f, v, (f32)max_y)); - - gui_activate_scrolling(target); - result.is_animating = 1; - } - } - // NOTE(allen): NO BREAK HERE!! - - case guicom_scrollable_invisible: - { - if (user_input->mouse.wheel != 0){ - result.vars.target_y += user_input->mouse.wheel; - - result.vars.target_y = - clamp(0, result.vars.target_y, max_y); - gui_activate_scrolling(target); - result.is_animating = 1; - } - }break; - - case guicom_scrollable_top: - { - GUI_id id = gui_id_scrollbar_top(); - - if (scroll_button_input(target, &gui_session, user_input, id, &result.is_animating)){ - result.vars.target_y -= clamp_bottom(1, target->delta >> 2); - result.vars.target_y = clamp_bottom(0, result.vars.target_y); - result.consumed_l = 1; - } - }break; - - case guicom_scrollable_bottom: - { - GUI_id id = gui_id_scrollbar_bottom(); - - if (scroll_button_input(target, &gui_session, user_input, id, &result.is_animating)){ - result.vars.target_y += clamp_bottom(1, target->delta >> 2); - result.vars.target_y = clamp_top(result.vars.target_y, max_y); - result.consumed_l = 1; - } - }break; - - case guicom_begin_scrollable_section: - { - in_scroll = true; - scroll_rect.x0 = region.x0; - scroll_rect.y0 = prev_bottom; - scroll_rect.x1 = region.x1; - scroll_rect.y1 = region.y1; - }break; - - case guicom_end_scrollable_section: - { - in_scroll = false; - if (!is_file_scroll){ - result.has_max_y_suggestion = 1; - result.max_y = gui_session.suggested_max_y; - } - }break; + i32 target_x = 0; + i32 target_y = 0; + if (file_is_ready(file)){ + Vec2 cursor = view_get_cursor_xy(view); + + f32 width = view_width(view); + f32 height = view_height(view); + + if (cursor.x >= target_x + width){ + target_x = round32(cursor.x - width*.35f); } + + target_y = clamp_bottom(0, floor32(cursor.y - height*.5f)); } + + result.vars.target_y = target_y; + result.vars.scroll_y = (f32)target_y; + result.vars.prev_target_y = -1000; + + result.vars.target_x = target_x; + result.vars.scroll_x = (f32)target_x; + result.vars.prev_target_x = -1000; } - if (!user_input->mouse.l){ - if (!gui_id_is_null(target->mouse_hot)){ - memset(&target->mouse_hot, 0, sizeof(target->mouse_hot)); - result.is_animating = true; - } + if (!file->is_loading && file->state.paste_effect.seconds_down > 0.f){ + file->state.paste_effect.seconds_down -= user_input->dt; + result.is_animating = true; } + result.has_max_y_suggestion = true; + result.max_y = view_compute_max_target_y(view); + } + + { GUI_Scroll_Vars scroll_vars = result.vars; b32 is_new_target = (scroll_vars.target_x != scroll_vars.prev_target_x || scroll_vars.target_y != scroll_vars.prev_target_y); @@ -1461,125 +369,6 @@ draw_file_bar(System_Functions *system, Render_Target *target, View *view, Model } } -internal void -draw_color_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Face_ID font_id, i32_Rect rect, GUI_id id, u32 fore, u32 back, String text){ - i32 active_level = gui_active_level(gui_target, id); - - if (active_level > 0){ - Swap(u32, back, fore); - } - - draw_rectangle(target, rect, back); - draw_string(system, target, font_id, text, rect.x0, rect.y0 + 1, fore); -} - -internal void -draw_fat_option_block(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, GUI_id id, String text, String pop, i8 checkbox = -1){ - Style *style = &models->styles.styles[0]; - - i32 active_level = gui_active_level(gui_target, id); - - i32_Rect inner = get_inner_rect(rect, 3); - - u32 margin = style_get_margin_color(active_level, style); - u32 back = style->main.back_color; - u32 text_color = style->main.default_color; - u32 pop_color = style->main.file_info_style.pop2_color; - - i32 h = view->transient.line_height; - i32 x = inner.x0 + 3; - i32 y = inner.y0 + h/2 - 1; - - draw_rectangle(target, inner, back); - draw_margin(target, rect, inner, margin); - - if (checkbox != -1){ - u32 checkbox_color = style->main.margin_active_color; - i32_Rect checkbox_rect = get_inner_rect(inner, (inner.y1 - inner.y0 - h)/2); - checkbox_rect.x1 = checkbox_rect.x0 + (checkbox_rect.y1 - checkbox_rect.y0); - - if (checkbox == 0){ - draw_rectangle_outline(target, checkbox_rect, checkbox_color); - } - else{ - draw_rectangle(target, checkbox_rect, checkbox_color); - } - - x = checkbox_rect.x1 + 3; - } - - x = ceil32(draw_string(system, target, font_id, text, x, y, text_color)); - draw_string(system, target, font_id, pop, x, y, pop_color); -} - -internal void -draw_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, GUI_id id, String text){ - Style *style = &models->styles.styles[0]; - - i32 active_level = gui_active_level(gui_target, id); - - i32_Rect inner = get_inner_rect(rect, 3); - - u32 margin = style->main.default_color; - u32 back = style_get_margin_color(active_level, style); - u32 text_color = style->main.default_color; - - i32 h = view->transient.line_height; - i32 y = inner.y0 + h/2 - 1; - - i32 w = (i32)font_string_width(system, target, font_id, text); - i32 x = (inner.x1 + inner.x0 - w)/2; - - draw_rectangle(target, inner, back); - draw_rectangle_outline(target, inner, margin); - - draw_string(system, target, font_id, text, x, y, text_color); -} - -internal void -draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, GUI_id id, Style *style){ - i32 active_level = gui_active_level(gui_target, id); - char font_name_space[256]; - String font_name = make_fixed_width_string(font_name_space); - font_name.size = system->font.get_name_by_id(font_id, font_name.str, font_name.memory_size); - Font_Pointers font = system->font.get_pointers_by_id(font_id); - - i32_Rect inner = get_inner_rect(rect, 3); - - u32 margin_color = style_get_margin_color(active_level, style); - u32 back = style->main.back_color; - u32 text_color = style->main.default_color; - u32 keyword_color = style->main.keyword_color; - u32 int_constant_color = style->main.int_constant_color; - u32 comment_color = style->main.comment_color; - - draw_margin(target, rect, inner, margin_color); - draw_rectangle(target, inner, back); - - i32 y = inner.y0; - i32 x = inner.x0; - x = ceil32(draw_string(system, target, font_id, style->name.str, x, y, text_color)); - i32 font_x = (i32)(inner.x1 - font_string_width(system, target, font_id, font_name)); - if (font_x > x + 10){ - draw_string(system, target, font_id, font_name, font_x, y, text_color); - } - - i32 height = font.metrics->height; - x = inner.x0; - y += height; - x = ceil32(draw_string(system, target, font_id, "if", x, y, keyword_color)); - x = ceil32(draw_string(system, target, font_id, "(x < ", x, y, text_color)); - x = ceil32(draw_string(system, target, font_id, "0", x, y, int_constant_color)); - x = ceil32(draw_string(system, target, font_id, ") { x = ", x, y, text_color)); - x = ceil32(draw_string(system, target, font_id, "0", x, y, int_constant_color)); - x = ceil32(draw_string(system, target, font_id, "; } ", x, y, text_color)); - x = ceil32(draw_string(system, target, font_id, "// comment", x, y, comment_color)); - - x = inner.x0; - y += height; - draw_string(system, target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^", x, y, text_color); -} - internal i32 do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target, Input_Summary *user_input){ @@ -1588,198 +377,71 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc i32 result = 0; - GUI_Session gui_session = {0}; - GUI_Header *h = 0; - GUI_Target *gui_target = &view->transient.gui_target; - GUI_Interpret_Result interpret_result = {0}; - - f32 v = {0}; - i32 max_y = view_compute_max_target_y(view); - + i32 line_height = view->transient.line_height; + Style *style = &models->styles.styles[0]; Face_ID font_id = file->settings.font_id; - if (gui_target->push.pos > 0){ - gui_session_init(&gui_session, gui_target, rect, view->transient.line_height); - - v = view_get_scroll_y(view); - - i32_Rect clip_rect = rect; - draw_push_clip(target, clip_rect); - - for (h = (GUI_Header*)gui_target->push.base; - h->type; - h = NextHeader(h)){ - interpret_result = gui_interpret(gui_target, &gui_session, h, - *scroll, view->transient.scroll_region, max_y); - - if (interpret_result.has_info){ - if (gui_session.clip_y > clip_rect.y0){ - clip_rect.y0 = gui_session.clip_y; - draw_change_clip(target, clip_rect); - } + + if (!view->transient.hide_file_bar){ + i32_Rect top_bar_rect = {0}; + top_bar_rect.x0 = rect.x0; + top_bar_rect.y0 = rect.y0; + top_bar_rect.x1 = rect.x1; + top_bar_rect.y1 = rect.y0 + line_height + 2; + rect.y0 = top_bar_rect.y1; + draw_file_bar(system, target, view, models, file, top_bar_rect); + } + + draw_push_clip(target, rect); + if (view->transient.ui_mode_counter == 0){ + if (file_is_ready(file)){ + result = render_loaded_file_in_view(system, view, models, rect, is_active, target); + } + } + else{ + i32 item_count = view->transient.ui_control.count; + UI_Item *item = view->transient.ui_control.items; + for (i32 i = 0; i < item_count; ++i, item += 1){ + switch (item->type){ + case UIType_Option: + { + u32 back = style->main.back_color; + u32 margin = style_get_margin_color(item->activation_level, style); + u32 text_color = style->main.default_color; + u32 pop_color = style->main.file_info_style.pop2_color; + i32_Rect item_rect = item->rectangle; + item_rect.x0 += rect.x0; + item_rect.y0 += rect.y0; + item_rect.x1 += rect.x0; + item_rect.y1 += rect.y0; + i32_Rect inner = get_inner_rect(item_rect, 3); + draw_rectangle(target, inner, back); + draw_margin(target, item_rect, inner, margin); + i32 x = inner.x0 + 3; + i32 y = inner.y0 + line_height/2 - 1; + x = ceil32(draw_string(system, target, font_id, item->string, x, y, text_color)); + draw_string(system, target, font_id, item->status, x, y, pop_color); + }break; - switch (h->type){ - case guicom_top_bar: - { - draw_file_bar(system, target, view, models, file, gui_session.rect); - }break; - - case guicom_file: - { - if (file_is_ready(file)){ - result = render_loaded_file_in_view(system, view, models, gui_session.rect, is_active, target); - } - }break; - - case guicom_text_field: - { - void *ptr = (h+1); - String p = gui_read_string(&ptr); - String t = gui_read_string(&ptr); - draw_text_field(system, target, view, models, font_id, gui_session.rect, p, t); - }break; - - case guicom_text_with_cursor: - { - void *ptr = (h+1); - String s = gui_read_string(&ptr); - i32 pos = gui_read_integer(&ptr); - - draw_text_with_cursor(system, target, view, models, font_id, gui_session.rect, s, pos); - }break; - - case guicom_color_button: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - u32 fore = (u32)gui_read_integer(&ptr); - u32 back = (u32)gui_read_integer(&ptr); - String t = gui_read_string(&ptr); - - draw_color_button(system, gui_target, target, view, font_id, gui_session.rect, b->id, fore, back, t); - }break; - - case guicom_file_option: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - b32 folder = gui_read_integer(&ptr); - String f = gui_read_string(&ptr); - String m = gui_read_string(&ptr); - - if (folder){ - append_s_char(&f, '/'); - } - - draw_fat_option_block(system, gui_target, target, view, models, font_id, gui_session.rect, b->id, f, m); - }break; - - case guicom_style_preview: - { - GUI_Interactive *b = (GUI_Interactive*)h; - i32 style_index = *(i32*)(b + 1); - Style *style = &models->styles.styles[style_index]; - - draw_style_preview(system, gui_target, target, view, models, font_id, gui_session.rect, b->id, style); - }break; - - case guicom_fixed_option: - case guicom_fixed_option_checkbox: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - String f = gui_read_string(&ptr); - String m = {0}; - i8 status = -1; - if (h->type == guicom_fixed_option_checkbox){ - gui_read_byte(&ptr); - status = (i8)gui_read_byte(&ptr); - } - - draw_fat_option_block(system, gui_target, target, view, models, font_id, gui_session.rect, b->id, f, m, status); - }break; - - case guicom_button: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - String t = gui_read_string(&ptr); - - draw_button(system, gui_target, target, view, models, font_id, gui_session.rect, b->id, t); - }break; - - case guicom_scrollable_bar: - { - Style *style = &models->styles.styles[0]; - - u32 back; - u32 outline; - - i32_Rect bar = gui_session.rect; - - back = style->main.back_color; - if (is_active){ - outline = style->main.margin_active_color; - } - else{ - outline = style->main.margin_color; - } - - draw_rectangle(target, bar, back); - draw_rectangle_outline(target, bar, outline); - }break; - - case guicom_scrollable_top: - case guicom_scrollable_slider: - case guicom_scrollable_bottom: - { - GUI_id id; - Style *style = &models->styles.styles[0]; - i32_Rect box = gui_session.rect; - - i32 active_level; - - u32 back; - u32 outline; - - switch (h->type){ - case guicom_scrollable_top: id = gui_id_scrollbar_top(); break; - case guicom_scrollable_bottom: id = gui_id_scrollbar_bottom(); break; - default: id = gui_id_scrollbar_slider(); break; - } - - active_level = gui_active_level(gui_target, id); - - switch (active_level){ - case 0: back = style->main.back_color; break; - case 1: back = style->main.margin_hover_color; break; - default: back = style->main.margin_active_color; break; - } - - if (is_active){ - outline = style->main.margin_active_color; - } - else{ - outline = style->main.margin_color; - } - - draw_rectangle(target, box, back); - draw_margin(target, box, get_inner_rect(box, 2), outline); - }break; - - case guicom_begin_scrollable_section: - clip_rect.x1 = Min(gui_session.scroll_region.x1, clip_rect.x1); - draw_push_clip(target, clip_rect); - break; - - case guicom_end_scrollable_section: - clip_rect = draw_pop_clip(target); - break; - } + case UIType_TextField: + { + u32 back_color = style->main.margin_color; + u32 text1_color = style->main.default_color; + u32 text2_color = style->main.file_info_style.pop1_color; + i32_Rect item_rect = item->rectangle; + item_rect.x0 += rect.x0; + item_rect.y0 += rect.y0; + item_rect.x1 += rect.x0; + item_rect.y1 += rect.y0; + draw_rectangle(target, item_rect, back_color); + i32 x = item_rect.x0; + i32 y = item_rect.y0 + 2; + x = ceil32(draw_string(system, target, font_id, item->query, x, y, text2_color)); + draw_string(system, target, font_id, item->string, x, y, text1_color); + }break; } } - - draw_pop_clip(target); } + draw_pop_clip(target); return(result); } diff --git a/meta/4ed_metagen.cpp b/meta/4ed_metagen.cpp index 74d71db4..2a7ccd1b 100644 --- a/meta/4ed_metagen.cpp +++ b/meta/4ed_metagen.cpp @@ -682,7 +682,7 @@ generate_remapping_code_and_data(){ bind(mappings, 'o', MDFR_CTRL, interactive_open_or_new); bind(mappings, 'o', MDFR_ALT, open_in_other); bind(mappings, 'k', MDFR_CTRL, interactive_kill_buffer); - bind(mappings, 'i', MDFR_CTRL, interactive_switch_buffer); + bind(mappings, 'i', MDFR_CTRL, interactive_switch_buffer_DUMMY_API_EXPLORATION); bind(mappings, 'h', MDFR_CTRL, project_go_to_root_directory); bind(mappings, 'S', MDFR_CTRL, save_all_dirty_buffers);