Fixed file/buffer lister crashes for very long lists, fixed kill buffer on dirty buffer bug
parent
ff30d17a7f
commit
cf5b9f3b52
|
@ -151,7 +151,7 @@ activate_snippet(Application_Links *app, Partition *scratch, Heap *heap,
|
|||
View_Summary *view, struct Lister_State *state,
|
||||
String text_field, void *user_data, bool32 activated_by_mouse){
|
||||
int32_t index = (int32_t)PtrAsInt(user_data);
|
||||
Snippet_Array snippets = *(Snippet_Array*)state->lister.user_data;
|
||||
Snippet_Array snippets = *(Snippet_Array*)state->lister.data.user_data;
|
||||
if (0 <= index && index < snippets.count){
|
||||
Snippet snippet = snippets.snippets[index];
|
||||
lister_default(app, scratch, heap, view, state, ListerActivation_Finished);
|
||||
|
|
|
@ -270,7 +270,7 @@ static Command_Metadata fcoder_metacmd_table[228] = {
|
|||
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1060 },
|
||||
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 203 },
|
||||
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 484 },
|
||||
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 935 },
|
||||
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 972 },
|
||||
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 26 },
|
||||
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 96 },
|
||||
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 35 },
|
||||
|
@ -311,11 +311,11 @@ static Command_Metadata fcoder_metacmd_table[228] = {
|
|||
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 81 },
|
||||
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 562 },
|
||||
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 540 },
|
||||
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 748 },
|
||||
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 853 },
|
||||
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 881 },
|
||||
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 819 },
|
||||
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 729 },
|
||||
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 784 },
|
||||
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 889 },
|
||||
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 917 },
|
||||
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 855 },
|
||||
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 765 },
|
||||
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1540 },
|
||||
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 26 },
|
||||
{ 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", 36, 133 },
|
||||
|
@ -375,7 +375,7 @@ static Command_Metadata fcoder_metacmd_table[228] = {
|
|||
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 573 },
|
||||
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1067 },
|
||||
{ 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", 39, 1074 },
|
||||
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder theme selector list.", 37, "w:\\4ed\\code\\4coder_lists.cpp", 28, 897 },
|
||||
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder theme selector list.", 37, "w:\\4ed\\code\\4coder_lists.cpp", 28, 933 },
|
||||
{ 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", 36, 1447 },
|
||||
{ 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", 36, 1602 },
|
||||
{ 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", 46, 57 },
|
||||
|
|
|
@ -10,7 +10,7 @@ activate_jump(Application_Links *app, Partition *scratch, Heap *heap,
|
|||
String text_field, void *user_data, bool32 activated_by_mouse){
|
||||
Lister_Activation_Code result_code = ListerActivation_Finished;
|
||||
int32_t list_index = (int32_t)PtrAsInt(user_data);
|
||||
Jump_Lister_Parameters *params = (Jump_Lister_Parameters*)state->lister.user_data;
|
||||
Jump_Lister_Parameters *params = (Jump_Lister_Parameters*)state->lister.data.user_data;
|
||||
Marker_List *list = get_marker_list_for_buffer(params->list_buffer_id);
|
||||
if (list != 0){
|
||||
View_Summary target_view = {};
|
||||
|
|
279
4coder_lists.cpp
279
4coder_lists.cpp
|
@ -21,8 +21,8 @@ CUSTOM_DOC("A lister mode command that activates the list's action on the highli
|
|||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->initialized){
|
||||
void *user_data = 0;
|
||||
if (0 <= state->raw_item_index && state->raw_item_index < state->lister.options.count){
|
||||
user_data = lister_get_user_data(&state->lister, state->raw_item_index);
|
||||
if (0 <= state->raw_item_index && state->raw_item_index < state->lister.data.options.count){
|
||||
user_data = lister_get_user_data(&state->lister.data, state->raw_item_index);
|
||||
}
|
||||
lister_call_activate_handler(app, scratch, heap, &view, state, user_data, false);
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ CUSTOM_DOC("A lister mode command that dispatches to the lister's write characte
|
|||
{
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->lister.handlers.write_character != 0){
|
||||
state->lister.handlers.write_character(app);
|
||||
if (state->lister.data.handlers.write_character != 0){
|
||||
state->lister.data.handlers.write_character(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,8 @@ CUSTOM_DOC("A lister mode command that dispatches to the lister's backspace text
|
|||
{
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->lister.handlers.backspace != 0){
|
||||
state->lister.handlers.backspace(app);
|
||||
if (state->lister.data.handlers.backspace != 0){
|
||||
state->lister.data.handlers.backspace(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,8 @@ CUSTOM_DOC("A lister mode command that dispatches to the lister's navigate up ha
|
|||
{
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->lister.handlers.navigate_up != 0){
|
||||
state->lister.handlers.navigate_up(app);
|
||||
if (state->lister.data.handlers.navigate_up != 0){
|
||||
state->lister.data.handlers.navigate_up(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,8 @@ CUSTOM_DOC("A lister mode command that dispatches to the lister's navigate down
|
|||
{
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->lister.handlers.navigate_down != 0){
|
||||
state->lister.handlers.navigate_down(app);
|
||||
if (state->lister.data.handlers.navigate_down != 0){
|
||||
state->lister.data.handlers.navigate_down(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,8 +134,8 @@ CUSTOM_DOC("A lister mode command that inserts a new character to the text field
|
|||
uint8_t character[4];
|
||||
uint32_t length = to_writable_character(in, character);
|
||||
if (length > 0){
|
||||
append(&state->lister.text_field, make_string(character, length));
|
||||
append(&state->lister.key_string, make_string(character, length));
|
||||
append(&state->lister.data.text_field, make_string(character, length));
|
||||
append(&state->lister.data.key_string, make_string(character, length));
|
||||
state->item_index = 0;
|
||||
view_zero_scroll(app, &view);
|
||||
lister_update_ui(app, scratch, &view, state);
|
||||
|
@ -150,8 +150,8 @@ CUSTOM_DOC("A lister mode command that backspaces one character from the text fi
|
|||
View_Summary view = get_active_view(app, AccessAll);
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->initialized){
|
||||
backspace_utf8(&state->lister.text_field);
|
||||
backspace_utf8(&state->lister.key_string);
|
||||
backspace_utf8(&state->lister.data.text_field);
|
||||
backspace_utf8(&state->lister.data.key_string);
|
||||
state->item_index = 0;
|
||||
view_zero_scroll(app, &view);
|
||||
lister_update_ui(app, scratch, &view, state);
|
||||
|
@ -167,7 +167,7 @@ CUSTOM_DOC("A lister mode command that moves the highlighted item one up in the
|
|||
if (state->initialized){
|
||||
state->item_index = state->item_index - 1;
|
||||
if (state->item_index < 0){
|
||||
state->item_index = state->option_item_count - 1;
|
||||
state->item_index = state->item_count_after_filter - 1;
|
||||
}
|
||||
state->set_view_vertical_focus_to_item = true;
|
||||
lister_update_ui(app, scratch, &view, state);
|
||||
|
@ -182,7 +182,7 @@ CUSTOM_DOC("A lister mode command that moves the highlighted item one down in th
|
|||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->initialized){
|
||||
state->item_index = state->item_index + 1;
|
||||
if (state->item_index > state->option_item_count - 1){
|
||||
if (state->item_index > state->item_count_after_filter - 1){
|
||||
state->item_index = 0;
|
||||
}
|
||||
state->set_view_vertical_focus_to_item = true;
|
||||
|
@ -201,12 +201,12 @@ CUSTOM_DOC("A lister mode command that inserts a character into the text field o
|
|||
uint8_t character[4];
|
||||
uint32_t length = to_writable_character(in, character);
|
||||
if (length > 0){
|
||||
append(&state->lister.text_field, make_string(character, length));
|
||||
copy(&state->lister.key_string, front_of_directory(state->lister.text_field));
|
||||
append(&state->lister.data.text_field, make_string(character, length));
|
||||
copy(&state->lister.data.key_string, front_of_directory(state->lister.data.text_field));
|
||||
if (character[0] == '/' || character[0] == '\\'){
|
||||
String new_hot = state->lister.text_field;
|
||||
String new_hot = state->lister.data.text_field;
|
||||
directory_set_hot(app, new_hot.str, new_hot.size);
|
||||
lister_call_refresh_handler(app, &state->arena, &state->lister);
|
||||
lister_call_refresh_handler(app, &state->lister);
|
||||
}
|
||||
state->item_index = 0;
|
||||
view_zero_scroll(app, &view);
|
||||
|
@ -222,9 +222,9 @@ CUSTOM_DOC("A lister mode command that backspaces one character from the text fi
|
|||
View_Summary view = get_active_view(app, AccessAll);
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
if (state->initialized){
|
||||
if (state->lister.text_field.size > 0){
|
||||
char last_char = state->lister.text_field.str[state->lister.text_field.size - 1];
|
||||
backspace_utf8(&state->lister.text_field);
|
||||
if (state->lister.data.text_field.size > 0){
|
||||
char last_char = state->lister.data.text_field.str[state->lister.data.text_field.size - 1];
|
||||
backspace_utf8(&state->lister.data.text_field);
|
||||
if (last_char == '/' || last_char == '\\'){
|
||||
User_Input input = get_command_input(app);
|
||||
bool32 is_modified =
|
||||
|
@ -232,15 +232,15 @@ CUSTOM_DOC("A lister mode command that backspaces one character from the text fi
|
|||
input.key.modifiers[MDFR_CONTROL_INDEX] ||
|
||||
input.key.modifiers[MDFR_ALT_INDEX] ||
|
||||
input.key.modifiers[MDFR_COMMAND_INDEX];
|
||||
String new_hot = path_of_directory(state->lister.text_field);
|
||||
String new_hot = path_of_directory(state->lister.data.text_field);
|
||||
if (!is_modified){
|
||||
state->lister.text_field.size = new_hot.size;
|
||||
state->lister.data.text_field.size = new_hot.size;
|
||||
}
|
||||
directory_set_hot(app, new_hot.str, new_hot.size);
|
||||
lister_call_refresh_handler(app, &state->arena, &state->lister);
|
||||
lister_call_refresh_handler(app, &state->lister);
|
||||
}
|
||||
else{
|
||||
copy(&state->lister.key_string, front_of_directory(state->lister.text_field));
|
||||
copy(&state->lister.data.key_string, front_of_directory(state->lister.data.text_field));
|
||||
}
|
||||
|
||||
state->item_index = 0;
|
||||
|
@ -264,7 +264,7 @@ CUSTOM_DOC("A lister mode command that handles input for the fixed sure to kill
|
|||
if (length > 0){
|
||||
void *user_data = 0;
|
||||
bool32 did_shortcut_key = false;
|
||||
for (Lister_Node *node = state->lister.options.first;
|
||||
for (Lister_Node *node = state->lister.data.options.first;
|
||||
node != 0;
|
||||
node = node->next){
|
||||
char *hotkeys = (char*)(node + 1);
|
||||
|
@ -316,11 +316,11 @@ begin_integrated_lister__with_refresh_handler(Application_Links *app, char *quer
|
|||
view_begin_ui_mode(app, view);
|
||||
view_set_setting(app, view, ViewSetting_UICommandMap, default_lister_ui_map);
|
||||
Lister_State *state = view_get_lister_state(view);
|
||||
init_lister_state(state, heap);
|
||||
lister_first_init(&state->arena, &state->lister, user_data, user_data_size);
|
||||
lister_set_query_string(&state->lister, query_string);
|
||||
state->lister.handlers = handlers;
|
||||
handlers.refresh(app, &state->arena, &state->lister);
|
||||
init_lister_state(app, state, heap);
|
||||
lister_first_init(app, &state->lister, user_data, user_data_size, 0);
|
||||
lister_set_query_string(&state->lister.data, query_string);
|
||||
state->lister.data.handlers = handlers;
|
||||
handlers.refresh(app, &state->lister);
|
||||
lister_update_ui(app, scratch, view, state);
|
||||
}
|
||||
else{
|
||||
|
@ -333,6 +333,15 @@ begin_integrated_lister__with_refresh_handler(Application_Links *app, char *quer
|
|||
}
|
||||
}
|
||||
|
||||
static const int32_t default_string_size_estimation = 0;
|
||||
|
||||
static int32_t
|
||||
lister__get_arena_size(int32_t option_count, int32_t user_data_size,
|
||||
int32_t estimated_string_space_size){
|
||||
int32_t arena_size = (user_data_size + 7 + option_count*sizeof(Lister_Node) + estimated_string_space_size);
|
||||
return(arena_size);
|
||||
}
|
||||
|
||||
static void
|
||||
begin_integrated_lister__basic_list(Application_Links *app, char *query_string,
|
||||
Lister_Activation_Function_Type *activate,
|
||||
|
@ -345,20 +354,15 @@ begin_integrated_lister__basic_list(Application_Links *app, char *query_string,
|
|||
view_begin_ui_mode(app, view);
|
||||
view_set_setting(app, view, ViewSetting_UICommandMap, default_lister_ui_map);
|
||||
Lister_State *state = view_get_lister_state(view);
|
||||
int32_t arena_size = (user_data_size + option_count*sizeof(Lister_Node) + estimated_string_space_size);
|
||||
arena_size = (arena_size + (4 << 10) - 1);
|
||||
arena_size = arena_size - arena_size%(4 << 10);
|
||||
if (arena_size < (64 << 10)){
|
||||
arena_size = (64 << 10);
|
||||
}
|
||||
init_lister_state(state, heap, arena_size);
|
||||
lister_first_init(&state->arena, &state->lister, user_data, user_data_size);
|
||||
int32_t arena_size = lister__get_arena_size(option_count, user_data_size, estimated_string_space_size);
|
||||
init_lister_state(app, state, heap);
|
||||
lister_first_init(app, &state->lister, user_data, user_data_size, arena_size);
|
||||
for (int32_t i = 0; i < option_count; i += 1){
|
||||
lister_add_item(&state->arena, &state->lister, options[i].string, options[i].status, options[i].user_data, 0);
|
||||
lister_add_item(&state->lister, options[i].string, options[i].status, options[i].user_data, 0);
|
||||
}
|
||||
lister_set_query_string(&state->lister, query_string);
|
||||
state->lister.handlers = lister_get_default_handlers();
|
||||
state->lister.handlers.activate = activate;
|
||||
lister_set_query_string(&state->lister.data, query_string);
|
||||
state->lister.data.handlers = lister_get_default_handlers();
|
||||
state->lister.data.handlers.activate = activate;
|
||||
lister_update_ui(app, scratch, view, state);
|
||||
}
|
||||
|
||||
|
@ -367,27 +371,29 @@ begin_integrated_lister__with_fixed_options(Application_Links *app, char *query_
|
|||
Lister_Handlers handlers,
|
||||
void *user_data, int32_t user_data_size,
|
||||
Lister_Fixed_Option *options, int32_t option_count,
|
||||
int32_t estimated_string_space_size,
|
||||
View_Summary *view){
|
||||
Partition *scratch = &global_part;
|
||||
Heap *heap = &global_heap;
|
||||
view_begin_ui_mode(app, view);
|
||||
view_set_setting(app, view, ViewSetting_UICommandMap, default_lister_ui_map);
|
||||
Lister_State *state = view_get_lister_state(view);
|
||||
init_lister_state(state, heap);
|
||||
lister_first_init(&state->arena, &state->lister, user_data, user_data_size);
|
||||
init_lister_state(app, state, heap);
|
||||
int32_t arena_size = lister__get_arena_size(option_count, user_data_size, estimated_string_space_size);
|
||||
lister_first_init(app, &state->lister, user_data, user_data_size, arena_size);
|
||||
for (int32_t i = 0; i < option_count; i += 1){
|
||||
char *shortcut_chars = options[i].shortcut_chars;
|
||||
int32_t shortcut_chars_length = str_size(shortcut_chars);
|
||||
void *extra = lister_add_item(&state->arena, &state->lister,
|
||||
void *extra = lister_add_item(&state->lister,
|
||||
make_string_slowly(options[i].string),
|
||||
make_string_slowly(options[i].status),
|
||||
options[i].user_data,
|
||||
shortcut_chars_length + 1);
|
||||
memcpy(extra, shortcut_chars, shortcut_chars_length + 1);
|
||||
}
|
||||
lister_set_query_string(&state->lister, query_string);
|
||||
state->lister.handlers = handlers;
|
||||
state->lister.handlers.refresh = 0;
|
||||
lister_set_query_string(&state->lister.data, query_string);
|
||||
state->lister.data.handlers = handlers;
|
||||
state->lister.data.handlers.refresh = 0;
|
||||
lister_update_ui(app, scratch, view, state);
|
||||
}
|
||||
|
||||
|
@ -396,71 +402,86 @@ begin_integrated_lister__with_fixed_options(Application_Links *app, char *query_
|
|||
Lister_Activation_Function_Type *activate,
|
||||
void *user_data, int32_t user_data_size,
|
||||
Lister_Fixed_Option *options, int32_t option_count,
|
||||
int32_t estimated_string_space_size,
|
||||
View_Summary *view){
|
||||
Lister_Handlers handlers = lister_get_fixed_list_handlers();
|
||||
handlers.activate = activate;
|
||||
begin_integrated_lister__with_fixed_options(app, query_string,
|
||||
handlers, user_data, user_data_size,
|
||||
options, option_count,
|
||||
estimated_string_space_size,
|
||||
view);
|
||||
}
|
||||
|
||||
static void
|
||||
begin_integrated_lister__ui_list(Application_Links *app, char *query_string,
|
||||
Lister_Handlers handlers,
|
||||
void *user_data, int32_t user_data_size,
|
||||
Lister_UI_Option *options, int32_t option_count,
|
||||
View_Summary *view){
|
||||
begin_integrated_lister__theme_list(Application_Links *app, char *query_string,
|
||||
Lister_Handlers handlers,
|
||||
void *user_data, int32_t user_data_size,
|
||||
Lister_UI_Option *options, int32_t option_count,
|
||||
int32_t estimated_string_space_size,
|
||||
View_Summary *view){
|
||||
Partition *scratch = &global_part;
|
||||
Heap *heap = &global_heap;
|
||||
view_begin_ui_mode(app, view);
|
||||
view_set_setting(app, view, ViewSetting_UICommandMap, default_lister_ui_map);
|
||||
Lister_State *state = view_get_lister_state(view);
|
||||
init_lister_state(state, heap);
|
||||
lister_first_init(&state->arena, &state->lister, user_data, user_data_size);
|
||||
state->lister.theme_list = true;
|
||||
init_lister_state(app, state, heap);
|
||||
int32_t arena_size = lister__get_arena_size(option_count, user_data_size, estimated_string_space_size);
|
||||
lister_first_init(app, &state->lister, user_data, user_data_size, arena_size);
|
||||
state->lister.data.theme_list = true;
|
||||
for (int32_t i = 0; i < option_count; i += 1){
|
||||
lister_add_ui_item(&state->arena, &state->lister,
|
||||
make_string_slowly(options[i].string),
|
||||
options[i].index,
|
||||
options[i].user_data, 0);
|
||||
lister_add_theme_item(&state->lister,
|
||||
make_string_slowly(options[i].string),
|
||||
options[i].index,
|
||||
options[i].user_data, 0);
|
||||
}
|
||||
lister_set_query_string(&state->lister, query_string);
|
||||
state->lister.handlers = handlers;
|
||||
state->lister.handlers.refresh = 0;
|
||||
lister_set_query_string(&state->lister.data, query_string);
|
||||
state->lister.data.handlers = handlers;
|
||||
state->lister.data.handlers.refresh = 0;
|
||||
lister_update_ui(app, scratch, view, state);
|
||||
}
|
||||
|
||||
static void
|
||||
begin_integrated_lister__ui_list(Application_Links *app, char *query_string,
|
||||
Lister_Activation_Function_Type *activate,
|
||||
void *user_data, int32_t user_data_size,
|
||||
Lister_UI_Option *options, int32_t option_count,
|
||||
View_Summary *view){
|
||||
begin_integrated_lister__theme_list(Application_Links *app, char *query_string,
|
||||
Lister_Activation_Function_Type *activate,
|
||||
void *user_data, int32_t user_data_size,
|
||||
Lister_UI_Option *options, int32_t option_count,
|
||||
int32_t estimated_string_space_size,
|
||||
View_Summary *view){
|
||||
Lister_Handlers handlers = lister_get_default_handlers();
|
||||
handlers.activate = activate;
|
||||
begin_integrated_lister__ui_list(app, query_string,
|
||||
handlers, user_data, user_data_size,
|
||||
options, option_count,
|
||||
view);
|
||||
begin_integrated_lister__theme_list(app, query_string,
|
||||
handlers, user_data, user_data_size,
|
||||
options, option_count,
|
||||
estimated_string_space_size,
|
||||
view);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static void
|
||||
generate_all_buffers_list__output_buffer(Partition *arena, Lister *lister, Buffer_Summary buffer){
|
||||
generate_all_buffers_list__output_buffer(Lister *lister, Buffer_Summary buffer){
|
||||
String status = {};
|
||||
switch (buffer.dirty){
|
||||
case DirtyState_UnsavedChanges: status = make_lit_string("*"); break;
|
||||
case DirtyState_UnloadedChanges: status = make_lit_string("!"); break;
|
||||
}
|
||||
String buffer_name = make_string(buffer.buffer_name, buffer.buffer_name_len);
|
||||
lister_add_item(arena, lister, buffer_name, status, IntAsPtr(buffer.buffer_id), 0);
|
||||
lister_add_item(lister, buffer_name, status, IntAsPtr(buffer.buffer_id), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
generate_all_buffers_list(Application_Links *app, Partition *arena, Lister *lister){
|
||||
lister_begin_new_item_set(lister);
|
||||
generate_all_buffers_list(Application_Links *app, Lister *lister){
|
||||
int32_t buffer_count = get_buffer_count(app);
|
||||
int32_t memory_size = 0;
|
||||
memory_size += buffer_count*(sizeof(Lister_Node) + 3);
|
||||
for (Buffer_Summary buffer = get_buffer_first(app, AccessAll);
|
||||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
memory_size += buffer.buffer_name_len;
|
||||
}
|
||||
|
||||
lister_begin_new_item_set(app, lister, memory_size);
|
||||
|
||||
Buffer_ID buffers_currently_being_viewed[16];
|
||||
int32_t currently_viewed_buffer_count = 0;
|
||||
|
@ -489,7 +510,7 @@ generate_all_buffers_list(Application_Links *app, Partition *arena, Lister *list
|
|||
}
|
||||
}
|
||||
if (buffer.buffer_name_len == 0 || buffer.buffer_name[0] != '*'){
|
||||
generate_all_buffers_list__output_buffer(arena, lister, buffer);
|
||||
generate_all_buffers_list__output_buffer(lister, buffer);
|
||||
}
|
||||
skip1:;
|
||||
}
|
||||
|
@ -503,65 +524,79 @@ generate_all_buffers_list(Application_Links *app, Partition *arena, Lister *list
|
|||
}
|
||||
}
|
||||
if (buffer.buffer_name_len != 0 && buffer.buffer_name[0] == '*'){
|
||||
generate_all_buffers_list__output_buffer(arena, lister, buffer);
|
||||
generate_all_buffers_list__output_buffer(lister, buffer);
|
||||
}
|
||||
skip2:;
|
||||
}
|
||||
// Buffers That Are Open in Views
|
||||
for (int32_t i = 0; i < currently_viewed_buffer_count; i += 1){
|
||||
Buffer_Summary buffer = get_buffer(app, buffers_currently_being_viewed[i], AccessAll);
|
||||
generate_all_buffers_list__output_buffer(arena, lister, buffer);
|
||||
generate_all_buffers_list__output_buffer(lister, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
generate_hot_directory_file_list(Application_Links *app, Partition *arena, Lister *lister){
|
||||
{
|
||||
Temp_Memory temp = begin_temp_memory(arena);
|
||||
String hot = get_hot_directory(app, arena);
|
||||
if (hot.size > 0 && hot.str[hot.size - 1] != '/' && hot.str[hot.size - 1] != '\\'){
|
||||
if (push_array(arena, char, 1) != 0){
|
||||
hot.memory_size += 1;
|
||||
append_s_char(&hot, '/');
|
||||
}
|
||||
}
|
||||
lister_set_text_field_string(lister, hot);
|
||||
lister_set_key_string(lister, front_of_directory(hot));
|
||||
end_temp_memory(temp);
|
||||
generate_hot_directory_file_list(Application_Links *app, Lister *lister){
|
||||
if (lister->arena.max < (64 << 10)){
|
||||
lister_arena_clear_data_ensure_bytes(app, lister, (64 << 10));
|
||||
}
|
||||
|
||||
lister_begin_new_item_set(lister);
|
||||
String hot = get_hot_directory(app, arena);
|
||||
push_align(arena, 8);
|
||||
File_List file_list = {};
|
||||
if (hot.str != 0){
|
||||
file_list = get_file_list(app, hot.str, hot.size);
|
||||
Temp_Memory temp = begin_temp_memory(&lister->arena);
|
||||
String hot = get_hot_directory(app, &lister->arena);
|
||||
if (hot.size > 0 && hot.str[hot.size - 1] != '/' && hot.str[hot.size - 1] != '\\'){
|
||||
if (push_array(&lister->arena, char, 1) != 0){
|
||||
hot.memory_size += 1;
|
||||
append_s_char(&hot, '/');
|
||||
}
|
||||
}
|
||||
lister_set_text_field_string(&lister->data, hot);
|
||||
lister_set_key_string(&lister->data, front_of_directory(hot));
|
||||
|
||||
File_List file_list = get_file_list(app, hot.str, hot.size);
|
||||
end_temp_memory(temp);
|
||||
|
||||
File_Info *one_past_last = file_list.infos + file_list.count;
|
||||
|
||||
int32_t memory_requirement = 0;
|
||||
memory_requirement += lister->data.user_data_size;
|
||||
memory_requirement += file_list.count*(sizeof(Lister_Node) + 10);
|
||||
memory_requirement += hot.size + 2;
|
||||
for (File_Info *info = file_list.infos;
|
||||
info < one_past_last;
|
||||
info += 1){
|
||||
memory_requirement += info->filename_len;
|
||||
}
|
||||
|
||||
lister_begin_new_item_set(app, lister, memory_requirement);
|
||||
|
||||
hot = get_hot_directory(app, &lister->arena);
|
||||
push_align(&lister->arena, 8);
|
||||
if (hot.str != 0){
|
||||
for (File_Info *info = file_list.infos, *one_past_last = file_list.infos + file_list.count;
|
||||
String empty_string = make_lit_string("");
|
||||
Lister_Prealloced_String empty_string_prealloced = {empty_string};
|
||||
for (File_Info *info = file_list.infos;
|
||||
info < one_past_last;
|
||||
info += 1){
|
||||
if (!info->folder) continue;
|
||||
String file_name = build_string(arena,
|
||||
String file_name = build_string(&lister->arena,
|
||||
make_string(info->filename, info->filename_len),
|
||||
"/", "");
|
||||
String status = make_lit_string("");
|
||||
lister_add_item(arena, lister, lister_prealloced(file_name), status, file_name.str, 0);
|
||||
lister_add_item(lister, lister_prealloced(file_name), empty_string_prealloced, file_name.str, 0);
|
||||
}
|
||||
|
||||
for (File_Info *info = file_list.infos, *one_past_last = file_list.infos + file_list.count;
|
||||
info < one_past_last;
|
||||
info += 1){
|
||||
if (info->folder) continue;
|
||||
String file_name = string_push_copy(arena, make_string(info->filename, info->filename_len));
|
||||
String file_name = string_push_copy(&lister->arena, make_string(info->filename, info->filename_len));
|
||||
char *is_loaded = "";
|
||||
char *status_flag = "";
|
||||
|
||||
Temp_Memory path_temp = begin_temp_memory(arena);
|
||||
Temp_Memory path_temp = begin_temp_memory(&lister->arena);
|
||||
String full_file_path = {};
|
||||
full_file_path.size = 0;
|
||||
full_file_path.memory_size = hot.size + 1 + info->filename_len + 1;
|
||||
full_file_path.str = push_array(arena, char, full_file_path.memory_size);
|
||||
full_file_path.str = push_array(&lister->arena, char, full_file_path.memory_size);
|
||||
append(&full_file_path, hot);
|
||||
if (full_file_path.size == 0 ||
|
||||
char_is_slash(full_file_path.str[full_file_path.size - 1])){
|
||||
|
@ -571,7 +606,6 @@ generate_hot_directory_file_list(Application_Links *app, Partition *arena, Liste
|
|||
Buffer_Summary buffer = get_buffer_by_file_name(app,
|
||||
full_file_path.str, full_file_path.size,
|
||||
AccessAll);
|
||||
|
||||
end_temp_memory(path_temp);
|
||||
|
||||
if (buffer.exists){
|
||||
|
@ -581,11 +615,12 @@ generate_hot_directory_file_list(Application_Links *app, Partition *arena, Liste
|
|||
case DirtyState_UnloadedChanges: status_flag = " !"; break;
|
||||
}
|
||||
}
|
||||
String status = build_string(arena, is_loaded, status_flag, "");
|
||||
lister_add_item(arena, lister, lister_prealloced(file_name), lister_prealloced(status), file_name.str, 0);
|
||||
String status = build_string(&lister->arena, is_loaded, status_flag, "");
|
||||
lister_add_item(lister, lister_prealloced(file_name), lister_prealloced(status), file_name.str, 0);
|
||||
}
|
||||
free_file_list(app, file_list);
|
||||
}
|
||||
|
||||
free_file_list(app, file_list);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -628,7 +663,7 @@ activate_confirm_kill(Application_Links *app, Partition *scratch, Heap *heap,
|
|||
View_Summary *view, Lister_State *state,
|
||||
String text_field, void *user_data, bool32 clicked){
|
||||
int32_t behavior = (int32_t)PtrAsInt(user_data);
|
||||
Buffer_ID buffer_id = *(Buffer_ID*)(state->lister.user_data);
|
||||
Buffer_ID buffer_id = *(Buffer_ID*)(state->lister.data.user_data);
|
||||
switch (behavior){
|
||||
case SureToKill_No:
|
||||
{}break;
|
||||
|
@ -668,7 +703,7 @@ do_gui_sure_to_kill(Application_Links *app, Buffer_Summary *buffer, View_Summary
|
|||
begin_integrated_lister__with_fixed_options(app, "There are unsaved changes, close anyway?",
|
||||
activate_confirm_kill,
|
||||
&buffer->buffer_id, sizeof(buffer->buffer_id),
|
||||
options, option_count,
|
||||
options, option_count, default_string_size_estimation,
|
||||
view);
|
||||
}
|
||||
|
||||
|
@ -694,7 +729,7 @@ activate_confirm_close_4coder(Application_Links *app, Partition *scratch, Heap *
|
|||
send_exit_signal(app);
|
||||
}break;
|
||||
}
|
||||
lister_default(app, scratch, heap, view, state, ListerActivation_Finished);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -710,6 +745,7 @@ do_gui_sure_to_close_4coder(Application_Links *app, View_Summary *view){
|
|||
activate_confirm_close_4coder,
|
||||
0, 0,
|
||||
options, option_count,
|
||||
default_string_size_estimation,
|
||||
view);
|
||||
}
|
||||
|
||||
|
@ -738,11 +774,11 @@ static void
|
|||
activate_kill_buffer(Application_Links *app, Partition *scratch, Heap *heap,
|
||||
View_Summary *view, struct Lister_State *state,
|
||||
String text_field, void *user_data, bool32 activated_by_mouse){
|
||||
lister_default(app, scratch, heap, view, state, ListerActivation_Finished);
|
||||
if (user_data != 0){
|
||||
Buffer_ID buffer_id = (Buffer_ID)(PtrAsInt(user_data));
|
||||
kill_buffer(app, buffer_identifier(buffer_id), view->view_id, 0);
|
||||
}
|
||||
lister_default(app, scratch, heap, view, state, ListerActivation_Finished);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(interactive_kill_buffer)
|
||||
|
@ -910,11 +946,12 @@ CUSTOM_DOC("Opens the 4coder theme selector list.")
|
|||
options[i].index = i;
|
||||
options[i].user_data = IntAsPtr(i);
|
||||
}
|
||||
begin_integrated_lister__ui_list(app,
|
||||
"Select a theme:",
|
||||
activate_select_theme, 0, 0,
|
||||
options, theme_count,
|
||||
&view);
|
||||
begin_integrated_lister__theme_list(app,
|
||||
"Select a theme:",
|
||||
activate_select_theme, 0, 0,
|
||||
options, theme_count,
|
||||
default_string_size_estimation,
|
||||
&view);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
|
||||
// TODO(allen): documentation comment here
|
||||
|
||||
static UI_Item*
|
||||
ui_list_add_item(Partition *arena, UI_List *list, UI_Item item){
|
||||
|
@ -196,26 +196,50 @@ view_get_lister_state(View_Summary *view){
|
|||
return(&global_lister_state[view->view_id]);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
lister_standard_arena_size_round_up(int32_t arena_size){
|
||||
if (arena_size < (64 << 10)){
|
||||
arena_size = (64 << 10);
|
||||
}
|
||||
else{
|
||||
arena_size += (4 << 10) - 1;
|
||||
arena_size -= arena_size%(4 << 10);
|
||||
}
|
||||
return(arena_size);
|
||||
}
|
||||
|
||||
static void
|
||||
init_lister_state(Lister_State *state, Heap *heap, int32_t arena_size){
|
||||
lister_arena_clear_data_ensure_bytes(Application_Links *app, Lister *lister, int32_t minimum_bytes){
|
||||
if (lister->arena.base == 0 || lister->arena.max < minimum_bytes){
|
||||
int32_t rounded_user_data_size = lister->data.user_data_size;
|
||||
rounded_user_data_size += 7;
|
||||
rounded_user_data_size -= rounded_user_data_size%8;
|
||||
int32_t new_size = (lister->arena.max + rounded_user_data_size + minimum_bytes + 1)*2;
|
||||
new_size = lister_standard_arena_size_round_up(new_size);
|
||||
void *new_memory = memory_allocate(app, new_size);
|
||||
memcpy(new_memory, lister->data.user_data, lister->data.user_data_size);
|
||||
lister->data.user_data = new_memory;
|
||||
if (lister->arena.base != 0){
|
||||
memory_free(app, lister->arena.base, lister->arena.max);
|
||||
}
|
||||
lister->arena = make_part(new_memory, new_size);
|
||||
push_array(&lister->arena, char, lister->data.user_data_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_lister_state(Application_Links *app, Lister_State *state, Heap *heap){
|
||||
state->initialized = true;
|
||||
state->hot_user_data = 0;
|
||||
state->item_index = 0;
|
||||
state->set_view_vertical_focus_to_item = false;
|
||||
state->option_item_count = 0;
|
||||
if (state->arena.base != 0){
|
||||
heap_free(heap, state->arena.base);
|
||||
state->item_count_after_filter = 0;
|
||||
if (state->lister.arena.base != 0){
|
||||
memory_free(app, state->lister.arena.base, state->lister.arena.max);
|
||||
}
|
||||
state->arena = make_part(heap_allocate(heap, arena_size), arena_size);
|
||||
memset(&state->lister, 0, sizeof(state->lister));
|
||||
}
|
||||
|
||||
static void
|
||||
init_lister_state(Lister_State *state, Heap *heap){
|
||||
int32_t arena_size = (64 << 10);
|
||||
init_lister_state(state, heap, arena_size);
|
||||
}
|
||||
|
||||
UI_QUIT_FUNCTION(lister_quit_function){
|
||||
Lister_State *state = view_get_lister_state(&view);
|
||||
state->initialized = false;
|
||||
|
@ -240,14 +264,18 @@ lister_get_clicked_item(Application_Links *app, View_Summary *view, Partition *s
|
|||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
||||
Lister_State *state){
|
||||
bool32 is_theme_list = state->lister.theme_list;
|
||||
|
||||
int32_t x0 = 0;
|
||||
int32_t x1 = view->view_region.x1 - view->view_region.x0;
|
||||
int32_t line_height = (int32_t)view->line_height;
|
||||
static int32_t
|
||||
lister_get_line_height(View_Summary *view){
|
||||
return((int32_t)view->line_height);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
lister_get_text_field_height(View_Summary *view){
|
||||
return((int32_t)view->line_height);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
lister_get_block_height(int32_t line_height, bool32 is_theme_list){
|
||||
int32_t block_height = 0;
|
||||
if (is_theme_list){
|
||||
block_height = line_height*3 + 6;
|
||||
|
@ -255,6 +283,19 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
|||
else{
|
||||
block_height = line_height*2;
|
||||
}
|
||||
return(block_height);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
||||
Lister_State *state){
|
||||
bool32 is_theme_list = state->lister.data.theme_list;
|
||||
|
||||
int32_t x0 = 0;
|
||||
int32_t x1 = view->view_region.x1 - view->view_region.x0;
|
||||
int32_t line_height = lister_get_line_height(view);
|
||||
int32_t block_height = lister_get_block_height(line_height, is_theme_list);
|
||||
int32_t text_field_height = lister_get_text_field_height(view);
|
||||
|
||||
Temp_Memory full_temp = begin_temp_memory(scratch);
|
||||
|
||||
|
@ -263,11 +304,11 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
|||
refresh_view(app, view);
|
||||
get_view_relative_mouse_positions(app, *view, &mx, &my, 0, 0);
|
||||
|
||||
int32_t y_pos = line_height;
|
||||
int32_t y_pos = text_field_height;
|
||||
|
||||
state->raw_item_index = -1;
|
||||
|
||||
int32_t node_count = state->lister.options.count;
|
||||
int32_t node_count = state->lister.data.options.count;
|
||||
Lister_Node_Ptr_Array exact_matches = {};
|
||||
exact_matches.node_ptrs = push_array(scratch, Lister_Node*, 1);
|
||||
Lister_Node_Ptr_Array before_extension_matches = {};
|
||||
|
@ -275,12 +316,12 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
|||
Lister_Node_Ptr_Array substring_matches = {};
|
||||
substring_matches.node_ptrs = push_array(scratch, Lister_Node*, node_count);
|
||||
|
||||
String key = state->lister.key_string;
|
||||
String key = state->lister.data.key_string;
|
||||
Absolutes absolutes = {};
|
||||
get_absolutes(key, &absolutes, true, true);
|
||||
bool32 has_wildcard = (absolutes.count > 3);
|
||||
|
||||
for (Lister_Node *node = state->lister.options.first;
|
||||
for (Lister_Node *node = state->lister.data.options.first;
|
||||
node != 0;
|
||||
node = node->next){
|
||||
if (key.size == 0 ||
|
||||
|
@ -354,7 +395,7 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
|||
}
|
||||
}
|
||||
}
|
||||
state->option_item_count = item_index_counter;
|
||||
state->item_count_after_filter = item_index_counter;
|
||||
|
||||
if (hovered_item != 0){
|
||||
hovered_item->activation_level = UIActivation_Hover;
|
||||
|
@ -373,8 +414,7 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
|||
|
||||
if (state->set_view_vertical_focus_to_item){
|
||||
if (highlighted_item != 0){
|
||||
view_set_vertical_focus(app, view,
|
||||
highlighted_item->rectangle.y0, highlighted_item->rectangle.y1);
|
||||
view_set_vertical_focus(app, view, highlighted_item->rectangle.y0, highlighted_item->rectangle.y1);
|
||||
}
|
||||
state->set_view_vertical_focus_to_item = false;
|
||||
}
|
||||
|
@ -384,15 +424,15 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view,
|
|||
item_rect.x0 = x0;
|
||||
item_rect.y0 = 0;
|
||||
item_rect.x1 = x1;
|
||||
item_rect.y1 = item_rect.y0 + line_height;
|
||||
item_rect.y1 = item_rect.y0 + text_field_height;
|
||||
y_pos = item_rect.y1;
|
||||
|
||||
UI_Item item = {};
|
||||
item.type = UIType_TextField;
|
||||
item.activation_level = UIActivation_Active;
|
||||
item.coordinates = UICoordinates_ViewRelative;
|
||||
item.text_field.query = state->lister.query;
|
||||
item.text_field.string = state->lister.text_field;
|
||||
item.text_field.query = state->lister.data.query;
|
||||
item.text_field.string = state->lister.data.text_field;
|
||||
item.user_data = 0;
|
||||
item.rectangle = item_rect;
|
||||
ui_list_add_item(scratch, &list, item);
|
||||
|
@ -412,100 +452,97 @@ lister_prealloced(String string){
|
|||
}
|
||||
|
||||
static void
|
||||
lister_first_init(Partition *arena, Lister *lister, void *user_data, int32_t user_data_size){
|
||||
lister_first_init(Application_Links *app, Lister *lister, void *user_data, int32_t user_data_size, int32_t arena_size){
|
||||
memset(lister, 0, sizeof(*lister));
|
||||
lister->query = make_fixed_width_string(lister->query_space);
|
||||
lister->text_field = make_fixed_width_string(lister->text_field_space);
|
||||
lister->key_string = make_fixed_width_string(lister->key_string_space);
|
||||
if (user_data != 0){
|
||||
lister->user_data = push_array(arena, char, user_data_size);
|
||||
push_align(arena, 8);
|
||||
memcpy(lister->user_data, user_data, user_data_size);
|
||||
lister->data.query = make_fixed_width_string(lister->data.query_space);
|
||||
lister->data.text_field = make_fixed_width_string(lister->data.text_field_space);
|
||||
lister->data.key_string = make_fixed_width_string(lister->data.key_string_space);
|
||||
if (arena_size < user_data_size){
|
||||
arena_size = user_data_size;
|
||||
}
|
||||
lister->data.user_data_size = 0;
|
||||
if (arena_size != 0){
|
||||
lister_arena_clear_data_ensure_bytes(app, lister, arena_size);
|
||||
lister->data.user_data = push_array(&lister->arena, char, user_data_size);
|
||||
push_align(&lister->arena, 8);
|
||||
if (user_data != 0){
|
||||
memcpy(lister->data.user_data, user_data, user_data_size);
|
||||
}
|
||||
lister->data.user_data_size = user_data_size;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lister_begin_new_item_set(Lister *lister){
|
||||
memset(&lister->options, 0, sizeof(lister->options));
|
||||
lister_begin_new_item_set(Application_Links *app, Lister *lister, int32_t list_memory_size){
|
||||
lister_arena_clear_data_ensure_bytes(app, lister, list_memory_size);
|
||||
memset(&lister->data.options, 0, sizeof(lister->data.options));
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_add_item(Partition *arena, Lister *lister,
|
||||
Lister_Prealloced_String string, Lister_Prealloced_String status,
|
||||
lister_add_item(Lister *lister, Lister_Prealloced_String string, Lister_Prealloced_String status,
|
||||
void *user_data, int32_t extra_space){
|
||||
Lister_Node *node = push_array(arena, Lister_Node, 1);
|
||||
Lister_Node *node = push_array(&lister->arena, Lister_Node, 1);
|
||||
node->string = string.string;
|
||||
node->status = status.string;
|
||||
node->user_data = user_data;
|
||||
node->raw_index = lister->options.count;
|
||||
zdll_push_back(lister->options.first, lister->options.last, node);
|
||||
lister->options.count += 1;
|
||||
void *result = push_array(arena, char, extra_space);
|
||||
push_align(arena, 8);
|
||||
node->raw_index = lister->data.options.count;
|
||||
zdll_push_back(lister->data.options.first, lister->data.options.last, node);
|
||||
lister->data.options.count += 1;
|
||||
void *result = push_array(&lister->arena, char, extra_space);
|
||||
push_align(&lister->arena, 8);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_add_item(Partition *arena, Lister *lister,
|
||||
Lister_Prealloced_String string, String status,
|
||||
lister_add_item(Lister *lister, Lister_Prealloced_String string, String status,
|
||||
void *user_data, int32_t extra_space){
|
||||
return(lister_add_item(arena, lister,
|
||||
string,
|
||||
lister_prealloced(string_push_copy(arena, status)),
|
||||
return(lister_add_item(lister, string, lister_prealloced(string_push_copy(&lister->arena, status)),
|
||||
user_data, extra_space));
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_add_item(Partition *arena, Lister *lister,
|
||||
String string, Lister_Prealloced_String status,
|
||||
lister_add_item(Lister *lister, String string, Lister_Prealloced_String status,
|
||||
void *user_data, int32_t extra_space){
|
||||
return(lister_add_item(arena, lister,
|
||||
lister_prealloced(string_push_copy(arena, string)),
|
||||
status,
|
||||
return(lister_add_item(lister, lister_prealloced(string_push_copy(&lister->arena, string)), status,
|
||||
user_data, extra_space));
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_add_item(Partition *arena, Lister *lister,
|
||||
String string, String status,
|
||||
void *user_data, int32_t extra_space){
|
||||
return(lister_add_item(arena, lister,
|
||||
lister_prealloced(string_push_copy(arena, string)),
|
||||
lister_prealloced(string_push_copy(arena, status)),
|
||||
lister_add_item(Lister *lister, String string, String status, void *user_data, int32_t extra_space){
|
||||
return(lister_add_item(lister,
|
||||
lister_prealloced(string_push_copy(&lister->arena, string)),
|
||||
lister_prealloced(string_push_copy(&lister->arena, status)),
|
||||
user_data, extra_space));
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_add_ui_item(Partition *arena, Lister *lister,
|
||||
Lister_Prealloced_String string, int32_t index,
|
||||
void *user_data, int32_t extra_space){
|
||||
Lister_Node *node = push_array(arena, Lister_Node, 1);
|
||||
lister_add_theme_item(Lister *lister,
|
||||
Lister_Prealloced_String string, int32_t index,
|
||||
void *user_data, int32_t extra_space){
|
||||
Lister_Node *node = push_array(&lister->arena, Lister_Node, 1);
|
||||
node->string = string.string;
|
||||
node->index = index;
|
||||
node->user_data = user_data;
|
||||
node->raw_index = lister->options.count;
|
||||
zdll_push_back(lister->options.first, lister->options.last, node);
|
||||
lister->options.count += 1;
|
||||
void *result = push_array(arena, char, extra_space);
|
||||
push_align(arena, 8);
|
||||
node->raw_index = lister->data.options.count;
|
||||
zdll_push_back(lister->data.options.first, lister->data.options.last, node);
|
||||
lister->data.options.count += 1;
|
||||
void *result = push_array(&lister->arena, char, extra_space);
|
||||
push_align(&lister->arena, 8);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_add_ui_item(Partition *arena, Lister *lister,
|
||||
String string, int32_t index,
|
||||
void *user_data, int32_t extra_space){
|
||||
return(lister_add_ui_item(arena, lister,
|
||||
lister_prealloced(string_push_copy(arena, string)),
|
||||
index,
|
||||
user_data, extra_space));
|
||||
lister_add_theme_item(Lister *lister, String string, int32_t index,
|
||||
void *user_data, int32_t extra_space){
|
||||
return(lister_add_theme_item(lister, lister_prealloced(string_push_copy(&lister->arena, string)), index,
|
||||
user_data, extra_space));
|
||||
}
|
||||
|
||||
static void*
|
||||
lister_get_user_data(Lister *lister, int32_t index){
|
||||
if (0 <= index && index < lister->options.count){
|
||||
lister_get_user_data(Lister_Data *lister_data, int32_t index){
|
||||
if (0 <= index && index < lister_data->options.count){
|
||||
int32_t counter = 0;
|
||||
for (Lister_Node *node = lister->options.first;
|
||||
for (Lister_Node *node = lister_data->options.first;
|
||||
node != 0;
|
||||
node = node->next){
|
||||
if (counter == index){
|
||||
|
@ -518,10 +555,9 @@ lister_get_user_data(Lister *lister, int32_t index){
|
|||
}
|
||||
|
||||
static void
|
||||
lister_call_refresh_handler(Application_Links *app, Partition *arena, Lister *lister){
|
||||
if (lister->handlers.refresh != 0){
|
||||
arena->pos = 0;
|
||||
lister->handlers.refresh(app, arena, lister);
|
||||
lister_call_refresh_handler(Application_Links *app, Lister *lister){
|
||||
if (lister->data.handlers.refresh != 0){
|
||||
lister->data.handlers.refresh(app, lister);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,9 +570,9 @@ lister_default(Application_Links *app, Partition *scratch, Heap *heap,
|
|||
{
|
||||
view_end_ui_mode(app, view);
|
||||
state->initialized = false;
|
||||
if (state->arena.base != 0){
|
||||
heap_free(heap, state->arena.base);
|
||||
memset(&state->arena, 0, sizeof(state->arena));
|
||||
if (state->lister.arena.base != 0){
|
||||
memory_free(app, state->lister.arena.base, state->lister.arena.max);
|
||||
memset(&state->lister.arena, 0, sizeof(state->lister.arena));
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -549,7 +585,7 @@ lister_default(Application_Links *app, Partition *scratch, Heap *heap,
|
|||
{
|
||||
view_begin_ui_mode(app, view);
|
||||
state->item_index = 0;
|
||||
lister_call_refresh_handler(app, &state->arena, &state->lister);
|
||||
lister_call_refresh_handler(app, &state->lister);
|
||||
lister_update_ui(app, scratch, view, state);
|
||||
}break;
|
||||
}
|
||||
|
@ -559,7 +595,7 @@ static void
|
|||
lister_call_activate_handler(Application_Links *app, Partition *scratch, Heap *heap,
|
||||
View_Summary *view, Lister_State *state,
|
||||
void *user_data, bool32 activated_by_mouse){
|
||||
Lister *lister = &state->lister;
|
||||
Lister_Data *lister = &state->lister.data;
|
||||
if (lister->handlers.activate != 0){
|
||||
lister->handlers.activate(app, scratch, heap, view, state,
|
||||
lister->text_field, user_data, activated_by_mouse);
|
||||
|
@ -570,32 +606,32 @@ lister_call_activate_handler(Application_Links *app, Partition *scratch, Heap *h
|
|||
}
|
||||
|
||||
static void
|
||||
lister_set_query_string(Lister *lister, char *string){
|
||||
lister_set_query_string(Lister_Data *lister, char *string){
|
||||
copy(&lister->query, string);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_set_query_string(Lister *lister, String string){
|
||||
lister_set_query_string(Lister_Data *lister, String string){
|
||||
copy(&lister->query, string);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_set_text_field_string(Lister *lister, char *string){
|
||||
lister_set_text_field_string(Lister_Data *lister, char *string){
|
||||
copy(&lister->text_field, string);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_set_text_field_string(Lister *lister, String string){
|
||||
lister_set_text_field_string(Lister_Data *lister, String string){
|
||||
copy(&lister->text_field, string);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_set_key_string(Lister *lister, char *string){
|
||||
lister_set_key_string(Lister_Data *lister, char *string){
|
||||
copy(&lister->key_string, string);
|
||||
}
|
||||
|
||||
static void
|
||||
lister_set_key_string(Lister *lister, String string){
|
||||
lister_set_key_string(Lister_Data *lister, String string){
|
||||
copy(&lister->key_string, string);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ typedef void Lister_Activation_Function_Type(Application_Links *app, Partition *
|
|||
View_Summary *view, struct Lister_State *state,
|
||||
String text_field, void *user_data, bool32 activated_by_mouse);
|
||||
|
||||
typedef void Lister_Regenerate_List_Function_Type(Application_Links *app, Partition *arena, struct Lister *lister);
|
||||
typedef void Lister_Regenerate_List_Function_Type(Application_Links *app, struct Lister *lister);
|
||||
|
||||
struct Lister_Node{
|
||||
Lister_Node *next;
|
||||
|
@ -52,12 +52,13 @@ struct Lister_Handlers{
|
|||
Custom_Command_Function *navigate_down;
|
||||
};
|
||||
|
||||
struct Lister{
|
||||
struct Lister_Data{
|
||||
// Event Handlers
|
||||
Lister_Handlers handlers;
|
||||
|
||||
// List Data
|
||||
void *user_data;
|
||||
int32_t user_data_size;
|
||||
char query_space[256];
|
||||
String query;
|
||||
char text_field_space[256];
|
||||
|
@ -68,19 +69,29 @@ struct Lister{
|
|||
bool32 theme_list;
|
||||
};
|
||||
|
||||
struct Lister_Prealloced_String{
|
||||
String string;
|
||||
struct Lister{
|
||||
Partition arena;
|
||||
Lister_Data data;
|
||||
};
|
||||
|
||||
struct Lister_State{
|
||||
bool32 initialized;
|
||||
Lister lister;
|
||||
|
||||
// Action defered to next UI update
|
||||
bool32 set_view_vertical_focus_to_item;
|
||||
|
||||
// State set directly by input handlers
|
||||
void *hot_user_data;
|
||||
int32_t item_index;
|
||||
|
||||
// State of UI computed during UI update
|
||||
int32_t raw_item_index;
|
||||
bool32 set_view_vertical_focus_to_item;
|
||||
int32_t option_item_count;
|
||||
Partition arena;
|
||||
Lister lister;
|
||||
int32_t item_count_after_filter;
|
||||
};
|
||||
|
||||
struct Lister_Prealloced_String{
|
||||
String string;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
|
13
todo.txt
13
todo.txt
|
@ -4,6 +4,7 @@
|
|||
{
|
||||
[] Recover scroll bars
|
||||
[] Cold scroll
|
||||
[] Optimize lookup in file track data structures
|
||||
}
|
||||
|
||||
Bugs
|
||||
|
@ -12,12 +13,20 @@
|
|||
[x] High CPU usage in listers (endless animation bug)
|
||||
[x] Panel resizing doesn't work
|
||||
[x] On windows file lister: /foo/bar.txt
|
||||
[?] Press Tab in Open File Lister With Text "C:"/Tab when no valid completions in open file lister
|
||||
[x] Notepad like mode clicking to new view doesn't snap the mark
|
||||
[x] Notepad like mode replacing text with cursor at end of selection in middle of long file
|
||||
[] Tab when no valid completions in open file lister
|
||||
[x] Renaming a file to a case insensitively equivalent name on windows deletes the file
|
||||
[x] Start from windows start menu and open file
|
||||
[] opening large projects
|
||||
[] Make lots of new files
|
||||
[] Texture binding changes too often problem
|
||||
[] SSHFS segfault on linux
|
||||
[] New file when the file is already open
|
||||
[] really long single line wrapped (300,000?)
|
||||
[] Mac german keyboard layout
|
||||
[] Linux animate bug? (Lister lag)
|
||||
[] Modifiers on scroll wheels not working?
|
||||
Repro Needed
|
||||
{
|
||||
[?] pasting long comment at top of code files doesn't always parse right away???
|
||||
|
@ -26,7 +35,6 @@
|
|||
{
|
||||
[] saving to removable media -> need more info
|
||||
[] crash on obj file (san-miguel-low-poly.obj) -> need more info
|
||||
[] Graphics problem (fonts not rendering) -> need more info
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +60,7 @@ Long Term
|
|||
Bugs
|
||||
{
|
||||
[] Remote Desktop Doesn't Work -> Need Renderer Modularity & Software Renderer
|
||||
[] Graphics problem (fonts not rendering) -> need more info
|
||||
[] Jim's file is blank even though it tries to load a real file (wtf)
|
||||
[] Lexing Scientific Notation " 3.402823466e+38F "
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue