diff --git a/4coder_API/4coder_types.h b/4coder_API/4coder_types.h index 9a5daa2f..3faf6418 100644 --- a/4coder_API/4coder_types.h +++ b/4coder_API/4coder_types.h @@ -714,7 +714,11 @@ A handle for a managed object can "go bad" when it's scope is cleared, or when i ManagedObjectType_Memory = 1, /* DOC(A marker object is used to place markers into buffers that move along with the text upon which they are placed. A marker object has a specific buffer to which it is attached, and must be allocated in a scope dependent upon the lifetime of that buffer. Marker objects always use the Marker type for their items, and their item size is always sizeof(Marker). When a marker object is freed, all of the marker visuals attached to it are also freed and the specific buffer of the object no longer adjusts the marker data when edits occur.) */ ManagedObjectType_Markers = 2, - ManagedObjectType_COUNT = 3, + /* DOC(TODO) */ + ManagedObjectType_Arena = 3, + + + ManagedObjectType_COUNT = 4, }; /* DOC(A handle to a managed scope. A managed scope contains variables and objects all of which can be freed and reset in optimized bulk operations. Many managed scopes are created and destroyed by the core to track the lifetime of entities like buffers and views. Because a managed scope contains it's own copy of the managed variables, managed scopes can also be used as a keying mechanism to store and retrieve special information related to entities like buffers and views.) */ @@ -844,92 +848,6 @@ STRUCT Query_Bar{ String string; }; -/* DOC(An enumeration of the types of UI widget items that can be placed in a UI.) */ -ENUM(int16_t, UI_Item_Type){ - /* DOC(An 'option' is a rectangle with a margin that can be highlighted, and a main string in default text color, and a secondary string in pop2 color, on a single line centered vertically in the item rectangle.) */ - UIType_Option = 0, - /* DOC(A 'text field' is a rectangle with a query string in pop1 color, and a main string in default text color, on a single line centered verticall in the item rectangle.) */ - UIType_TextField = 1, - /* DOC(A 'color theme' is a rectangle that ignores the active color palette and previews a specified color palette, with a specified string on the first line. This item is particularly meant for creating the color theme lister, but could be reused for anything, however there is no way to remove all the sample text in the widget added alongside the main string.) */ - UIType_ColorTheme = 2, -}; - -/* DOC(An enumeration of the levels of activation that can be placed on an item in a UI, this can effect the appearance of some widgets.) */ -ENUM(int8_t, UI_Activation_Level){ - UIActivation_None = 0, - UIActivation_Hover = 1, - UIActivation_Active = 2, -}; - -/* DOC(An enumeration of the coordinate systems in which an item's rectangle can be specified. This is not always a convenience feature as it means after scrolling the widget data does not necessarily needed to be updated, thus saving extra work. All coordiante systems are in pixels, with y increasing downward, and x increasing rightward.) */ -ENUM(int8_t, UI_Coordinate_System){ - /* DOC(The 'view' coordiante system is effected by the scroll value of the view. If the y scroll value is at 100 and an item is placed with a vertical range from 50 to 90, the item is not visible. When the scroll value is at (0,0), this coordinate system aligns with the view relative coordiante system.) */ - UICoordinates_ViewSpace = 0, - /* DOC(The 'panel' coordiante system is only effected by the screen coordinates of the panel. (0,0) is always the top left corner of space inside the panel margin.) */ - UICoordinates_PanelSpace = 1, - UICoordinates_COUNT = 2, -}; - -/* DOC(A UI_Item is essentially the data to specify a single widget. The exact appearance and qualities of a displayed widget are determined by the item's type.) -DOC_SEE(UI_Item_Type) -DOC_SEE(UI_Activation_Level) -DOC_SEE(UI_Coordinate_System) -*/ -STRUCT UI_Item{ - /* DOC(The type of the item.) */ - UI_Item_Type type; - /* DOC(The activation level of the item.) */ - UI_Activation_Level activation_level; - /* DOC(The coordinate system in which the item's rectanlge is expressed.) */ - UI_Coordinate_System coordinates; - /* DOC(The rectangle of an item, combined with it's coordinate system, specify where on the screen the widget will be rendered.) */ - i32_Rect rectangle; - // 32-bits of padding to fill here - union{ - struct{ - /* DOC(The main string of an 'option' widget.) */ - String string; - /* DOC(The secondary string of an 'option' widget.) */ - String status; - } option; - struct{ - /* DOC(The query string of a 'text field' widget.) */ - String query; - /* DOC(The main string of an 'text field' widget.) */ - String string; - } text_field; - struct{ - /* DOC(The custom first line string of the color theme preview block.) */ - String string; - /* DOC(The index of the color theme to be used with the preview block.) */ - int32_t index; - } color_theme; - }; - /* DOC(All items can have an attached user_data pointer to associate the item back to whatever user space data or object is needed for interactign with the item.) */ - void *user_data; -}; - -/* DOC(Wraps a UI_Item in a doubly linked list node.) */ -STRUCT UI_Item_Node{ - UI_Item_Node *next; - UI_Item_Node *prev; - UI_Item fixed; -}; - -/* DOC(A zero-ended doubly linked list object.) */ -STRUCT UI_List{ - UI_Item_Node *first; - UI_Item_Node *last; - int32_t count; -}; - -/* DOC(An array of UI_Items and a set of bounding boxes that store the union item rectangle per coordiante system, used to optimize activation and re-render operations.) */ -STRUCT UI_Control{ - UI_Item *items; - int32_t count; - i32_Rect bounding_box[UICoordinates_COUNT]; -}; - TYPEDEF_FUNC void UI_Quit_Function_Type(struct Application_Links *app, View_Summary view); #define UI_QUIT_FUNCTION(name) void name(struct Application_Links *app, View_Summary view) diff --git a/4coder_api_transition_30_31.cpp b/4coder_api_transition_30_31.cpp index 92fa440e..33a35820 100644 --- a/4coder_api_transition_30_31.cpp +++ b/4coder_api_transition_30_31.cpp @@ -480,26 +480,6 @@ view_end_ui_mode(Application_Links *app, View_Summary *view){ return(result); } -static bool32 -view_set_ui(Application_Links *app, View_Summary *view, UI_Control *control, UI_Quit_Function_Type *quit_function){ - bool32 result = false; - if (view != 0 && view->exists){ - result = view_set_ui(app, view->view_id, control, quit_function); - get_view_summary(app, view->view_id, AccessAll, view); - } - return(result); -} - -static UI_Control -view_get_ui_copy(Application_Links *app, View_Summary *view, struct Partition *part){ - UI_Control result = {}; - if (view != 0 && view->exists){ - view_get_ui_copy(app, view->view_id, part, &result); - get_view_summary(app, view->view_id, AccessAll, view); - } - return(result); -} - static bool32 view_set_highlight(Application_Links *app, View_ID view_id, int32_t start, int32_t end, bool32 turn_on){ // NOTE(allen): this feature is completely removed, transition to using highlighted markers instead diff --git a/4coder_default_framework.cpp b/4coder_default_framework.cpp index c715afea..a55a5bb8 100644 --- a/4coder_default_framework.cpp +++ b/4coder_default_framework.cpp @@ -5,9 +5,6 @@ // TOP -static Partition global_part; -static Heap global_heap; - static void unlock_jump_buffer(void){ locked_buffer.size = 0; @@ -311,26 +308,24 @@ CUSTOM_DOC("Switch to a named key binding map.") //////////////////////////////// static void -default_4coder_initialize(Application_Links *app, int32_t override_font_size, bool32 override_hinting){ - int32_t part_size = (32 << 20); - int32_t heap_size = ( 4 << 20); - +default_4coder_initialize(Application_Links *app, i32 override_font_size, b32 override_hinting){ + i32 part_size = (16 << 10); void *part_mem = memory_allocate(app, part_size); global_part = make_part(part_mem, part_size); + i32 heap_size = (4 << 20); void *heap_mem = memory_allocate(app, heap_size); heap_init(&global_heap); heap_extend(&global_heap, heap_mem, heap_size); - static const char message[] = "" + static char message[] = "Welcome to " VERSION "\n" "If you're new to 4coder there are some tutorials at http://4coder.net/tutorials.html\n" "Direct bug reports to editor@4coder.net for maximum reply speed\n" "Questions or requests can go to editor@4coder.net or to 4coder.handmade.network\n" "The change log can be found in CHANGES.txt\n" "\n"; - String msg = make_lit_string(message); - print_message(app, msg.str, msg.size); + print_message(app, message, sizeof(message) - 1); #if 0 load_folder_of_themes_into_live_set(app, &global_part, "themes"); @@ -342,6 +337,7 @@ default_4coder_initialize(Application_Links *app, int32_t override_font_size, bo view_paste_index_loc = managed_variable_create_or_get_id(app, "DEFAULT.paste_index" , 0); view_is_passive_loc = managed_variable_create_or_get_id(app, "DEFAULT.is_passive" , 0); view_snap_mark_to_cursor = managed_variable_create_or_get_id(app, "DEFAULT.mark_to_cursor", 0); + view_ui_data = managed_variable_create_or_get_id(app, "DEFAULT.ui_data" , 0); } static void diff --git a/4coder_default_framework_variables.cpp b/4coder_default_framework_variables.cpp index 31a68215..c7861743 100644 --- a/4coder_default_framework_variables.cpp +++ b/4coder_default_framework_variables.cpp @@ -39,22 +39,26 @@ static Managed_Variable_ID view_next_rewrite_loc = 0; static Managed_Variable_ID view_paste_index_loc = 0; static Managed_Variable_ID view_is_passive_loc = 0; static Managed_Variable_ID view_snap_mark_to_cursor = 0; +static Managed_Variable_ID view_ui_data = 0; static char out_buffer_space[1024]; static char command_space[1024]; static char hot_directory_space[1024]; -static bool32 highlight_line_at_cursor = true; -static bool32 do_matching_enclosure_highlight = true; -static bool32 do_matching_paren_highlight = true; -static bool32 do_colored_comment_keywords = true; -static bool32 suppressing_mouse = false; +static b32 highlight_line_at_cursor = true; +static b32 do_matching_enclosure_highlight = true; +static b32 do_matching_paren_highlight = true; +static b32 do_colored_comment_keywords = true; +static b32 suppressing_mouse = false; -static bool32 cursor_is_hidden = false; +static b32 cursor_is_hidden = false; static b32 show_fps_hud = false; +static Partition global_part; +static Heap global_heap; + enum{ FCoderMode_Original = 0, FCoderMode_NotepadLike = 1, diff --git a/4coder_default_hooks.cpp b/4coder_default_hooks.cpp index 303152c9..d2939b10 100644 --- a/4coder_default_hooks.cpp +++ b/4coder_default_hooks.cpp @@ -274,7 +274,9 @@ MODIFY_COLOR_TABLE_SIG(default_modify_color_table){ return(color_table); } -RENDER_CALLER_SIG(default_render_caller){ +static void +default_buffer_render_caller(Application_Links *app, View_ID view_id, Range on_screen_range, i32 frame_index, f32 literal_dt, f32 animation_dt, + Render_Callback *do_core_render){ View_Summary view = get_view(app, view_id, AccessAll); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessAll); View_Summary active_view = get_active_view(app, AccessAll); @@ -514,9 +516,9 @@ RENDER_CALLER_SIG(default_render_caller){ char space[256]; String str = make_fixed_width_string(space); - Fancy_Color white = fancy_from_rgba_color(1.f, 1.f, 1.f, 1.f); - Fancy_Color pink = fancy_from_rgba_color(1.f, 0.f, 1.f, 1.f); - Fancy_Color green = fancy_from_rgba_color(0.f, 1.f, 0.f, 1.f); + Fancy_Color white = fancy_rgba(1.f, 1.f, 1.f, 1.f); + Fancy_Color pink = fancy_rgba(1.f, 0.f, 1.f, 1.f); + Fancy_Color green = fancy_rgba(0.f, 1.f, 0.f, 1.f); Fancy_String_List list = {}; push_fancy_stringf(&arena, &list, pink , "FPS: "); push_fancy_stringf(&arena, &list, green, "["); @@ -545,6 +547,88 @@ RENDER_CALLER_SIG(default_render_caller){ managed_scope_clear_self_all_dependent_scopes(app, render_scope); } +static int_color +get_margin_color(i32 level){ + int_color margin = 0; + switch (level){ + default: + case UIActivation_None: + { + margin = Stag_List_Item; + }break; + case UIActivation_Hover: + { + margin = Stag_List_Item_Hover; + }break; + case UIActivation_Active: + { + margin = Stag_List_Item_Active; + }break; + } + return(margin); +} + +static void +default_ui_render_caller(Application_Links *app, View_ID view_id, Range on_screen_range, i32 frame_index, f32 literal_dt, f32 animation_dt, + Render_Callback *do_core_render){ + UI_Data *ui_data = 0; + Arena *ui_arena = 0; + if (view_get_ui_data(app, view_id, ViewGetUIFlag_KeepDataAsIs, &ui_data, &ui_arena)){ + View_Summary view = {}; + if (get_view_summary(app, view_id, AccessAll, &view)){ + Rect_f32 rect_f32 = f32R(view.render_region); + GUI_Scroll_Vars ui_scroll = view.scroll_vars; + + for (UI_Item *item = ui_data->list.first; + item != 0; + item = item->next){ + Rect_i32 item_rect_i32 = item->rect_outer; + Rect_f32 item_rect = f32R(item_rect_i32); + + switch (item->coordinates){ + case UICoordinates_ViewSpace: + { + item_rect.p0 -= ui_scroll.scroll_p; + item_rect.p1 -= ui_scroll.scroll_p; + }break; + case UICoordinates_PanelSpace: + {}break; + } + + if (rect_overlap(item_rect, rect_f32)){ + Rect_f32 inner_rect = get_inner_rect(item_rect, (f32)item->inner_margin); + + Face_ID font_id = 0; + get_face_id(app, view.buffer_id, &font_id); + + // TODO(allen): get font_id line height + f32 line_height = view.line_height; + f32 info_height = (f32)item->line_count*line_height; + + draw_rectangle(app, inner_rect, Stag_Back); + Vec2 p = V2(inner_rect.x0 + 3.f, (f32)(round32((inner_rect.y0 + inner_rect.y1 - info_height)*0.5f))); + for (i32 i = 0; i < item->line_count; i += 1){ + draw_fancy_string(app, font_id, item->lines[i].first, p, Stag_Default, 0, 0, V2(1.f, 0)); + p.y += view.line_height; + } + if (item->inner_margin > 0){ + draw_margin(app, item_rect, inner_rect, get_margin_color(item->activation_level)); + } + } + } + } + } +} + +RENDER_CALLER_SIG(default_render_caller){ + if (view_is_in_ui_mode(app, view_id)){ + default_ui_render_caller(app, view_id, on_screen_range, frame_index, literal_dt, animation_dt, do_core_render); + } + else{ + default_buffer_render_caller(app, view_id, on_screen_range, frame_index, literal_dt, animation_dt, do_core_render); + } +} + HOOK_SIG(default_exit){ // If this returns zero it cancels the exit. if (allow_immediate_close_without_checking_for_changes){ @@ -750,9 +834,9 @@ OPEN_FILE_HOOK_SIG(default_file_settings){ Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll); Assert(buffer.exists); - bool32 treat_as_code = false; - bool32 treat_as_todo = false; - bool32 lex_without_strings = false; + b32 treat_as_code = false; + b32 treat_as_todo = false; + b32 lex_without_strings = false; CString_Array extensions = get_code_extensions(&global_config.code_exts); @@ -819,8 +903,8 @@ OPEN_FILE_HOOK_SIG(default_file_settings){ } } - int32_t map_id = (treat_as_code)?((int32_t)default_code_map):((int32_t)mapid_file); - int32_t map_id_query = 0; + i32 map_id = (treat_as_code)?((i32)default_code_map):((i32)mapid_file); + i32 map_id_query = 0; buffer_set_setting(app, &buffer, BufferSetting_MapID, default_lister_ui_map); buffer_get_setting(app, &buffer, BufferSetting_MapID, &map_id_query); @@ -834,9 +918,9 @@ OPEN_FILE_HOOK_SIG(default_file_settings){ buffer_set_setting(app, &buffer, BufferSetting_ParserContext, parse_context_id); // NOTE(allen): Decide buffer settings - bool32 wrap_lines = true; - bool32 use_virtual_whitespace = false; - bool32 use_lexer = false; + b32 wrap_lines = true; + b32 use_virtual_whitespace = false; + b32 use_lexer = false; if (treat_as_todo){ lex_without_strings = true; wrap_lines = true; diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index 7e8ca600..1ed64308 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -25,9 +25,9 @@ #include "4coder_lib/4cpp_lexer.h" -#include "4coder_ui_helper.h" #include "4coder_helper.h" #include "4coder_fancy.h" +#include "4coder_ui_helper.h" #include "4coder_default_framework.h" #include "4coder_mirror.h" #include "4coder_config.h" diff --git a/4coder_fancy.cpp b/4coder_fancy.cpp index 6a6b079f..ac3eb63b 100644 --- a/4coder_fancy.cpp +++ b/4coder_fancy.cpp @@ -5,7 +5,7 @@ // TOP static Fancy_Color -blend_color(id_color a, f32 t, id_color b){ +fancy_blend(id_color a, f32 t, id_color b){ Fancy_Color result = {}; result.index_a = (u16)a; result.index_b = (u16)b; @@ -17,7 +17,7 @@ blend_color(id_color a, f32 t, id_color b){ } static Fancy_Color -single_color(id_color a){ +fancy_id(id_color a){ Fancy_Color result = {}; result.index_a = (u16)a; result.index_b = 0; @@ -29,7 +29,7 @@ single_color(id_color a){ } static Fancy_Color -fancy_from_rgba_color(argb_color color){ +fancy_rgba(argb_color color){ Fancy_Color result = {}; result.rgba = color; result.code = 0; @@ -37,8 +37,8 @@ fancy_from_rgba_color(argb_color color){ } static Fancy_Color -fancy_from_rgba_color(f32 r, f32 g, f32 b, f32 a){ - Fancy_Color result = fancy_from_rgba_color(pack_color4(V4(r, g, b, a))); +fancy_rgba(f32 r, f32 g, f32 b, f32 a){ + Fancy_Color result = fancy_rgba(pack_color4(V4(r, g, b, a))); return(result); } @@ -84,33 +84,52 @@ is_valid(Fancy_Color source){ return(result); } +static void +fancy_string_list_push(Fancy_String_List *list, Fancy_String *string){ + list->last = (list->last ? list->last->next : list->first) = string; +} + static Fancy_String * push_fancy_string(Arena *arena, Fancy_String_List *list, Fancy_Color fore, Fancy_Color back, String value){ Fancy_String *result = push_array(arena, Fancy_String, 1); + memset(result, 0, sizeof(*result)); + result->value = string_push_copy(arena, value); result->fore = fore; result->back = back; - result->pre_margin = 0; - result->post_margin = 0; - result->next = 0; if (list != 0){ - list->last = (list->last ? list->last->next : list->first) = result; + fancy_string_list_push(list, result); } return(result); } +static Fancy_String * +push_fancy_string(Arena *arena, Fancy_Color fore, Fancy_Color back, String value){ + return(push_fancy_string(arena, 0, fore, back, value)); +} + static Fancy_String * push_fancy_string(Arena *arena, Fancy_String_List *list, Fancy_Color fore, String value){ return(push_fancy_string(arena, list, fore, pass_through_fancy_color(), value)); } +static Fancy_String * +push_fancy_string(Arena *arena, Fancy_Color fore, String value){ + return(push_fancy_string(arena, 0, fore, pass_through_fancy_color(), value)); +} + static Fancy_String * push_fancy_string(Arena *arena, Fancy_String_List *list, String value){ return(push_fancy_string(arena, list, pass_through_fancy_color(), pass_through_fancy_color(), value)); } +static Fancy_String * +push_fancy_string(Arena *arena, String value){ + return(push_fancy_string(arena, 0, pass_through_fancy_color(), pass_through_fancy_color(), value)); +} + static Fancy_String* push_fancy_vstringf(Arena *arena, Fancy_String_List *list, Fancy_Color fore, Fancy_Color back, char *format, va_list args){ // TODO(casey): Allen, ideally we would have our own formatter here that just outputs into a buffer and can't ever "run out of space". @@ -150,6 +169,14 @@ push_fancy_stringf(Arena *arena, Fancy_String_List *list, char *format, ...){ return(result); } +static Fancy_String_List +fancy_string_list_single(Fancy_String *fancy_string){ + Fancy_String_List list = {}; + list.first = fancy_string; + list.last = fancy_string; + return(list); +} + static Vec2 draw_fancy_string(Application_Links *app, Face_ID font_id, Fancy_String *string, Vec2 P, int_color fore, int_color back, u32 flags, Vec2 dP){ diff --git a/4coder_generated/app_functions.h b/4coder_generated/app_functions.h index c2f8efdb..3b312eb2 100644 --- a/4coder_generated/app_functions.h +++ b/4coder_generated/app_functions.h @@ -60,8 +60,9 @@ struct Application_Links; #define VIEW_POST_FADE_SIG(n) bool32 n(Application_Links *app, View_ID view_id, float seconds, int32_t start, int32_t end, int_color color) #define VIEW_BEGIN_UI_MODE_SIG(n) bool32 n(Application_Links *app, View_ID view_id) #define VIEW_END_UI_MODE_SIG(n) bool32 n(Application_Links *app, View_ID view_id) -#define VIEW_SET_UI_SIG(n) bool32 n(Application_Links *app, View_ID view_id, UI_Control *control, UI_Quit_Function_Type *quit_function) -#define VIEW_GET_UI_COPY_SIG(n) bool32 n(Application_Links *app, View_ID view_id, struct Partition *part, UI_Control *ui_control_out) +#define VIEW_IS_IN_UI_MODE_SIG(n) bool32 n(Application_Links *app, View_ID view_id) +#define VIEW_SET_QUIT_UI_HANDLER_SIG(n) bool32 n(Application_Links *app, View_ID view_id, UI_Quit_Function_Type *quit_function) +#define VIEW_GET_QUIT_UI_HANDLER_SIG(n) bool32 n(Application_Links *app, View_ID view_id, UI_Quit_Function_Type **quit_function_out) #define CREATE_USER_MANAGED_SCOPE_SIG(n) Managed_Scope n(Application_Links *app) #define DESTROY_USER_MANAGED_SCOPE_SIG(n) bool32 n(Application_Links *app, Managed_Scope scope) #define GET_GLOBAL_MANAGED_SCOPE_SIG(n) Managed_Scope n(Application_Links *app) @@ -73,8 +74,9 @@ struct Application_Links; #define MANAGED_VARIABLE_CREATE_OR_GET_ID_SIG(n) Managed_Variable_ID n(Application_Links *app, char *null_terminated_name, uint64_t default_value) #define MANAGED_VARIABLE_SET_SIG(n) bool32 n(Application_Links *app, Managed_Scope scope, Managed_Variable_ID id, uint64_t value) #define MANAGED_VARIABLE_GET_SIG(n) bool32 n(Application_Links *app, Managed_Scope scope, Managed_Variable_ID id, uint64_t *value_out) -#define ALLOC_MANAGED_MEMORY_IN_SCOPE_SIG(n) Managed_Object n(Application_Links *app, Managed_Scope scope, int32_t item_size, int32_t count) +#define ALLOC_MANAGED_MEMORY_IN_SCOPE_SIG(n) Managed_Object n(Application_Links *app, Managed_Scope scope, i32 item_size, i32 count) #define ALLOC_BUFFER_MARKERS_ON_BUFFER_SIG(n) Managed_Object n(Application_Links *app, Buffer_ID buffer_id, int32_t count, Managed_Scope *optional_extra_scope) +#define ALLOC_MANAGED_ARENA_IN_SCOPE_SIG(n) Managed_Object n(Application_Links *app, Managed_Scope scope, i32 page_size) #define CREATE_MARKER_VISUAL_SIG(n) Marker_Visual n(Application_Links *app, Managed_Object object) #define MARKER_VISUAL_SET_EFFECT_SIG(n) bool32 n(Application_Links *app, Marker_Visual visual, Marker_Visual_Type type, int_color color, int_color text_color, Marker_Visual_Text_Style text_style) #define MARKER_VISUAL_SET_TAKE_RULE_SIG(n) bool32 n(Application_Links *app, Marker_Visual visual, Marker_Visual_Take_Rule take_rule) @@ -207,8 +209,9 @@ typedef VIEW_SET_BUFFER_SIG(View_Set_Buffer_Function); typedef VIEW_POST_FADE_SIG(View_Post_Fade_Function); typedef VIEW_BEGIN_UI_MODE_SIG(View_Begin_UI_Mode_Function); typedef VIEW_END_UI_MODE_SIG(View_End_UI_Mode_Function); -typedef VIEW_SET_UI_SIG(View_Set_UI_Function); -typedef VIEW_GET_UI_COPY_SIG(View_Get_UI_Copy_Function); +typedef VIEW_IS_IN_UI_MODE_SIG(View_Is_In_UI_Mode_Function); +typedef VIEW_SET_QUIT_UI_HANDLER_SIG(View_Set_Quit_UI_Handler_Function); +typedef VIEW_GET_QUIT_UI_HANDLER_SIG(View_Get_Quit_UI_Handler_Function); typedef CREATE_USER_MANAGED_SCOPE_SIG(Create_User_Managed_Scope_Function); typedef DESTROY_USER_MANAGED_SCOPE_SIG(Destroy_User_Managed_Scope_Function); typedef GET_GLOBAL_MANAGED_SCOPE_SIG(Get_Global_Managed_Scope_Function); @@ -222,6 +225,7 @@ typedef MANAGED_VARIABLE_SET_SIG(Managed_Variable_Set_Function); typedef MANAGED_VARIABLE_GET_SIG(Managed_Variable_Get_Function); typedef ALLOC_MANAGED_MEMORY_IN_SCOPE_SIG(Alloc_Managed_Memory_In_Scope_Function); typedef ALLOC_BUFFER_MARKERS_ON_BUFFER_SIG(Alloc_Buffer_Markers_On_Buffer_Function); +typedef ALLOC_MANAGED_ARENA_IN_SCOPE_SIG(Alloc_Managed_Arena_In_Scope_Function); typedef CREATE_MARKER_VISUAL_SIG(Create_Marker_Visual_Function); typedef MARKER_VISUAL_SET_EFFECT_SIG(Marker_Visual_Set_Effect_Function); typedef MARKER_VISUAL_SET_TAKE_RULE_SIG(Marker_Visual_Set_Take_Rule_Function); @@ -356,8 +360,9 @@ View_Set_Buffer_Function *view_set_buffer; View_Post_Fade_Function *view_post_fade; View_Begin_UI_Mode_Function *view_begin_ui_mode; View_End_UI_Mode_Function *view_end_ui_mode; -View_Set_UI_Function *view_set_ui; -View_Get_UI_Copy_Function *view_get_ui_copy; +View_Is_In_UI_Mode_Function *view_is_in_ui_mode; +View_Set_Quit_UI_Handler_Function *view_set_quit_ui_handler; +View_Get_Quit_UI_Handler_Function *view_get_quit_ui_handler; Create_User_Managed_Scope_Function *create_user_managed_scope; Destroy_User_Managed_Scope_Function *destroy_user_managed_scope; Get_Global_Managed_Scope_Function *get_global_managed_scope; @@ -371,6 +376,7 @@ Managed_Variable_Set_Function *managed_variable_set; Managed_Variable_Get_Function *managed_variable_get; Alloc_Managed_Memory_In_Scope_Function *alloc_managed_memory_in_scope; Alloc_Buffer_Markers_On_Buffer_Function *alloc_buffer_markers_on_buffer; +Alloc_Managed_Arena_In_Scope_Function *alloc_managed_arena_in_scope; Create_Marker_Visual_Function *create_marker_visual; Marker_Visual_Set_Effect_Function *marker_visual_set_effect; Marker_Visual_Set_Take_Rule_Function *marker_visual_set_take_rule; @@ -504,8 +510,9 @@ View_Set_Buffer_Function *view_set_buffer_; View_Post_Fade_Function *view_post_fade_; View_Begin_UI_Mode_Function *view_begin_ui_mode_; View_End_UI_Mode_Function *view_end_ui_mode_; -View_Set_UI_Function *view_set_ui_; -View_Get_UI_Copy_Function *view_get_ui_copy_; +View_Is_In_UI_Mode_Function *view_is_in_ui_mode_; +View_Set_Quit_UI_Handler_Function *view_set_quit_ui_handler_; +View_Get_Quit_UI_Handler_Function *view_get_quit_ui_handler_; Create_User_Managed_Scope_Function *create_user_managed_scope_; Destroy_User_Managed_Scope_Function *destroy_user_managed_scope_; Get_Global_Managed_Scope_Function *get_global_managed_scope_; @@ -519,6 +526,7 @@ Managed_Variable_Set_Function *managed_variable_set_; Managed_Variable_Get_Function *managed_variable_get_; Alloc_Managed_Memory_In_Scope_Function *alloc_managed_memory_in_scope_; Alloc_Buffer_Markers_On_Buffer_Function *alloc_buffer_markers_on_buffer_; +Alloc_Managed_Arena_In_Scope_Function *alloc_managed_arena_in_scope_; Create_Marker_Visual_Function *create_marker_visual_; Marker_Visual_Set_Effect_Function *marker_visual_set_effect_; Marker_Visual_Set_Take_Rule_Function *marker_visual_set_take_rule_; @@ -660,8 +668,9 @@ app_links->view_set_buffer_ = View_Set_Buffer;\ app_links->view_post_fade_ = View_Post_Fade;\ app_links->view_begin_ui_mode_ = View_Begin_UI_Mode;\ app_links->view_end_ui_mode_ = View_End_UI_Mode;\ -app_links->view_set_ui_ = View_Set_UI;\ -app_links->view_get_ui_copy_ = View_Get_UI_Copy;\ +app_links->view_is_in_ui_mode_ = View_Is_In_UI_Mode;\ +app_links->view_set_quit_ui_handler_ = View_Set_Quit_UI_Handler;\ +app_links->view_get_quit_ui_handler_ = View_Get_Quit_UI_Handler;\ app_links->create_user_managed_scope_ = Create_User_Managed_Scope;\ app_links->destroy_user_managed_scope_ = Destroy_User_Managed_Scope;\ app_links->get_global_managed_scope_ = Get_Global_Managed_Scope;\ @@ -675,6 +684,7 @@ app_links->managed_variable_set_ = Managed_Variable_Set;\ app_links->managed_variable_get_ = Managed_Variable_Get;\ app_links->alloc_managed_memory_in_scope_ = Alloc_Managed_Memory_In_Scope;\ app_links->alloc_buffer_markers_on_buffer_ = Alloc_Buffer_Markers_On_Buffer;\ +app_links->alloc_managed_arena_in_scope_ = Alloc_Managed_Arena_In_Scope;\ app_links->create_marker_visual_ = Create_Marker_Visual;\ app_links->marker_visual_set_effect_ = Marker_Visual_Set_Effect;\ app_links->marker_visual_set_take_rule_ = Marker_Visual_Set_Take_Rule;\ @@ -808,8 +818,9 @@ static bool32 view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID static bool32 view_post_fade(Application_Links *app, View_ID view_id, float seconds, int32_t start, int32_t end, int_color color){return(app->view_post_fade(app, view_id, seconds, start, end, color));} static bool32 view_begin_ui_mode(Application_Links *app, View_ID view_id){return(app->view_begin_ui_mode(app, view_id));} static bool32 view_end_ui_mode(Application_Links *app, View_ID view_id){return(app->view_end_ui_mode(app, view_id));} -static bool32 view_set_ui(Application_Links *app, View_ID view_id, UI_Control *control, UI_Quit_Function_Type *quit_function){return(app->view_set_ui(app, view_id, control, quit_function));} -static bool32 view_get_ui_copy(Application_Links *app, View_ID view_id, struct Partition *part, UI_Control *ui_control_out){return(app->view_get_ui_copy(app, view_id, part, ui_control_out));} +static bool32 view_is_in_ui_mode(Application_Links *app, View_ID view_id){return(app->view_is_in_ui_mode(app, view_id));} +static bool32 view_set_quit_ui_handler(Application_Links *app, View_ID view_id, UI_Quit_Function_Type *quit_function){return(app->view_set_quit_ui_handler(app, view_id, quit_function));} +static bool32 view_get_quit_ui_handler(Application_Links *app, View_ID view_id, UI_Quit_Function_Type **quit_function_out){return(app->view_get_quit_ui_handler(app, view_id, quit_function_out));} static Managed_Scope create_user_managed_scope(Application_Links *app){return(app->create_user_managed_scope(app));} static bool32 destroy_user_managed_scope(Application_Links *app, Managed_Scope scope){return(app->destroy_user_managed_scope(app, scope));} static Managed_Scope get_global_managed_scope(Application_Links *app){return(app->get_global_managed_scope(app));} @@ -821,8 +832,9 @@ static Managed_Variable_ID managed_variable_get_id(Application_Links *app, char static Managed_Variable_ID managed_variable_create_or_get_id(Application_Links *app, char *null_terminated_name, uint64_t default_value){return(app->managed_variable_create_or_get_id(app, null_terminated_name, default_value));} static bool32 managed_variable_set(Application_Links *app, Managed_Scope scope, Managed_Variable_ID id, uint64_t value){return(app->managed_variable_set(app, scope, id, value));} static bool32 managed_variable_get(Application_Links *app, Managed_Scope scope, Managed_Variable_ID id, uint64_t *value_out){return(app->managed_variable_get(app, scope, id, value_out));} -static Managed_Object alloc_managed_memory_in_scope(Application_Links *app, Managed_Scope scope, int32_t item_size, int32_t count){return(app->alloc_managed_memory_in_scope(app, scope, item_size, count));} +static Managed_Object alloc_managed_memory_in_scope(Application_Links *app, Managed_Scope scope, i32 item_size, i32 count){return(app->alloc_managed_memory_in_scope(app, scope, item_size, count));} static Managed_Object alloc_buffer_markers_on_buffer(Application_Links *app, Buffer_ID buffer_id, int32_t count, Managed_Scope *optional_extra_scope){return(app->alloc_buffer_markers_on_buffer(app, buffer_id, count, optional_extra_scope));} +static Managed_Object alloc_managed_arena_in_scope(Application_Links *app, Managed_Scope scope, i32 page_size){return(app->alloc_managed_arena_in_scope(app, scope, page_size));} static Marker_Visual create_marker_visual(Application_Links *app, Managed_Object object){return(app->create_marker_visual(app, object));} static bool32 marker_visual_set_effect(Application_Links *app, Marker_Visual visual, Marker_Visual_Type type, int_color color, int_color text_color, Marker_Visual_Text_Style text_style){return(app->marker_visual_set_effect(app, visual, type, color, text_color, text_style));} static bool32 marker_visual_set_take_rule(Application_Links *app, Marker_Visual visual, Marker_Visual_Take_Rule take_rule){return(app->marker_visual_set_take_rule(app, visual, take_rule));} @@ -956,8 +968,9 @@ static bool32 view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID static bool32 view_post_fade(Application_Links *app, View_ID view_id, float seconds, int32_t start, int32_t end, int_color color){return(app->view_post_fade_(app, view_id, seconds, start, end, color));} static bool32 view_begin_ui_mode(Application_Links *app, View_ID view_id){return(app->view_begin_ui_mode_(app, view_id));} static bool32 view_end_ui_mode(Application_Links *app, View_ID view_id){return(app->view_end_ui_mode_(app, view_id));} -static bool32 view_set_ui(Application_Links *app, View_ID view_id, UI_Control *control, UI_Quit_Function_Type *quit_function){return(app->view_set_ui_(app, view_id, control, quit_function));} -static bool32 view_get_ui_copy(Application_Links *app, View_ID view_id, struct Partition *part, UI_Control *ui_control_out){return(app->view_get_ui_copy_(app, view_id, part, ui_control_out));} +static bool32 view_is_in_ui_mode(Application_Links *app, View_ID view_id){return(app->view_is_in_ui_mode_(app, view_id));} +static bool32 view_set_quit_ui_handler(Application_Links *app, View_ID view_id, UI_Quit_Function_Type *quit_function){return(app->view_set_quit_ui_handler_(app, view_id, quit_function));} +static bool32 view_get_quit_ui_handler(Application_Links *app, View_ID view_id, UI_Quit_Function_Type **quit_function_out){return(app->view_get_quit_ui_handler_(app, view_id, quit_function_out));} static Managed_Scope create_user_managed_scope(Application_Links *app){return(app->create_user_managed_scope_(app));} static bool32 destroy_user_managed_scope(Application_Links *app, Managed_Scope scope){return(app->destroy_user_managed_scope_(app, scope));} static Managed_Scope get_global_managed_scope(Application_Links *app){return(app->get_global_managed_scope_(app));} @@ -969,8 +982,9 @@ static Managed_Variable_ID managed_variable_get_id(Application_Links *app, char static Managed_Variable_ID managed_variable_create_or_get_id(Application_Links *app, char *null_terminated_name, uint64_t default_value){return(app->managed_variable_create_or_get_id_(app, null_terminated_name, default_value));} static bool32 managed_variable_set(Application_Links *app, Managed_Scope scope, Managed_Variable_ID id, uint64_t value){return(app->managed_variable_set_(app, scope, id, value));} static bool32 managed_variable_get(Application_Links *app, Managed_Scope scope, Managed_Variable_ID id, uint64_t *value_out){return(app->managed_variable_get_(app, scope, id, value_out));} -static Managed_Object alloc_managed_memory_in_scope(Application_Links *app, Managed_Scope scope, int32_t item_size, int32_t count){return(app->alloc_managed_memory_in_scope_(app, scope, item_size, count));} +static Managed_Object alloc_managed_memory_in_scope(Application_Links *app, Managed_Scope scope, i32 item_size, i32 count){return(app->alloc_managed_memory_in_scope_(app, scope, item_size, count));} static Managed_Object alloc_buffer_markers_on_buffer(Application_Links *app, Buffer_ID buffer_id, int32_t count, Managed_Scope *optional_extra_scope){return(app->alloc_buffer_markers_on_buffer_(app, buffer_id, count, optional_extra_scope));} +static Managed_Object alloc_managed_arena_in_scope(Application_Links *app, Managed_Scope scope, i32 page_size){return(app->alloc_managed_arena_in_scope_(app, scope, page_size));} static Marker_Visual create_marker_visual(Application_Links *app, Managed_Object object){return(app->create_marker_visual_(app, object));} static bool32 marker_visual_set_effect(Application_Links *app, Marker_Visual visual, Marker_Visual_Type type, int_color color, int_color text_color, Marker_Visual_Text_Style text_style){return(app->marker_visual_set_effect_(app, visual, type, color, text_color, text_style));} static bool32 marker_visual_set_take_rule(Application_Links *app, Marker_Visual visual, Marker_Visual_Take_Rule take_rule){return(app->marker_visual_set_take_rule_(app, visual, take_rule));} diff --git a/4coder_generated/command_metadata.h b/4coder_generated/command_metadata.h index 2209cd8b..0c80dcf5 100644 --- a/4coder_generated/command_metadata.h +++ b/4coder_generated/command_metadata.h @@ -254,7 +254,7 @@ int32_t source_name_len; int32_t line_number; }; static Command_Metadata fcoder_metacmd_table[233] = { -{ 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", 40, 250 }, +{ 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", 40, 247 }, { 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", 34, 630 }, { 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", 34, 641 }, { PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 620 }, @@ -264,8 +264,8 @@ static Command_Metadata fcoder_metacmd_table[233] = { { PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 187 }, { PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 155 }, { PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 151 }, -{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 152 }, -{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 162 }, +{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 149 }, +{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 159 }, { PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 209 }, { PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 430 }, { PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 207 }, @@ -275,7 +275,7 @@ static Command_Metadata fcoder_metacmd_table[233] = { { 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, 503 }, -{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 974 }, +{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 973 }, { PROC_LINKS(comment_line, 0), "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 135 }, { PROC_LINKS(comment_line_toggle, 0), "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 159 }, { 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 }, @@ -318,11 +318,11 @@ static Command_Metadata fcoder_metacmd_table[233] = { { 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, 79 }, { 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, 586 }, { 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, 564 }, -{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 775 }, -{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 885 }, -{ 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, 847 }, -{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 756 }, +{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 774 }, +{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 884 }, +{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 916 }, +{ 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, 846 }, +{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 755 }, { PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1583 }, { 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, 166 }, @@ -342,21 +342,21 @@ static Command_Metadata fcoder_metacmd_table[233] = { { PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "w:\\4ed\\code\\4coder_search.cpp", 29, 892 }, { PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\4coder_lists.cpp", 28, 15 }, { PROC_LINKS(lister__backspace_text_field, 0), "lister__backspace_text_field", 28, "A lister mode command that dispatches to the lister's backspace text field handler.", 83, "w:\\4ed\\code\\4coder_lists.cpp", 28, 41 }, -{ PROC_LINKS(lister__backspace_text_field__default, 0), "lister__backspace_text_field__default", 37, "A lister mode command that backspaces one character from the text field.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 146 }, -{ PROC_LINKS(lister__backspace_text_field__file_path, 0), "lister__backspace_text_field__file_path", 39, "A lister mode command that backspaces one character from the text field of a file system list.", 94, "w:\\4ed\\code\\4coder_lists.cpp", 28, 218 }, +{ PROC_LINKS(lister__backspace_text_field__default, 0), "lister__backspace_text_field__default", 37, "A lister mode command that backspaces one character from the text field.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 145 }, +{ PROC_LINKS(lister__backspace_text_field__file_path, 0), "lister__backspace_text_field__file_path", 39, "A lister mode command that backspaces one character from the text field of a file system list.", 94, "w:\\4ed\\code\\4coder_lists.cpp", 28, 217 }, { PROC_LINKS(lister__mouse_press, 0), "lister__mouse_press", 19, "A lister mode command that beings a click interaction with a list item under the mouse.", 87, "w:\\4ed\\code\\4coder_lists.cpp", 28, 86 }, { PROC_LINKS(lister__mouse_release, 0), "lister__mouse_release", 21, "A lister mode command that ends a click interaction with a list item under the mouse, possibly activating it.", 109, "w:\\4ed\\code\\4coder_lists.cpp", 28, 98 }, { PROC_LINKS(lister__move_down, 0), "lister__move_down", 17, "A lister mode command that dispatches to the lister's navigate down handler.", 76, "w:\\4ed\\code\\4coder_lists.cpp", 28, 61 }, -{ PROC_LINKS(lister__move_down__default, 0), "lister__move_down__default", 26, "A lister mode command that moves the highlighted item one down in the list.", 75, "w:\\4ed\\code\\4coder_lists.cpp", 28, 177 }, +{ PROC_LINKS(lister__move_down__default, 0), "lister__move_down__default", 26, "A lister mode command that moves the highlighted item one down in the list.", 75, "w:\\4ed\\code\\4coder_lists.cpp", 28, 176 }, { PROC_LINKS(lister__move_up, 0), "lister__move_up", 15, "A lister mode command that dispatches to the lister's navigate up handler.", 74, "w:\\4ed\\code\\4coder_lists.cpp", 28, 51 }, -{ PROC_LINKS(lister__move_up__default, 0), "lister__move_up__default", 24, "A lister mode command that moves the highlighted item one up in the list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 161 }, +{ PROC_LINKS(lister__move_up__default, 0), "lister__move_up__default", 24, "A lister mode command that moves the highlighted item one up in the list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 160 }, { PROC_LINKS(lister__quit, 0), "lister__quit", 12, "A lister mode command that quits the list without executing any actions.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 8 }, -{ PROC_LINKS(lister__repaint, 0), "lister__repaint", 15, "A lister mode command that updates the lists UI data.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 115 }, +{ PROC_LINKS(lister__repaint, 0), "lister__repaint", 15, "A lister mode command that updates the lists UI data.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 114 }, { PROC_LINKS(lister__wheel_scroll, 0), "lister__wheel_scroll", 20, "A lister mode command that scrolls the list in response to the mouse wheel.", 75, "w:\\4ed\\code\\4coder_lists.cpp", 28, 71 }, { PROC_LINKS(lister__write_character, 0), "lister__write_character", 23, "A lister mode command that dispatches to the lister's write character handler.", 78, "w:\\4ed\\code\\4coder_lists.cpp", 28, 31 }, -{ PROC_LINKS(lister__write_character__default, 0), "lister__write_character__default", 32, "A lister mode command that inserts a new character to the text field.", 69, "w:\\4ed\\code\\4coder_lists.cpp", 28, 126 }, -{ PROC_LINKS(lister__write_character__file_path, 0), "lister__write_character__file_path", 34, "A lister mode command that inserts a character into the text field of a file system list.", 89, "w:\\4ed\\code\\4coder_lists.cpp", 28, 193 }, -{ PROC_LINKS(lister__write_character__fixed_list, 0), "lister__write_character__fixed_list", 35, "A lister mode command that handles input for the fixed sure to kill list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 253 }, +{ PROC_LINKS(lister__write_character__default, 0), "lister__write_character__default", 32, "A lister mode command that inserts a new character to the text field.", 69, "w:\\4ed\\code\\4coder_lists.cpp", 28, 125 }, +{ PROC_LINKS(lister__write_character__file_path, 0), "lister__write_character__file_path", 34, "A lister mode command that inserts a character into the text field of a file system list.", 89, "w:\\4ed\\code\\4coder_lists.cpp", 28, 192 }, +{ PROC_LINKS(lister__write_character__fixed_list, 0), "lister__write_character__fixed_list", 35, "A lister mode command that handles input for the fixed sure to kill list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 252 }, { PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1083 }, { PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1271 }, { PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "w:\\4ed\\code\\4coder_miblo_numbers.cpp", 36, 110 }, @@ -389,8 +389,8 @@ static Command_Metadata fcoder_metacmd_table[233] = { { 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", 46, 71 }, { 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", 46, 63 }, { PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1526 }, -{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 181 }, -{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 172 }, +{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 178 }, +{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 169 }, { PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 347 }, { PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 338 }, { PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 46 }, @@ -406,7 +406,7 @@ static Command_Metadata fcoder_metacmd_table[233] = { { PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1087 }, { PROC_LINKS(redo, 0), "redo", 4, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1706 }, { PROC_LINKS(redo_this_buffer, 0), "redo_this_buffer", 16, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1620 }, -{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 300 }, +{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 297 }, { PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1227 }, { PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 383 }, { PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1598 }, @@ -446,8 +446,8 @@ static Command_Metadata fcoder_metacmd_table[233] = { { PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 61 }, { PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 75 }, { PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 121 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 268 }, -{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 262 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 265 }, +{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 259 }, { PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1498 }, { PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1510 }, { PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1504 }, @@ -457,18 +457,18 @@ static Command_Metadata fcoder_metacmd_table[233] = { { PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1269 }, { PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1275 }, { PROC_LINKS(snippet_lister, 0), "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 248 }, -{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 244 }, +{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 241 }, { PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1550 }, { PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 410 }, { PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 390 }, { PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 540 }, { PROC_LINKS(toggle_fps_meter, 0), "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 558 }, -{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 292 }, -{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 280 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 274 }, +{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 289 }, +{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 277 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 271 }, { PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 549 }, -{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 256 }, -{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 286 }, +{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 253 }, +{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 283 }, { PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 638 }, { PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 627 }, { PROC_LINKS(uncomment_line, 0), "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 147 }, diff --git a/4coder_helper.cpp b/4coder_helper.cpp index e9e54b9c..c0605930 100644 --- a/4coder_helper.cpp +++ b/4coder_helper.cpp @@ -1671,5 +1671,13 @@ draw_string(Application_Links *app, Face_ID font_id, String string, Vec2 p, int_ return(draw_string(app, font_id, string, p, color, 0, V2(1.f, 0.f))); } +static void +draw_margin(Application_Links *app, f32_Rect outer, f32_Rect inner, int_color color){ + draw_rectangle(app, f32R(outer.x0, outer.y0, outer.x1, inner.y0), color); + draw_rectangle(app, f32R(outer.x0, inner.y1, outer.x1, outer.y1), color); + draw_rectangle(app, f32R(outer.x0, inner.y0, inner.x0, inner.y1), color); + draw_rectangle(app, f32R(inner.x1, inner.y0, outer.x1, inner.y1), color); +} + // BOTTOM diff --git a/4coder_lists.cpp b/4coder_lists.cpp index 3544cdb6..6d9fb247 100644 --- a/4coder_lists.cpp +++ b/4coder_lists.cpp @@ -90,7 +90,7 @@ CUSTOM_DOC("A lister mode command that beings a click interaction with a list it View_Summary view = get_active_view(app, AccessAll); Lister_State *state = view_get_lister_state(&view); if (state->initialized){ - UI_Item clicked = lister_get_clicked_item(app, &view, scratch); + UI_Item clicked = lister_get_clicked_item(app, view.view_id, scratch); state->hot_user_data = clicked.user_data; } } @@ -103,10 +103,9 @@ CUSTOM_DOC("A lister mode command that ends a click interaction with a list item View_Summary view = get_active_view(app, AccessAll); Lister_State *state = view_get_lister_state(&view); if (state->initialized && state->hot_user_data != 0){ - UI_Item clicked = lister_get_clicked_item(app, &view, scratch); + UI_Item clicked = lister_get_clicked_item(app, view.view_id, scratch); if (state->hot_user_data == clicked.user_data){ - lister_call_activate_handler(app, scratch, heap, &view, - state, clicked.user_data, true); + lister_call_activate_handler(app, scratch, heap, &view, state, clicked.user_data, true); } } state->hot_user_data = 0; diff --git a/4coder_ui_helper.cpp b/4coder_ui_helper.cpp index 01e2953e..1890e3ee 100644 --- a/4coder_ui_helper.cpp +++ b/4coder_ui_helper.cpp @@ -6,13 +6,85 @@ // TODO(allen): documentation comment here +//////////////////////////////// + +typedef u32 View_Get_UI_Flags; +enum{ + ViewGetUIFlag_KeepDataAsIs = 0, + ViewGetUIFlag_ClearData = 1, +}; + +static b32 +view_get_ui_data(Application_Links *app, View_ID view_id, View_Get_UI_Flags flags, UI_Data **ui_data_out, Arena **ui_arena_out){ + b32 result = false; + Managed_Scope scope = 0; + if (view_get_managed_scope(app, view_id, &scope)){ + Managed_Object ui_data_object = 0; + if (managed_variable_get(app, scope, view_ui_data, &ui_data_object)){ + if (ui_data_object == 0){ + Managed_Object new_ui_data_object = alloc_managed_memory_in_scope(app, scope, sizeof(UI_Storage), 1); + Managed_Object arena_object = alloc_managed_arena_in_scope(app, scope, (8 << 10)); + Arena *arena = 0; + if (managed_object_load_data(app, arena_object, 0, 1, &arena)){ + UI_Data *ui_data = push_array(arena, UI_Data, 1); + UI_Storage storage = {}; + storage.data = ui_data; + storage.arena = arena; + storage.arena_object = arena_object; + storage.temp = begin_temp_memory(arena); + if (managed_object_store_data(app, new_ui_data_object, 0, 1, &storage)){ + if (managed_variable_set(app, scope, view_ui_data, new_ui_data_object)){ + ui_data_object = new_ui_data_object; + } + } + } + } + if (ui_data_object != 0){ + UI_Storage storage = {}; + if (managed_object_load_data(app, ui_data_object, 0, 1, &storage)){ + *ui_data_out = storage.data; + *ui_arena_out = storage.arena; + if ((flags & ViewGetUIFlag_ClearData) != 0){ + end_temp_memory(storage.temp); + } + result = true; + } + } + } + } + return(result); +} + +static b32 +view_clear_ui_data(Application_Links *app, View_ID view_id){ + b32 result = false; + Managed_Scope scope = 0; + if (view_get_managed_scope(app, view_id, &scope)){ + Managed_Object ui_data_object = 0; + if (managed_variable_get(app, scope, view_ui_data, &ui_data_object)){ + if (ui_data_object != 0){ + UI_Storage storage = {}; + if (managed_object_load_data(app, ui_data_object, 0, 1, &storage)){ + managed_object_free(app, storage.arena_object); + managed_object_free(app, ui_data_object); + managed_variable_set(app, scope, view_ui_data, 0); + result = true; + } + } + } + } + return(result); +} + +//////////////////////////////// + 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); +ui_list_add_item(Arena *arena, UI_List *list, UI_Item item){ + UI_Item *node = push_array(arena, UI_Item, 1); + memcpy(node, &item, sizeof(item)); zdll_push_back(list->first, list->last, node); list->count += 1; - node->fixed = item; - return(&node->fixed); + return(node); } static i32_Rect @@ -34,48 +106,44 @@ ui__rect_union(i32_Rect a, i32_Rect b){ return(a); } -static UI_Control -ui_list_to_ui_control(Partition *arena, UI_List *list){ - UI_Control control = {}; - control.items = push_array(arena, UI_Item, list->count); +static void +ui_data_compute_bounding_boxes(UI_Data *ui_data){ i32_Rect neg_inf_rect = {}; neg_inf_rect.x0 = INT32_MAX; neg_inf_rect.y0 = INT32_MAX; neg_inf_rect.x1 = INT32_MIN; neg_inf_rect.y1 = INT32_MIN; for (uint32_t i = 0; i < UICoordinates_COUNT; ++i){ - control.bounding_box[i] = neg_inf_rect; + ui_data->bounding_box[i] = neg_inf_rect; } - for (UI_Item_Node *node = list->first; - node != 0; - node = node->next){ - UI_Item *item = &control.items[control.count++]; - *item = node->fixed; + for (UI_Item *item = ui_data->list.first; + item != 0; + item = item->next){ if (item->coordinates >= UICoordinates_COUNT){ item->coordinates = UICoordinates_ViewSpace; } - control.bounding_box[item->coordinates] = ui__rect_union(control.bounding_box[item->coordinates], item->rectangle); + Rect_i32 *box = &ui_data->bounding_box[item->coordinates]; + *box = ui__rect_union(*box, item->rect_outer); } - return(control); } static void -ui_control_set_top(UI_Control *control, int32_t top_y){ - control->bounding_box[UICoordinates_ViewSpace].y0 = top_y; +ui_control_set_top(UI_Data *data, int32_t top_y){ + data->bounding_box[UICoordinates_ViewSpace].y0 = top_y; } static void -ui_control_set_bottom(UI_Control *control, int32_t bottom_y){ - control->bounding_box[UICoordinates_ViewSpace].y1 = bottom_y; +ui_control_set_bottom(UI_Data *data, int32_t bottom_y){ + data->bounding_box[UICoordinates_ViewSpace].y1 = bottom_y; } static UI_Item* -ui_control_get_mouse_hit(UI_Control *control, Vec2_i32 view_p, Vec2_i32 panel_p){ +ui_control_get_mouse_hit(UI_Data *data, Vec2_i32 view_p, Vec2_i32 panel_p){ UI_Item *result = 0; - int32_t count = control->count; - UI_Item *item = control->items + count - 1; - for (int32_t i = 0; i < count && result == 0; ++i, item -= 1){ - i32_Rect r = item->rectangle; + for (UI_Item *item = data->list.first; + item != 0 && result == 0; + item = item->next){ + i32_Rect r = item->rect_outer; switch (item->coordinates){ case UICoordinates_ViewSpace: { @@ -95,12 +163,8 @@ ui_control_get_mouse_hit(UI_Control *control, Vec2_i32 view_p, Vec2_i32 panel_p) } static UI_Item* -ui_control_get_mouse_hit(UI_Control *control, - int32_t mx_scrolled, int32_t my_scrolled, - int32_t mx_unscrolled, int32_t my_unscrolled){ - return(ui_control_get_mouse_hit(control, - V2i32(mx_scrolled, my_scrolled), - V2i32(mx_unscrolled, my_unscrolled))); +ui_control_get_mouse_hit(UI_Data *data, int32_t mx_scrolled, int32_t my_scrolled, int32_t mx_unscrolled, int32_t my_unscrolled){ + return(ui_control_get_mouse_hit(data, V2i32(mx_scrolled, my_scrolled), V2i32(mx_unscrolled, my_unscrolled))); } //////////////////////////////// @@ -221,20 +285,26 @@ init_lister_state(Application_Links *app, Lister_State *state, Heap *heap){ UI_QUIT_FUNCTION(lister_quit_function){ Lister_State *state = view_get_lister_state(&view); state->initialized = false; + view_clear_ui_data(app, view.view_id); } static UI_Item -lister_get_clicked_item(Application_Links *app, View_Summary *view, Partition *scratch){ - Temp_Memory temp = begin_temp_memory(scratch); - UI_Control control = view_get_ui_copy(app, view, scratch); - Mouse_State mouse = get_mouse_state(app); - Vec2_i32 region_p0 = view->file_region.p0; - Vec2_i32 m_view_space = get_mouse_position_in_view_space(mouse, region_p0, V2i32(view->scroll_vars.scroll_p)); - Vec2_i32 m_panel_space = get_mouse_position_in_panel_space(mouse, region_p0); - UI_Item *clicked = ui_control_get_mouse_hit(&control, m_view_space, m_panel_space); +lister_get_clicked_item(Application_Links *app, View_ID view_id, Partition *scratch){ UI_Item result = {}; - if (clicked != 0){ - result = *clicked; + Temp_Memory temp = begin_temp_memory(scratch); + UI_Data *ui_data = 0; + Arena *ui_arena = 0; + if (view_get_ui_data(app, view_id, ViewGetUIFlag_KeepDataAsIs, &ui_data, &ui_arena)){ + View_Summary view = {}; + get_view_summary(app, view_id, AccessAll, &view); + Mouse_State mouse = get_mouse_state(app); + Vec2_i32 region_p0 = view.file_region.p0; + Vec2_i32 m_view_space = get_mouse_position_in_view_space(mouse, region_p0, V2i32(view.scroll_vars.scroll_p)); + Vec2_i32 m_panel_space = get_mouse_position_in_panel_space(mouse, region_p0); + UI_Item *clicked = ui_control_get_mouse_hit(ui_data, m_view_space, m_panel_space); + if (clicked != 0){ + result = *clicked; + } } end_temp_memory(temp); return(result); @@ -263,8 +333,7 @@ lister_get_block_height(int32_t line_height, bool32 is_theme_list){ } static void -lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view, - Lister_State *state){ +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; @@ -322,99 +391,135 @@ lister_update_ui(Application_Links *app, Partition *scratch, View_Summary *view, substring_matches, }; - UI_List list = {}; - UI_Item *highlighted_item = 0; - UI_Item *hot_item = 0; - UI_Item *hovered_item = 0; - int32_t item_index_counter = 0; - for (int32_t array_index = 0; array_index < ArrayCount(node_ptr_arrays); array_index += 1){ - Lister_Node_Ptr_Array node_ptr_array = node_ptr_arrays[array_index]; - for (int32_t node_index = 0; node_index < node_ptr_array.count; node_index += 1){ - Lister_Node *node = node_ptr_array.node_ptrs[node_index]; - + UI_Data *ui_data = 0; + Arena *ui_arena = 0; + if (view_get_ui_data(app, view->view_id, ViewGetUIFlag_ClearData, &ui_data, &ui_arena)){ + memset(ui_data, 0, sizeof(*ui_data)); + + UI_Item *highlighted_item = 0; + UI_Item *hot_item = 0; + UI_Item *hovered_item = 0; + int32_t item_index_counter = 0; + for (int32_t array_index = 0; array_index < ArrayCount(node_ptr_arrays); array_index += 1){ + Lister_Node_Ptr_Array node_ptr_array = node_ptr_arrays[array_index]; + for (int32_t node_index = 0; node_index < node_ptr_array.count; node_index += 1){ + Lister_Node *node = node_ptr_array.node_ptrs[node_index]; + + i32_Rect item_rect = {}; + item_rect.x0 = x0; + item_rect.y0 = y_pos; + item_rect.x1 = x1; + item_rect.y1 = y_pos + block_height; + y_pos = item_rect.y1; + + UI_Item item = {}; + item.activation_level = UIActivation_None; + item.coordinates = UICoordinates_ViewSpace; + item.rect_outer = item_rect; + item.inner_margin = 3; + + if (!is_theme_list){ + Fancy_String_List list = {}; + push_fancy_string (ui_arena, &list, fancy_id(Stag_Default), node->string); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Default), " "); + push_fancy_string (ui_arena, &list, fancy_id(Stag_Pop2 ), node->status); + item.lines[0] = list; + item.line_count = 1; + } + else{ + //i32 style_index = node->index; + + String name = make_lit_string("name"); + item.lines[0] = fancy_string_list_single(push_fancy_string(ui_arena, fancy_id(Stag_Default), name)); + + Fancy_String_List list = {}; + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Keyword ), "if "); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Default ), "(x < "); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Int_Constant), "0"); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Default ), ") { x = "); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Int_Constant), "0"); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Default ), "; } "); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Comment ), "// comment"); + item.lines[1] = list; + + item.line_count = 2; + } + + item.user_data = node->user_data; + + + UI_Item *item_ptr = ui_list_add_item(ui_arena, &ui_data->list, item); + if (hit_check(item_rect, view_m)){ + hovered_item = item_ptr; + } + if (state->item_index == item_index_counter){ + highlighted_item = item_ptr; + state->raw_item_index = node->raw_index; + } + item_index_counter += 1; + if (node->user_data == state->hot_user_data && hot_item != 0){ + hot_item = item_ptr; + } + } + } + state->item_count_after_filter = item_index_counter; + + if (hovered_item != 0){ + hovered_item->activation_level = UIActivation_Hover; + } + if (hot_item != 0){ + if (hot_item == hovered_item){ + hot_item->activation_level = UIActivation_Active; + } + else{ + hot_item->activation_level = UIActivation_Hover; + } + } + if (highlighted_item != 0){ + highlighted_item->activation_level = UIActivation_Active; + } + + if (state->set_view_vertical_focus_to_item){ + if (highlighted_item != 0){ + view_set_vertical_focus(app, view, highlighted_item->rect_outer.y0, highlighted_item->rect_outer.y1); + } + state->set_view_vertical_focus_to_item = false; + } + + { i32_Rect item_rect = {}; item_rect.x0 = x0; - item_rect.y0 = y_pos; + item_rect.y0 = 0; item_rect.x1 = x1; - item_rect.y1 = y_pos + block_height; + item_rect.y1 = item_rect.y0 + text_field_height; y_pos = item_rect.y1; UI_Item item = {}; - if (!is_theme_list){ - item.type = UIType_Option; - item.option.string = node->string; - item.option.status = node->status; + item.activation_level = UIActivation_Active; + item.coordinates = UICoordinates_PanelSpace; + item.rect_outer = item_rect; + item.inner_margin = 0; + { + Fancy_String_List list = {}; + push_fancy_string (ui_arena, &list, fancy_id(Stag_Pop1 ), state->lister.data.query); + push_fancy_stringf(ui_arena, &list, fancy_id(Stag_Pop1 ), " "); + push_fancy_string (ui_arena, &list, fancy_id(Stag_Default), state->lister.data.text_field); + item.lines[0] = list; + item.line_count = 1; } - else{ - item.type = UIType_ColorTheme; - item.color_theme.string = node->string; - item.color_theme.index = node->index; - } - item.activation_level = UIActivation_None; - item.coordinates = UICoordinates_ViewSpace; - item.user_data = node->user_data; - item.rectangle = item_rect; + item.user_data = 0; - UI_Item *item_ptr = ui_list_add_item(scratch, &list, item); - if (hit_check(item_rect, view_m)){ - hovered_item = item_ptr; - } - if (state->item_index == item_index_counter){ - highlighted_item = item_ptr; - state->raw_item_index = node->raw_index; - } - item_index_counter += 1; - if (node->user_data == state->hot_user_data && hot_item != 0){ - hot_item = item_ptr; - } + + ui_list_add_item(ui_arena, &ui_data->list, item); } - } - state->item_count_after_filter = item_index_counter; - - if (hovered_item != 0){ - hovered_item->activation_level = UIActivation_Hover; - } - if (hot_item != 0){ - if (hot_item == hovered_item){ - hot_item->activation_level = UIActivation_Active; - } - else{ - hot_item->activation_level = UIActivation_Hover; - } - } - if (highlighted_item != 0){ - highlighted_item->activation_level = UIActivation_Active; - } - - 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); - } - state->set_view_vertical_focus_to_item = false; - } - - { - i32_Rect item_rect = {}; - item_rect.x0 = x0; - item_rect.y0 = 0; - item_rect.x1 = x1; - 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_PanelSpace; - 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); + ui_data_compute_bounding_boxes(ui_data); + + // TODO(allen): what to do with control now? + //UI_Control control = ui_list_to_ui_control(scratch, &list); + view_set_quit_ui_handler(app, view->view_id, lister_quit_function); } - UI_Control control = ui_list_to_ui_control(scratch, &list); - view_set_ui(app, view, &control, lister_quit_function); - end_temp_memory(full_temp); } @@ -508,18 +613,19 @@ lister_add_theme_item(Lister *lister, String string, int32_t index, static void* lister_get_user_data(Lister_Data *lister_data, int32_t index){ + void *result = 0; if (0 <= index && index < lister_data->options.count){ int32_t counter = 0; for (Lister_Node *node = lister_data->options.first; node != 0; - node = node->next){ + node = node->next, counter += 1){ if (counter == index){ - return(node->user_data); + result = node->user_data; + break; } - counter += 1; } } - return(0); + return(result); } static void diff --git a/4coder_ui_helper.h b/4coder_ui_helper.h index d92b1036..32f150dd 100644 --- a/4coder_ui_helper.h +++ b/4coder_ui_helper.h @@ -7,6 +7,52 @@ #if !defined(FCODER_UI_HELPER_H) #define FCODER_UI_HELPER_H +typedef i8 UI_Item_Type; +enum UI_Activation_Level{ + UIActivation_None = 0, + UIActivation_Hover = 1, + UIActivation_Active = 2, +}; + +typedef u8 UI_Coordinate_System; +enum{ + UICoordinates_ViewSpace = 0, + UICoordinates_PanelSpace = 1, + UICoordinates_COUNT = 2, +}; + +struct UI_Item{ + UI_Item *next; + UI_Item *prev; + UI_Activation_Level activation_level; + UI_Coordinate_System coordinates; + Rect_i32 rect_outer; + i32 inner_margin; + Fancy_String_List lines[4]; + i32 line_count; + void *user_data; +}; + +struct UI_List{ + UI_Item *first; + UI_Item *last; + int32_t count; +}; + +struct UI_Data{ + UI_List list; + Rect_i32 bounding_box[UICoordinates_COUNT]; +}; + +struct UI_Storage{ + UI_Data *data; + Arena *arena; + Managed_Object arena_object; + Temp_Memory_Arena temp; +}; + +//////////////////////////////// + typedef int32_t Lister_Activation_Code; enum{ ListerActivation_Finished = 0, diff --git a/4ed.cpp b/4ed.cpp index b073ba3a..1fda8023 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1309,34 +1309,26 @@ App_Step_Sig(app_step){ View *view = panel->view; GUI_Scroll_Vars *scroll_vars = 0; - i32 max_y = 0; b32 file_scroll = false; File_Edit_Positions edit_pos = view_get_edit_pos(view); if (!view->ui_mode){ scroll_vars = &edit_pos.scroll; - max_y = view_compute_max_target_y(view); file_scroll = true; } else{ scroll_vars = &view->ui_scroll; - i32 bottom = view->ui_control.bounding_box[UICoordinates_ViewSpace].y1; - max_y = view_compute_max_target_y_from_bottom_y(view, (f32)bottom); file_scroll = false; } b32 active = (panel == active_panel); - Input_Process_Result ip_result = do_step_file_view(system, models, view, panel->rect_inner, active, dt, *scroll_vars, max_y); + GUI_Scroll_Vars new_scroll = do_step_file_view(system, models, view, panel->rect_inner, active, dt, *scroll_vars); - if (ip_result.is_animating){ - app_result.animating = true; - } - - if (memcmp(scroll_vars, &ip_result.scroll, sizeof(*scroll_vars)) != 0){ + if (memcmp(scroll_vars, &new_scroll, sizeof(*scroll_vars)) != 0){ if (file_scroll){ - view_set_scroll(system, view, ip_result.scroll); + view_set_scroll(system, view, new_scroll); } else{ - *scroll_vars = ip_result.scroll; + *scroll_vars = new_scroll; } } } diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 8ed21c5c..95b9efef 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -2260,18 +2260,14 @@ DOC_SEE(view_set_ui) { Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); + b32 result = false; if (view_api_check_view(view)){ - if (view->ui_mode){ - return(false); - } - else{ + if (!view->ui_mode){ view->ui_mode = true; - return(true); + result = true; } } - else{ - return(false); - } + return(result); } // TODO(allen): redocument @@ -2298,7 +2294,19 @@ DOC_SEE(view_set_ui) } API_EXPORT bool32 -View_Set_UI(Application_Links *app, View_ID view_id, UI_Control *control, UI_Quit_Function_Type *quit_function) +View_Is_In_UI_Mode(Application_Links *app, View_ID view_id){ + Models *models = (Models*)app->cmd_context; + View *view = imp_get_view(models, view_id); + bool32 result = false; + if (view_api_check_view(view)){ + result = view->ui_mode; + } + return(result); +} + +// TODO(allen): redocument +API_EXPORT bool32 +View_Set_Quit_UI_Handler(Application_Links *app, View_ID view_id, UI_Quit_Function_Type *quit_function) /* DOC_PARAM(view, A summary for the view which is to get the new UI widget data.) DOC_PARAM(control, A pointer to the baked UI widget data. To get data in the UI_Control format see the helper called ui_list_to_ui_control. More information about specifying widget data can be found in a comment in '4coder_ui_helper.cpp'. If this pointer is null the view's widget data is cleared to zero. The core maintains it's own copy of the widget data, so after this call the memory used to specify widget data may be freed.) @@ -2312,102 +2320,18 @@ DOC_SEE(UI_Quit_Function_Type) */ { Models *models = (Models*)app->cmd_context; - Heap *heap = &models->mem.heap; View *view = imp_get_view(models, view_id); - + b32 result = false; if (view_api_check_view(view)){ - if (view->ui_control.items != 0){ - heap_free(heap, view->ui_control.items); - } - memset(&view->ui_control, 0, sizeof(view->ui_control)); view->ui_quit = quit_function; - if (control != 0){ - if (control->count > 0){ - i32 string_size = 0; - for (UI_Item *item = control->items, *one_past_last = control->items + control->count; - item < one_past_last; - item += 1){ - switch (item->type){ - case UIType_Option: - { - string_size += item->option.string.size; - string_size += item->option.status.size; - }break; - - case UIType_TextField: - { - string_size += item->text_field.query.size; - string_size += item->text_field.string.size; - }break; - - case UIType_ColorTheme: - { - string_size += item->color_theme.string.size; - }break; - } - } - - i32 all_items_size = sizeof(UI_Item)*control->count; - i32 memory_size = all_items_size + string_size; - UI_Item *new_items = (UI_Item*)heap_allocate(heap, memory_size); - if (new_items != 0){ - char *string_space = (char*)(new_items + control->count); - Partition string_alloc = make_part(string_space, string_size); - i32 count = control->count; - memcpy(new_items, control->items, all_items_size); - for (UI_Item *item = new_items, *one_past_last = new_items + count; - item < one_past_last; - item += 1){ - - String *fixup[2]; - - int32_t fixup_count = 0; - switch (item->type){ - case UIType_Option: - { - fixup[0] = &item->option.string; - fixup[1] = &item->option.status; - fixup_count = 2; - }break; - case UIType_TextField: - { - fixup[0] = &item->text_field.query; - fixup[1] = &item->text_field.string; - fixup_count = 2; - }break; - case UIType_ColorTheme: - { - fixup[0] = &item->color_theme.string; - fixup_count = 1; - }break; - } - - for (i32 i = 0; i < fixup_count; i += 1){ - String old = *fixup[i]; - char *new_str = push_array(&string_alloc, char, old.size); - fixup[i]->str = new_str; - fixup[i]->size = old.size; - fixup[i]->memory_size = old.size; - memcpy(new_str, old.str, old.size); - } - } - view->ui_control.items = new_items; - view->ui_control.count = count; - } - else{ - return(false); - } - } - memcpy(view->ui_control.bounding_box, control->bounding_box, sizeof(control->bounding_box)); - } - return(true); + result = true; } - return(false); + return(result); } // TODO(allen): redocument API_EXPORT bool32 -View_Get_UI_Copy(Application_Links *app, View_ID view_id, struct Partition *part, UI_Control *ui_control_out) +View_Get_Quit_UI_Handler(Application_Links *app, View_ID view_id, UI_Quit_Function_Type **quit_function_out) /* DOC_PARAM(view, A summary for the view which is to get the new UI widget data.) DOC_PARAM(part, A memory arena onto which the UI widget data will be allocated.) @@ -2417,22 +2341,12 @@ DOC_SEE(view_set_ui) { Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); - if (part != 0 && view_api_check_view(view)){ - UI_Control *control = &view->ui_control; - ui_control_out->items = push_array(part, UI_Item, control->count); - if (ui_control_out->items != 0){ - ui_control_out->count = control->count; - // TODO(allen): do(fixup the pointers) - block_copy(ui_control_out->items, control->items, sizeof(*ui_control_out->items)*ui_control_out->count); - } - else{ - block_zero_struct(ui_control_out); - return(false); - } - block_copy(ui_control_out->bounding_box, control->bounding_box, sizeof(ui_control_out->bounding_box)); - return(true); + b32 result = false; + if (view_api_check_view(view)){ + *quit_function_out = view->ui_quit; + result = true; } - return(false); + return(result); } internal Dynamic_Workspace* @@ -2729,7 +2643,7 @@ DOC_RETURN(Returns non-zero on success. This call fails if scope does not refer } API_EXPORT Managed_Object -Alloc_Managed_Memory_In_Scope(Application_Links *app, Managed_Scope scope, int32_t item_size, int32_t count) +Alloc_Managed_Memory_In_Scope(Application_Links *app, Managed_Scope scope, i32 item_size, i32 count) /* DOC_PARAM(scope, A handle to the scope in which the new object will be allocated.) DOC_PARAM(item_size, The size, in bytes, of a single 'item' in this memory object. This effects the size of the allocation, and the indexing of the memory in the store and load calls.) @@ -2799,6 +2713,26 @@ DOC_SEE(Marker) return(result); } +API_EXPORT Managed_Object +Alloc_Managed_Arena_In_Scope(Application_Links *app, Managed_Scope scope, i32 page_size){ + Models *models = (Models*)app->cmd_context; + Heap *heap = &models->mem.heap; + Dynamic_Workspace *workspace = get_dynamic_workspace(models, scope); + Managed_Object result = 0; + if (workspace != 0){ + void *ptr = memory_bank_allocate(heap, &workspace->mem_bank, sizeof(Managed_Arena_Header) + sizeof(Arena*)); + Managed_Arena_Header *header = (Managed_Arena_Header*)ptr; + header->std_header.type = ManagedObjectType_Arena; + header->std_header.item_size = sizeof(Arena*); + header->std_header.count = 1; + zdll_push_back(workspace->arena_list.first, workspace->arena_list.last, header); + header->arena = make_arena(app, page_size); + u32 id = dynamic_workspace_store_pointer(heap, workspace, ptr); + result = ((u64)scope << 32) | (u64)id; + } + return(result); +} + internal Managed_Object_Ptr_And_Workspace get_dynamic_object_ptrs(Models *models, Managed_Object object){ Managed_Object_Ptr_And_Workspace result = {}; @@ -3025,12 +2959,24 @@ DOC_RETURN(Pushes an array onto part containing the handle to every marker visua internal u8* get_dynamic_object_memory_ptr(Managed_Object_Standard_Header *header){ + u8 *ptr = 0; if (header != 0){ - if (0 < header->type && header->type < ManagedObjectType_COUNT){ - return(((u8*)header) + managed_header_type_sizes[header->type]); + switch (header->type){ + case ManagedObjectType_Memory: + case ManagedObjectType_Markers: + { + ptr = ((u8*)header) + managed_header_type_sizes[header->type]; + }break; + + case ManagedObjectType_Arena: + { + ptr = ((u8*)header) + managed_header_type_sizes[header->type]; + Managed_Arena_Header *arena_header = (Managed_Arena_Header*)header; + *(Arena**)ptr = &arena_header->arena; + }break; } } - return(0); + return(ptr); } API_EXPORT uint32_t @@ -3110,26 +3056,37 @@ DOC(Permanently frees the specified object. Not only does this free up the memo Models *models = (Models*)app->cmd_context; u32 hi_id = (object >> 32)&max_u32; Dynamic_Workspace *workspace = get_dynamic_workspace(models, hi_id); + b32 result = false; if (workspace != 0){ u32 lo_id = object&max_u32; u8 *object_ptr = (u8*)dynamic_workspace_get_pointer(workspace, lo_id); if (object_ptr != 0){ Managed_Object_Type *type = (Managed_Object_Type*)object_ptr; - if (*type == ManagedObjectType_Markers){ - Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)object_ptr; - workspace->total_marker_count -= header->std_header.count; - if (header->visual_count > 0){ - marker_visual_free_chain(&workspace->visual_allocator, header->visual_first, header->visual_last, header->visual_count); - } - zdll_remove(workspace->buffer_markers_list.first, workspace->buffer_markers_list.last, header); - workspace->buffer_markers_list.count -= 1; + switch (*type){ + case ManagedObjectType_Markers: + { + Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)object_ptr; + workspace->total_marker_count -= header->std_header.count; + if (header->visual_count > 0){ + marker_visual_free_chain(&workspace->visual_allocator, header->visual_first, header->visual_last, header->visual_count); + } + zdll_remove(workspace->buffer_markers_list.first, workspace->buffer_markers_list.last, header); + workspace->buffer_markers_list.count -= 1; + }break; + + case ManagedObjectType_Arena: + { + Managed_Arena_Header *header = (Managed_Arena_Header*)object_ptr; + arena_release_all(&header->arena); + zdll_remove(workspace->arena_list.first, workspace->arena_list.last, header); + }break; } dynamic_workspace_erase_pointer(workspace, lo_id); memory_bank_free(&workspace->mem_bank, object_ptr); - return(true); + result = true; } } - return(false); + return(result); } API_EXPORT bool32 @@ -3148,16 +3105,17 @@ DOC_SEE(managed_object_get_item_count) Models *models = (Models*)app->cmd_context; Managed_Object_Ptr_And_Workspace object_ptrs = get_dynamic_object_ptrs(models, object); u8 *ptr = get_dynamic_object_memory_ptr(object_ptrs.header); + b32 result = false; if (ptr != 0){ u32 item_count = object_ptrs.header->count; if (0 <= first_index && first_index + count <= item_count){ u32 item_size = object_ptrs.header->item_size; memcpy(ptr + first_index*item_size, mem, count*item_size); heap_assert_good(&object_ptrs.workspace->mem_bank.heap); - return(true); + result = true; } } - return(false); + return(result); } API_EXPORT bool32 @@ -3176,16 +3134,17 @@ DOC_SEE(managed_object_get_item_count) Models *models = (Models*)app->cmd_context; Managed_Object_Ptr_And_Workspace object_ptrs = get_dynamic_object_ptrs(models, object); u8 *ptr = get_dynamic_object_memory_ptr(object_ptrs.header); + b32 result = false; if (ptr != 0){ u32 item_count = object_ptrs.header->count; if (0 <= first_index && first_index + count <= item_count){ u32 item_size = object_ptrs.header->item_size; memcpy(mem_out, ptr + first_index*item_size, count*item_size); heap_assert_good(&object_ptrs.workspace->mem_bank.heap); - return(true); + result = true; } } - return(false); + return(result); } API_EXPORT User_Input diff --git a/4ed_dynamic_variables.h b/4ed_dynamic_variables.h index 7f85d732..cfb7d09a 100644 --- a/4ed_dynamic_variables.h +++ b/4ed_dynamic_variables.h @@ -63,10 +63,18 @@ struct Marker_Visual_Allocator{ u32_Ptr_Table id_to_ptr_table; }; +struct Managed_Arena_Header{ + Managed_Object_Standard_Header std_header; + Managed_Arena_Header *next; + Managed_Arena_Header *prev; + Arena arena; +}; + global_const i32 managed_header_type_sizes[ManagedObjectType_COUNT] = { 0, sizeof(Managed_Memory_Header), sizeof(Managed_Buffer_Markers_Header), + sizeof(Managed_Arena_Header), }; struct Managed_Buffer_Markers_Header_List{ @@ -75,6 +83,12 @@ struct Managed_Buffer_Markers_Header_List{ i32 count; }; +struct Managed_Arena_Header_List{ + Managed_Arena_Header *first; + Managed_Arena_Header *last; + i32 count; +}; + //////////////////////////////// struct Dynamic_Variable_Slot{ @@ -109,6 +123,7 @@ struct Dynamic_Workspace{ i32 user_type; void *user_back_ptr; Managed_Buffer_Markers_Header_List buffer_markers_list; + Managed_Arena_Header_List arena_list; i32 total_marker_count; }; diff --git a/4ed_file.cpp b/4ed_file.cpp index 38127188..dbc216d4 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -25,7 +25,8 @@ file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i32 pos){ } internal void -file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){ +file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll, i32 max_y){ + scroll.target_y = clamp(0, scroll.target_y, max_y); edit_pos->scroll = scroll; edit_pos->last_set_type = EditPos_ScrollSet; } diff --git a/4ed_view.cpp b/4ed_view.cpp index 4ffd466b..9c727c24 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -64,10 +64,6 @@ live_set_free_view(Heap *heap, Lifetime_Allocator *lifetime_allocator, Live_View Assert(live_set->count > 0); --live_set->count; - if (view->ui_control.items != 0){ - heap_free(heap, view->ui_control.items); - } - view->next = live_set->free_sentinel.next; view->prev = &live_set->free_sentinel; live_set->free_sentinel.next = view; @@ -280,7 +276,7 @@ view_set_cursor(System_Functions *system, View *view, Full_Cursor cursor, b32 se internal void view_set_scroll(System_Functions *system, View *view, GUI_Scroll_Vars scroll){ File_Edit_Positions edit_pos = view_get_edit_pos(view); - file_edit_positions_set_scroll(&edit_pos, scroll); + file_edit_positions_set_scroll(&edit_pos, scroll, view_compute_max_target_y(view)); view_set_edit_pos(view, edit_pos); i32 pos = edit_pos.cursor_pos; if (view_move_cursor_to_view(system, view, edit_pos.scroll, &pos, view->preferred_x)){ @@ -297,7 +293,7 @@ view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, if (set_preferred_x){ view_set_preferred_x(view, cursor); } - file_edit_positions_set_scroll(&edit_pos, scroll); + file_edit_positions_set_scroll(&edit_pos, scroll, view_compute_max_target_y(view)); edit_pos.last_set_type = EditPos_None; view_set_edit_pos(view, edit_pos); } @@ -1181,6 +1177,9 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v } } +internal void +dont_do_core_render(Application_Links *app){} + internal void do_core_render(Application_Links *app){ Models *models = (Models*)app->cmd_context; @@ -1229,6 +1228,27 @@ view_get_render_cursor_target(System_Functions *system, View *view){ return(view_get_render_cursor(system, view, scroll_y)); } +internal void +view_call_render_caller(Models *models, Render_Target *target, View *view, + i32_Rect rect, Full_Cursor render_cursor, Range on_screen_range, Buffer_Render_Item *items, i32 item_count, + Render_Callback *core_render){ + if (models->render_caller != 0){ + View_ID view_id = view_get_id(&models->live_set, view); + models->render_view = view; + models->render_rect = rect; + models->render_cursor = render_cursor; + models->render_range = on_screen_range; + models->render_items = items; + models->render_item_count = item_count; + + i32 frame_index = target->frame_index; + f32 literal_dt = target->literal_dt; + f32 animation_dt = target->animation_dt; + models->render_caller(&models->app_links, view_id, on_screen_range, frame_index, literal_dt, animation_dt, core_render); + models->render_view = 0; + } +} + internal void render_loaded_file_in_view(System_Functions *system, View *view, Models *models, i32_Rect rect, b32 is_active, Render_Target *target){ Editing_File *file = view->file_data.file; @@ -1266,7 +1286,7 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models, Full_Cursor render_cursor = view_get_render_cursor(system, view); -#if 0 +#if 0 // TODO(allen): do(eliminate scroll_i nonsense) view->edit_pos_.scroll_i = render_cursor.pos; #endif @@ -1348,20 +1368,7 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models, //////////////////////////////// if (models->render_caller != 0){ - View_ID view_id = view_get_id(&models->live_set, view); - models->render_view = view; - models->render_rect = rect; - models->render_cursor = render_cursor; - models->render_range = on_screen_range; - models->render_items = items; - models->render_item_count = item_count; - - i32 frame_index = target->frame_index; - f32 literal_dt = target->literal_dt; - f32 animation_dt = target->animation_dt; - models->render_caller(&models->app_links, view_id, on_screen_range, - frame_index, literal_dt, animation_dt, do_core_render); - models->render_view = 0; + view_call_render_caller(models, target, view, rect, render_cursor, on_screen_range, items, item_count, do_core_render); } else{ render_loaded_file_in_view__inner(models, target, view, rect, render_cursor, on_screen_range, items, item_count); diff --git a/4ed_view.h b/4ed_view.h index 6781ef7b..5b7eeead 100644 --- a/4ed_view.h +++ b/4ed_view.h @@ -39,11 +39,11 @@ struct View{ i32 temp_view_top_left_target_pos; b32 ui_mode; - UI_Quit_Function_Type *ui_quit; - UI_Control ui_control; - GUI_Scroll_Vars ui_scroll; - Vec2_i32 prev_target; i32 ui_map_id; + GUI_Scroll_Vars ui_scroll; + UI_Quit_Function_Type *ui_quit; + + Vec2_i32 prev_target; b32 hide_scrollbar; b32 hide_file_bar; @@ -141,13 +141,6 @@ struct View_Step_Result{ b32 consume_esc; }; -struct Input_Process_Result{ - GUI_Scroll_Vars scroll; - b32 is_animating; - b32 consumed_l; - b32 consumed_r; -}; - enum{ FileCreateFlag_ReadOnly = 1, }; diff --git a/4ed_view_ui.cpp b/4ed_view_ui.cpp index 3d6de7f2..53afe64e 100644 --- a/4ed_view_ui.cpp +++ b/4ed_view_ui.cpp @@ -46,12 +46,8 @@ global_const Style_Color_Edit colors_to_edit[] = { {Stag_Pop2, Stag_Pop2, Stag_Bar, lit("Bar Pop 2")}, }; -internal Input_Process_Result -do_step_file_view(System_Functions *system, Models *models, View *view, i32_Rect rect, b32 is_active, f32 dt, GUI_Scroll_Vars scroll, i32 max_y){ - Input_Process_Result result = {}; - scroll.target_y = clamp(0, scroll.target_y, max_y); - result.scroll = scroll; - +internal GUI_Scroll_Vars +do_step_file_view(System_Functions *system, Models *models, View *view, i32_Rect rect, b32 is_active, f32 dt, GUI_Scroll_Vars scroll){ i32 line_height = view->line_height; if (!view->hide_file_bar){ @@ -75,25 +71,24 @@ do_step_file_view(System_Functions *system, Models *models, View *view, i32_Rect // TODO(allen): do(eliminate the built in paste_effect) if (!file->is_loading && file->state.paste_effect.seconds_down > 0.f){ file->state.paste_effect.seconds_down -= dt; - result.is_animating = true; + models->animate_next_frame = true; } // NOTE(allen): call scroll rule hook - b32 is_new_target = (result.scroll.target_x != view->prev_target.x || - result.scroll.target_y != view->prev_target.y); + b32 is_new_target = (scroll.target_x != view->prev_target.x || scroll.target_y != view->prev_target.y); - f32 target_x = (f32)result.scroll.target_x; - f32 target_y = (f32)result.scroll.target_y; + f32 target_x = (f32)scroll.target_x; + f32 target_y = (f32)scroll.target_y; View_ID view_id = view_get_id(&models->live_set, view); - if (models->scroll_rule(target_x, target_y, &result.scroll.scroll_x, &result.scroll.scroll_y, view_id, is_new_target, dt)){ - result.is_animating = true; + if (models->scroll_rule(target_x, target_y, &scroll.scroll_x, &scroll.scroll_y, view_id, is_new_target, dt)){ + models->animate_next_frame = true; } - view->prev_target.x = result.scroll.target_x; - view->prev_target.y = result.scroll.target_y; + view->prev_target.x = scroll.target_x; + view->prev_target.y = scroll.target_y; - return(result); + return(scroll); } //////////////////////////////// @@ -178,6 +173,7 @@ draw_file_bar(System_Functions *system, Render_Target *target, View *view, Model } } +#if 0 internal u32 get_margin_color(Color_Table color_table, i32 level){ u32 margin = 0; @@ -198,10 +194,10 @@ get_margin_color(Color_Table color_table, i32 level){ } return(margin); } +#endif internal void 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){ - Editing_File *file = view->file_data.file; Assert(file != 0); @@ -244,116 +240,124 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc view->widget_height = (f32)bar_count*(view->line_height + 2); draw_push_clip(target, rect); + if (!view->ui_mode){ if (file_is_ready(file)){ render_loaded_file_in_view(system, view, models, rect, is_active, target); } } else{ - f32_Rect rect_f32 = f32R(rect); - - i32 item_count = view->ui_control.count; - UI_Item *item = view->ui_control.items; - GUI_Scroll_Vars ui_scroll = view->ui_scroll; - for (i32 i = 0; i < item_count; ++i, item += 1){ - - f32_Rect item_rect = f32R(item->rectangle); - switch (item->coordinates){ - case UICoordinates_ViewSpace: - { - item_rect.x0 += rect_f32.x0 - ui_scroll.scroll_x; - item_rect.y0 += rect_f32.y0 - ui_scroll.scroll_y; - item_rect.x1 += rect_f32.x0 - ui_scroll.scroll_x; - item_rect.y1 += rect_f32.y0 - ui_scroll.scroll_y; - }break; - case UICoordinates_PanelSpace: - { - item_rect.x0 += rect_f32.x0; - item_rect.y0 += rect_f32.y0; - item_rect.x1 += rect_f32.x0; - item_rect.y1 += rect_f32.y0; - }break; - } - - if (rect_overlap(item_rect, rect_f32)){ - switch (item->type){ - case UIType_Option: - { - u32 back = color_table.vals[Stag_Back]; - u32 text_color = color_table.vals[Stag_Default]; - u32 pop_color = color_table.vals[Stag_Pop2]; - u32 margin_color = get_margin_color(color_table, item->activation_level); - f32_Rect inner = get_inner_rect(item_rect, 3); - draw_rectangle(target, inner, back); - Vec2 p = V2(inner.p0) + V2(3.f, line_height*0.5f - 1.f); - p.x += draw_string(system, target, font_id, item->option.string, p, text_color); - p.x += font_string_width(system, target, font_id, make_lit_string(" ")); - draw_string(system, target, font_id, item->option.status, p, pop_color); - draw_margin(target, item_rect, inner, margin_color); - }break; - - case UIType_TextField: - { - u32 back = color_table.vals[Stag_Back]; - u32 text1 = color_table.vals[Stag_Default]; - u32 text2 = color_table.vals[Stag_Pop1]; - draw_rectangle(target, item_rect, back); - Vec2 p = V2(item_rect.p0) + V2(0.f, 2.f); - p.x += draw_string(system, target, font_id, item->text_field.query, p, text2); - p.x += font_string_width(system, target, font_id, make_lit_string(" ")); - p.x += draw_string(system, target, font_id, item->text_field.string, p, text1); - }break; - - // TODO(allen): figure out how this should work again later - case UIType_ColorTheme: - {}break; - + Full_Cursor render_cursor = {}; + Range on_screen_range = {}; + view_call_render_caller(models, target, view, rect, render_cursor, on_screen_range, 0, 0, dont_do_core_render); + } + #if 0 - case UIType_ColorTheme: - { - Style *style_preview = &models->styles.styles[item->color_theme.index]; - u32 margin_color = get_margin_color(style_preview, item->activation_level); - u32 back = style_preview->theme.colors[Stag_Back]; - u32 text_color = style_preview->theme.colors[Stag_Default]; - u32 keyword_color = style_preview->theme.colors[Stag_Keyword]; - u32 int_constant_color = style_preview->theme.colors[Stag_Int_Constant]; - u32 comment_color = style_preview->theme.colors[Stag_Comment]; - - f32_Rect inner = get_inner_rect(item_rect, 3); - - draw_margin(target, item_rect, inner, margin_color); - draw_rectangle(target, inner, back); - - Vec2 p = V2(inner.p0); - String str = item->color_theme.string; - if (str.str == 0){ - str = style_preview->name; - } - p.x += draw_string(system, target, font_id, str, p, text_color); - f32 font_x = inner.x1 - font_string_width(system, target, font_id, font_name); - if (font_x > p.x + 10.f){ - draw_string(system, target, font_id, font_name, V2(font_x, p.y), text_color); - } - - Font_Pointers font = system->font.get_pointers_by_id(font_id); - i32 height = font.metrics->height; - p = V2(inner.x0, p.y + (f32)height); - p.x += draw_string(system, target, font_id, "if", p, keyword_color); - p.x += draw_string(system, target, font_id, "(x < ", p, text_color); - p.x += draw_string(system, target, font_id, "0", p, int_constant_color); - p.x += draw_string(system, target, font_id, ") { x = ", p, text_color); - p.x += draw_string(system, target, font_id, "0", p, int_constant_color); - p.x += draw_string(system, target, font_id, "; } ", p, text_color); - p.x += draw_string(system, target, font_id, "// comment", p, comment_color); - - p = V2(inner.x0, p.y + (f32)height); - draw_string(system, target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^", p, text_color); - }break; + f32_Rect rect_f32 = f32R(rect); + + i32 item_count = view->ui_control.count; + UI_Item *item = view->ui_control.items; + GUI_Scroll_Vars ui_scroll = view->ui_scroll; + for (i32 i = 0; i < item_count; ++i, item += 1){ + + f32_Rect item_rect = f32R(item->rectangle); + switch (item->coordinates){ + case UICoordinates_ViewSpace: + { + item_rect.x0 += rect_f32.x0 - ui_scroll.scroll_x; + item_rect.y0 += rect_f32.y0 - ui_scroll.scroll_y; + item_rect.x1 += rect_f32.x0 - ui_scroll.scroll_x; + item_rect.y1 += rect_f32.y0 - ui_scroll.scroll_y; + }break; + case UICoordinates_PanelSpace: + { + item_rect.x0 += rect_f32.x0; + item_rect.y0 += rect_f32.y0; + item_rect.x1 += rect_f32.x0; + item_rect.y1 += rect_f32.y0; + }break; + } + + if (rect_overlap(item_rect, rect_f32)){ + switch (item->type){ + case UIType_Option: + { + u32 back = color_table.vals[Stag_Back]; + u32 text_color = color_table.vals[Stag_Default]; + u32 pop_color = color_table.vals[Stag_Pop2]; + u32 margin_color = get_margin_color(color_table, item->activation_level); + f32_Rect inner = get_inner_rect(item_rect, 3); + draw_rectangle(target, inner, back); + Vec2 p = V2(inner.p0) + V2(3.f, line_height*0.5f - 1.f); + p.x += draw_string(system, target, font_id, item->option.string, p, text_color); + p.x += font_string_width(system, target, font_id, make_lit_string(" ")); + draw_string(system, target, font_id, item->option.status, p, pop_color); + draw_margin(target, item_rect, inner, margin_color); + }break; + + case UIType_TextField: + { + u32 back = color_table.vals[Stag_Back]; + u32 text1 = color_table.vals[Stag_Default]; + u32 text2 = color_table.vals[Stag_Pop1]; + draw_rectangle(target, item_rect, back); + Vec2 p = V2(item_rect.p0) + V2(0.f, 2.f); + p.x += draw_string(system, target, font_id, item->text_field.query, p, text2); + p.x += font_string_width(system, target, font_id, make_lit_string(" ")); + p.x += draw_string(system, target, font_id, item->text_field.string, p, text1); + }break; + + // TODO(allen): figure out how this should work again later + case UIType_ColorTheme: + {}break; + +#if 0 + case UIType_ColorTheme: + { + Style *style_preview = &models->styles.styles[item->color_theme.index]; + u32 margin_color = get_margin_color(style_preview, item->activation_level); + u32 back = style_preview->theme.colors[Stag_Back]; + u32 text_color = style_preview->theme.colors[Stag_Default]; + u32 keyword_color = style_preview->theme.colors[Stag_Keyword]; + u32 int_constant_color = style_preview->theme.colors[Stag_Int_Constant]; + u32 comment_color = style_preview->theme.colors[Stag_Comment]; + + f32_Rect inner = get_inner_rect(item_rect, 3); + + draw_margin(target, item_rect, inner, margin_color); + draw_rectangle(target, inner, back); + + Vec2 p = V2(inner.p0); + String str = item->color_theme.string; + if (str.str == 0){ + str = style_preview->name; + } + p.x += draw_string(system, target, font_id, str, p, text_color); + f32 font_x = inner.x1 - font_string_width(system, target, font_id, font_name); + if (font_x > p.x + 10.f){ + draw_string(system, target, font_id, font_name, V2(font_x, p.y), text_color); + } + + Font_Pointers font = system->font.get_pointers_by_id(font_id); + i32 height = font.metrics->height; + p = V2(inner.x0, p.y + (f32)height); + p.x += draw_string(system, target, font_id, "if", p, keyword_color); + p.x += draw_string(system, target, font_id, "(x < ", p, text_color); + p.x += draw_string(system, target, font_id, "0", p, int_constant_color); + p.x += draw_string(system, target, font_id, ") { x = ", p, text_color); + p.x += draw_string(system, target, font_id, "0", p, int_constant_color); + p.x += draw_string(system, target, font_id, "; } ", p, text_color); + p.x += draw_string(system, target, font_id, "// comment", p, comment_color); + + p = V2(inner.x0, p.y + (f32)height); + draw_string(system, target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^", p, text_color); + }break; #endif - } } } } + +#endif draw_pop_clip(target); }