Full rewrite of panel layout system
This commit is contained in:
parent
4e60d34016
commit
a8f678c740
|
@ -329,7 +329,12 @@ ENUM(int32_t, View_Split_Position){
|
||||||
/* DOC(This value indicates that the new view should be left of the existing view.) */
|
/* DOC(This value indicates that the new view should be left of the existing view.) */
|
||||||
ViewSplit_Left,
|
ViewSplit_Left,
|
||||||
/* DOC(This value indicates that the new view should be right of the existing view.) */
|
/* DOC(This value indicates that the new view should be right of the existing view.) */
|
||||||
ViewSplit_Right
|
ViewSplit_Right,
|
||||||
|
};
|
||||||
|
|
||||||
|
ENUM(int32_t, View_Split_Kind){
|
||||||
|
ViewSplitKind_Ratio,
|
||||||
|
ViewSplitKind_FixedPixels,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */
|
/* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */
|
||||||
|
@ -642,8 +647,6 @@ STRUCT i32_Rect{
|
||||||
int32_t y1;
|
int32_t y1;
|
||||||
};
|
};
|
||||||
|
|
||||||
GLOBAL_VAR i32_Rect null_i32_rect = {};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
DOC(A four corner axis aligned rectangle, with floating point coordinates.)
|
DOC(A four corner axis aligned rectangle, with floating point coordinates.)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -72,7 +72,7 @@ static View_Summary
|
||||||
open_footer_panel(Application_Links *app, View_Summary *view){
|
open_footer_panel(Application_Links *app, View_Summary *view){
|
||||||
View_Summary special_view = open_view(app, view, ViewSplit_Bottom);
|
View_Summary special_view = open_view(app, view, ViewSplit_Bottom);
|
||||||
new_view_settings(app, &special_view);
|
new_view_settings(app, &special_view);
|
||||||
view_set_split_proportion(app, &special_view, .2f);
|
view_set_split_pixel_size(app, &special_view, (int32_t)(special_view.line_height*10.f));
|
||||||
view_set_passive(app, &special_view, true);
|
view_set_passive(app, &special_view, true);
|
||||||
return(special_view);
|
return(special_view);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct Application_Links;
|
||||||
#define VIEW_GET_SETTING_SIG(n) bool32 n(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t *value_out)
|
#define VIEW_GET_SETTING_SIG(n) bool32 n(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t *value_out)
|
||||||
#define VIEW_SET_SETTING_SIG(n) bool32 n(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t value)
|
#define VIEW_SET_SETTING_SIG(n) bool32 n(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t value)
|
||||||
#define VIEW_GET_MANAGED_SCOPE_SIG(n) Managed_Scope n(Application_Links *app, View_ID view_id)
|
#define VIEW_GET_MANAGED_SCOPE_SIG(n) Managed_Scope n(Application_Links *app, View_ID view_id)
|
||||||
#define VIEW_SET_SPLIT_PROPORTION_SIG(n) bool32 n(Application_Links *app, View_Summary *view, float t)
|
#define VIEW_SET_SPLIT_SIG(n) bool32 n(Application_Links *app, View_Summary *view, View_Split_Kind kind, float t)
|
||||||
#define VIEW_GET_ENCLOSURE_RECT_SIG(n) i32_Rect n(Application_Links *app, View_Summary *view)
|
#define VIEW_GET_ENCLOSURE_RECT_SIG(n) i32_Rect n(Application_Links *app, View_Summary *view)
|
||||||
#define VIEW_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out)
|
#define VIEW_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out)
|
||||||
#define VIEW_SET_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x)
|
#define VIEW_SET_CURSOR_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x)
|
||||||
|
@ -167,7 +167,7 @@ typedef SET_ACTIVE_VIEW_SIG(Set_Active_View_Function);
|
||||||
typedef VIEW_GET_SETTING_SIG(View_Get_Setting_Function);
|
typedef VIEW_GET_SETTING_SIG(View_Get_Setting_Function);
|
||||||
typedef VIEW_SET_SETTING_SIG(View_Set_Setting_Function);
|
typedef VIEW_SET_SETTING_SIG(View_Set_Setting_Function);
|
||||||
typedef VIEW_GET_MANAGED_SCOPE_SIG(View_Get_Managed_Scope_Function);
|
typedef VIEW_GET_MANAGED_SCOPE_SIG(View_Get_Managed_Scope_Function);
|
||||||
typedef VIEW_SET_SPLIT_PROPORTION_SIG(View_Set_Split_Proportion_Function);
|
typedef VIEW_SET_SPLIT_SIG(View_Set_Split_Function);
|
||||||
typedef VIEW_GET_ENCLOSURE_RECT_SIG(View_Get_Enclosure_Rect_Function);
|
typedef VIEW_GET_ENCLOSURE_RECT_SIG(View_Get_Enclosure_Rect_Function);
|
||||||
typedef VIEW_COMPUTE_CURSOR_SIG(View_Compute_Cursor_Function);
|
typedef VIEW_COMPUTE_CURSOR_SIG(View_Compute_Cursor_Function);
|
||||||
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
|
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
|
||||||
|
@ -297,7 +297,7 @@ Set_Active_View_Function *set_active_view;
|
||||||
View_Get_Setting_Function *view_get_setting;
|
View_Get_Setting_Function *view_get_setting;
|
||||||
View_Set_Setting_Function *view_set_setting;
|
View_Set_Setting_Function *view_set_setting;
|
||||||
View_Get_Managed_Scope_Function *view_get_managed_scope;
|
View_Get_Managed_Scope_Function *view_get_managed_scope;
|
||||||
View_Set_Split_Proportion_Function *view_set_split_proportion;
|
View_Set_Split_Function *view_set_split;
|
||||||
View_Get_Enclosure_Rect_Function *view_get_enclosure_rect;
|
View_Get_Enclosure_Rect_Function *view_get_enclosure_rect;
|
||||||
View_Compute_Cursor_Function *view_compute_cursor;
|
View_Compute_Cursor_Function *view_compute_cursor;
|
||||||
View_Set_Cursor_Function *view_set_cursor;
|
View_Set_Cursor_Function *view_set_cursor;
|
||||||
|
@ -426,7 +426,7 @@ Set_Active_View_Function *set_active_view_;
|
||||||
View_Get_Setting_Function *view_get_setting_;
|
View_Get_Setting_Function *view_get_setting_;
|
||||||
View_Set_Setting_Function *view_set_setting_;
|
View_Set_Setting_Function *view_set_setting_;
|
||||||
View_Get_Managed_Scope_Function *view_get_managed_scope_;
|
View_Get_Managed_Scope_Function *view_get_managed_scope_;
|
||||||
View_Set_Split_Proportion_Function *view_set_split_proportion_;
|
View_Set_Split_Function *view_set_split_;
|
||||||
View_Get_Enclosure_Rect_Function *view_get_enclosure_rect_;
|
View_Get_Enclosure_Rect_Function *view_get_enclosure_rect_;
|
||||||
View_Compute_Cursor_Function *view_compute_cursor_;
|
View_Compute_Cursor_Function *view_compute_cursor_;
|
||||||
View_Set_Cursor_Function *view_set_cursor_;
|
View_Set_Cursor_Function *view_set_cursor_;
|
||||||
|
@ -563,7 +563,7 @@ app_links->set_active_view_ = Set_Active_View;\
|
||||||
app_links->view_get_setting_ = View_Get_Setting;\
|
app_links->view_get_setting_ = View_Get_Setting;\
|
||||||
app_links->view_set_setting_ = View_Set_Setting;\
|
app_links->view_set_setting_ = View_Set_Setting;\
|
||||||
app_links->view_get_managed_scope_ = View_Get_Managed_Scope;\
|
app_links->view_get_managed_scope_ = View_Get_Managed_Scope;\
|
||||||
app_links->view_set_split_proportion_ = View_Set_Split_Proportion;\
|
app_links->view_set_split_ = View_Set_Split;\
|
||||||
app_links->view_get_enclosure_rect_ = View_Get_Enclosure_Rect;\
|
app_links->view_get_enclosure_rect_ = View_Get_Enclosure_Rect;\
|
||||||
app_links->view_compute_cursor_ = View_Compute_Cursor;\
|
app_links->view_compute_cursor_ = View_Compute_Cursor;\
|
||||||
app_links->view_set_cursor_ = View_Set_Cursor;\
|
app_links->view_set_cursor_ = View_Set_Cursor;\
|
||||||
|
@ -692,7 +692,7 @@ static bool32 set_active_view(Application_Links *app, View_Summary *view){return
|
||||||
static bool32 view_get_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t *value_out){return(app->view_get_setting(app, view, setting, value_out));}
|
static bool32 view_get_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t *value_out){return(app->view_get_setting(app, view, setting, value_out));}
|
||||||
static bool32 view_set_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t value){return(app->view_set_setting(app, view, setting, value));}
|
static bool32 view_set_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t value){return(app->view_set_setting(app, view, setting, value));}
|
||||||
static Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id){return(app->view_get_managed_scope(app, view_id));}
|
static Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id){return(app->view_get_managed_scope(app, view_id));}
|
||||||
static bool32 view_set_split_proportion(Application_Links *app, View_Summary *view, float t){return(app->view_set_split_proportion(app, view, t));}
|
static bool32 view_set_split(Application_Links *app, View_Summary *view, View_Split_Kind kind, float t){return(app->view_set_split(app, view, kind, t));}
|
||||||
static i32_Rect view_get_enclosure_rect(Application_Links *app, View_Summary *view){return(app->view_get_enclosure_rect(app, view));}
|
static i32_Rect view_get_enclosure_rect(Application_Links *app, View_Summary *view){return(app->view_get_enclosure_rect(app, view));}
|
||||||
static bool32 view_compute_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out){return(app->view_compute_cursor(app, view, seek, cursor_out));}
|
static bool32 view_compute_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out){return(app->view_compute_cursor(app, view, seek, cursor_out));}
|
||||||
static bool32 view_set_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x){return(app->view_set_cursor(app, view, seek, set_preferred_x));}
|
static bool32 view_set_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x){return(app->view_set_cursor(app, view, seek, set_preferred_x));}
|
||||||
|
@ -821,7 +821,7 @@ static bool32 set_active_view(Application_Links *app, View_Summary *view){return
|
||||||
static bool32 view_get_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t *value_out){return(app->view_get_setting_(app, view, setting, value_out));}
|
static bool32 view_get_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t *value_out){return(app->view_get_setting_(app, view, setting, value_out));}
|
||||||
static bool32 view_set_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t value){return(app->view_set_setting_(app, view, setting, value));}
|
static bool32 view_set_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, int32_t value){return(app->view_set_setting_(app, view, setting, value));}
|
||||||
static Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id){return(app->view_get_managed_scope_(app, view_id));}
|
static Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id){return(app->view_get_managed_scope_(app, view_id));}
|
||||||
static bool32 view_set_split_proportion(Application_Links *app, View_Summary *view, float t){return(app->view_set_split_proportion_(app, view, t));}
|
static bool32 view_set_split(Application_Links *app, View_Summary *view, View_Split_Kind kind, float t){return(app->view_set_split_(app, view, kind, t));}
|
||||||
static i32_Rect view_get_enclosure_rect(Application_Links *app, View_Summary *view){return(app->view_get_enclosure_rect_(app, view));}
|
static i32_Rect view_get_enclosure_rect(Application_Links *app, View_Summary *view){return(app->view_get_enclosure_rect_(app, view));}
|
||||||
static bool32 view_compute_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out){return(app->view_compute_cursor_(app, view, seek, cursor_out));}
|
static bool32 view_compute_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out){return(app->view_compute_cursor_(app, view, seek, cursor_out));}
|
||||||
static bool32 view_set_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x){return(app->view_set_cursor_(app, view, seek, set_preferred_x));}
|
static bool32 view_set_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, bool32 set_preferred_x){return(app->view_set_cursor_(app, view, seek, set_preferred_x));}
|
||||||
|
|
|
@ -1596,5 +1596,17 @@ begin_notepad_mode(Application_Links *app){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
view_set_split_proportion(Application_Links *app, View_Summary *view, float t){
|
||||||
|
return(view_set_split(app, view, ViewSplitKind_Ratio, t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32
|
||||||
|
view_set_split_pixel_size(Application_Links *app, View_Summary *view, int32_t t){
|
||||||
|
return(view_set_split(app, view, ViewSplitKind_FixedPixels, (float)t));
|
||||||
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
342
4ed.cpp
342
4ed.cpp
|
@ -66,9 +66,10 @@ internal void
|
||||||
file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file){
|
file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file){
|
||||||
Assert(file != 0);
|
Assert(file != 0);
|
||||||
i32 pos = buffer_size(&file->state.buffer);
|
i32 pos = buffer_size(&file->state.buffer);
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
Layout *layout = &models->layout;
|
||||||
panel != &models->layout.used_sentinel;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel = panel->next){
|
panel != 0;
|
||||||
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file != file){
|
if (view->transient.file_data.file != file){
|
||||||
continue;
|
continue;
|
||||||
|
@ -78,15 +79,6 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
|
||||||
do_feedback_message(System_Functions *system, Models *models, String value){
|
|
||||||
Editing_File *file = models->message_buffer;
|
|
||||||
if (file != 0){
|
|
||||||
output_file_append(system, models, file, value);
|
|
||||||
file_cursor_to_end(system, models, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
|
|
||||||
#define USE_VARS(n) App_Vars *n = command->vars
|
#define USE_VARS(n) App_Vars *n = command->vars
|
||||||
|
@ -110,14 +102,6 @@ do_feedback_message(System_Functions *system, Models *models, String value){
|
||||||
|
|
||||||
#define COMMAND_DECL(n) internal void command_##n(System_Functions *system, Models *models, Command_Binding binding)
|
#define COMMAND_DECL(n) internal void command_##n(System_Functions *system, Models *models, Command_Binding binding)
|
||||||
|
|
||||||
internal View*
|
|
||||||
panel_make_empty(System_Functions *system, Models *models, Panel *panel){
|
|
||||||
Assert(panel->view == 0);
|
|
||||||
View_And_ID new_view = live_set_alloc_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set, panel);
|
|
||||||
view_set_file(system, models, new_view.view, models->scratch_buffer);
|
|
||||||
return(new_view.view);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMMAND_DECL(null){}
|
COMMAND_DECL(null){}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -133,7 +117,7 @@ view_undo_redo(System_Functions *system, Models *models, View *view, Edit_Stack
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_DECL(undo){
|
COMMAND_DECL(undo){
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||||
View *view = active_panel->view;
|
View *view = active_panel->view;
|
||||||
if (view_lock_flags(view) != 0){
|
if (view_lock_flags(view) != 0){
|
||||||
return;
|
return;
|
||||||
|
@ -147,7 +131,7 @@ COMMAND_DECL(undo){
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_DECL(redo){
|
COMMAND_DECL(redo){
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||||
View *view = active_panel->view;
|
View *view = active_panel->view;
|
||||||
if (view_lock_flags(view) != 0){
|
if (view_lock_flags(view) != 0){
|
||||||
return;
|
return;
|
||||||
|
@ -894,39 +878,13 @@ App_Init_Sig(app_init){
|
||||||
models->config_api = api;
|
models->config_api = api;
|
||||||
models->app_links.cmd_context = models;
|
models->app_links.cmd_context = models;
|
||||||
|
|
||||||
Partition *partition = &models->mem.part;
|
Partition *part = &models->mem.part;
|
||||||
|
|
||||||
i32 panel_max_count = MAX_VIEWS;
|
|
||||||
models->layout.panel_max_count = panel_max_count;
|
|
||||||
i32 divider_max_count = panel_max_count - 1;
|
|
||||||
models->layout.panel_count = 0;
|
|
||||||
|
|
||||||
Panel *panels = push_array(partition, Panel, panel_max_count);
|
|
||||||
models->layout.panels = panels;
|
|
||||||
|
|
||||||
dll_init_sentinel(&models->layout.free_sentinel);
|
|
||||||
dll_init_sentinel(&models->layout.used_sentinel);
|
|
||||||
|
|
||||||
Panel *panel = panels;
|
|
||||||
for (i32 i = 0; i < panel_max_count; ++i, ++panel){
|
|
||||||
dll_insert(&models->layout.free_sentinel, panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
Panel_Divider *dividers = push_array(partition, Panel_Divider, divider_max_count);
|
|
||||||
models->layout.dividers = dividers;
|
|
||||||
|
|
||||||
Panel_Divider *div = dividers;
|
|
||||||
for (i32 i = 0; i < divider_max_count-1; ++i, ++div){
|
|
||||||
div->next = (div + 1);
|
|
||||||
}
|
|
||||||
div->next = 0;
|
|
||||||
models->layout.free_divider = dividers;
|
|
||||||
|
|
||||||
|
// NOTE(allen): live set
|
||||||
{
|
{
|
||||||
models->live_set.count = 0;
|
models->live_set.count = 0;
|
||||||
models->live_set.max = panel_max_count;
|
models->live_set.max = MAX_VIEWS;
|
||||||
|
models->live_set.views = push_array(part, View, models->live_set.max);
|
||||||
models->live_set.views = push_array(partition, View, models->live_set.max);
|
|
||||||
|
|
||||||
//dll_init_sentinel
|
//dll_init_sentinel
|
||||||
models->live_set.free_sentinel.transient.next = &models->live_set.free_sentinel;
|
models->live_set.free_sentinel.transient.next = &models->live_set.free_sentinel;
|
||||||
|
@ -948,7 +906,7 @@ App_Init_Sig(app_init){
|
||||||
|
|
||||||
{
|
{
|
||||||
umem memsize = KB(8);
|
umem memsize = KB(8);
|
||||||
void *mem = push_array(partition, u8, (i32)memsize);
|
void *mem = push_array(part, u8, (i32)memsize);
|
||||||
parse_context_init_memory(&models->parse_context_memory, mem, memsize);
|
parse_context_init_memory(&models->parse_context_memory, mem, memsize);
|
||||||
parse_context_add_default(&models->parse_context_memory, &models->mem.heap);
|
parse_context_add_default(&models->parse_context_memory, &models->mem.heap);
|
||||||
}
|
}
|
||||||
|
@ -963,12 +921,10 @@ App_Init_Sig(app_init){
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic_variables_init(&models->variable_layout);
|
dynamic_variables_init(&models->variable_layout);
|
||||||
dynamic_workspace_init(&models->mem.heap, &models->lifetime_allocator,
|
dynamic_workspace_init(&models->mem.heap, &models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace);
|
||||||
DynamicWorkspace_Global, 0,
|
|
||||||
&models->dynamic_workspace);
|
|
||||||
|
|
||||||
// NOTE(allen): file setup
|
// NOTE(allen): file setup
|
||||||
working_set_init(system, &models->working_set, partition, &vars->models.mem.heap);
|
working_set_init(system, &models->working_set, part, &vars->models.mem.heap);
|
||||||
models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH;
|
models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH;
|
||||||
models->working_set.default_minimum_base_display_width = DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH;
|
models->working_set.default_minimum_base_display_width = DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH;
|
||||||
|
|
||||||
|
@ -991,7 +947,7 @@ App_Init_Sig(app_init){
|
||||||
// NOTE(allen): title space
|
// NOTE(allen): title space
|
||||||
models->has_new_title = true;
|
models->has_new_title = true;
|
||||||
models->title_capacity = KB(4);
|
models->title_capacity = KB(4);
|
||||||
models->title_space = push_array(partition, char, models->title_capacity);
|
models->title_space = push_array(part, char, models->title_capacity);
|
||||||
{
|
{
|
||||||
String builder = make_string_cap(models->title_space, 0, models->title_capacity);
|
String builder = make_string_cap(models->title_space, 0, models->title_capacity);
|
||||||
append(&builder, WINDOW_NAME);
|
append(&builder, WINDOW_NAME);
|
||||||
|
@ -1002,7 +958,7 @@ App_Init_Sig(app_init){
|
||||||
models->system = system;
|
models->system = system;
|
||||||
models->vars = vars;
|
models->vars = vars;
|
||||||
|
|
||||||
// NOTE(allen): init first panel
|
// NOTE(allen): init baked in buffers
|
||||||
File_Init init_files[] = {
|
File_Init init_files[] = {
|
||||||
{ make_lit_string("*messages*"), &models->message_buffer, true , },
|
{ make_lit_string("*messages*"), &models->message_buffer, true , },
|
||||||
{ make_lit_string("*scratch*"), &models->scratch_buffer, false, },
|
{ make_lit_string("*scratch*"), &models->scratch_buffer, false, },
|
||||||
|
@ -1011,7 +967,7 @@ App_Init_Sig(app_init){
|
||||||
Heap *heap = &models->mem.heap;
|
Heap *heap = &models->mem.heap;
|
||||||
for (i32 i = 0; i < ArrayCount(init_files); ++i){
|
for (i32 i = 0; i < ArrayCount(init_files); ++i){
|
||||||
Editing_File *file = working_set_alloc_always(&models->working_set, heap, &models->lifetime_allocator);
|
Editing_File *file = working_set_alloc_always(&models->working_set, heap, &models->lifetime_allocator);
|
||||||
buffer_bind_name(models, heap, partition, &models->working_set, file, init_files[i].name);
|
buffer_bind_name(models, heap, part, &models->working_set, file, init_files[i].name);
|
||||||
|
|
||||||
if (init_files[i].ptr != 0){
|
if (init_files[i].ptr != 0){
|
||||||
*init_files[i].ptr = file;
|
*init_files[i].ptr = file;
|
||||||
|
@ -1029,14 +985,20 @@ App_Init_Sig(app_init){
|
||||||
file->settings.unwrapped_lines = true;
|
file->settings.unwrapped_lines = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel_And_ID p = layout_alloc_panel(&models->layout);
|
// NOTE(allen): setup first panel
|
||||||
panel_make_empty(system, models, p.panel);
|
{
|
||||||
models->layout.active_panel = p.id;
|
Panel *panel = layout_initialize(part, &models->layout);
|
||||||
|
View *new_view = live_set_alloc_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set);
|
||||||
|
panel->view = new_view;
|
||||||
|
new_view->transient.panel = panel;
|
||||||
|
view_set_file(system, models, new_view, models->scratch_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): hot directory
|
||||||
hot_directory_init(&models->hot_directory, current_directory);
|
hot_directory_init(&models->hot_directory, current_directory);
|
||||||
|
|
||||||
// NOTE(allen): child proc list setup
|
// NOTE(allen): child proc list setup
|
||||||
vars->cli_processes = make_cli_list(partition, 16);
|
vars->cli_processes = make_cli_list(part, MAX_VIEWS);
|
||||||
|
|
||||||
// NOTE(allen): init GUI keys
|
// NOTE(allen): init GUI keys
|
||||||
models->user_up_key = key_up;
|
models->user_up_key = key_up;
|
||||||
|
@ -1104,18 +1066,9 @@ App_Step_Sig(app_step){
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(allen): reorganizing panels on screen
|
// NOTE(allen): reorganizing panels on screen
|
||||||
i32 prev_width = models->layout.full_width;
|
Vec2_i32 prev_dim = layout_get_root_size(&models->layout);
|
||||||
i32 prev_height = models->layout.full_height;
|
Vec2_i32 current_dim = V2(target->width, target->height);
|
||||||
i32 current_width = target->width;
|
layout_set_root_size(&models->layout, current_dim);
|
||||||
i32 current_height = target->height;
|
|
||||||
{
|
|
||||||
models->layout.full_width = current_width;
|
|
||||||
models->layout.full_height = current_height;
|
|
||||||
|
|
||||||
if (prev_width != current_width || prev_height != current_height){
|
|
||||||
layout_refit(&models->layout, prev_width, prev_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(allen): First frame initialization
|
// NOTE(allen): First frame initialization
|
||||||
if (input->first_step){
|
if (input->first_step){
|
||||||
|
@ -1242,8 +1195,8 @@ App_Step_Sig(app_step){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->mouse.x != models->prev_x || input->mouse.y != models->prev_y){
|
if (input->mouse.x != models->prev_x || input->mouse.y != models->prev_y){
|
||||||
b32 was_in_window = hit_check(models->prev_x, models->prev_y, i32R(0, 0, prev_width, prev_height));
|
b32 was_in_window = hit_check(models->prev_x, models->prev_y, i32R(0, 0, prev_dim.x, prev_dim.y));
|
||||||
b32 is_in_window = hit_check(input->mouse.x, input->mouse.y, i32R(0, 0, current_width, current_height));
|
b32 is_in_window = hit_check(input->mouse.x, input->mouse.y, i32R(0, 0, current_dim.x, current_dim.y));
|
||||||
if (is_in_window || was_in_window){
|
if (is_in_window || was_in_window){
|
||||||
mouse_event.keycode = key_mouse_move;
|
mouse_event.keycode = key_mouse_move;
|
||||||
input->keys.keys[input->keys.count++] = mouse_event;
|
input->keys.keys[input->keys.count++] = mouse_event;
|
||||||
|
@ -1255,80 +1208,42 @@ App_Step_Sig(app_step){
|
||||||
input->keys.keys[input->keys.count++] = mouse_event;
|
input->keys.keys[input->keys.count++] = mouse_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(allen): expose layout
|
||||||
|
Layout *layout = &models->layout;
|
||||||
|
|
||||||
// NOTE(allen): mouse hover status
|
// NOTE(allen): mouse hover status
|
||||||
Panel *mouse_panel = 0;
|
Panel *mouse_panel = 0;
|
||||||
b32 mouse_in_edit_area = false;
|
Panel *divider_panel = 0;
|
||||||
b32 mouse_in_margin_area = false;
|
b32 mouse_in_margin = false;
|
||||||
b32 mouse_on_divider = false;
|
Vec2_i32 mouse = V2(input->mouse.x, input->mouse.y);
|
||||||
b32 mouse_divider_vertical = false;
|
{
|
||||||
i32 mouse_divider_id = 0;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
i32 mouse_divider_side = 0;
|
panel != 0;
|
||||||
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
i32 mx = input->mouse.x;
|
if (hit_check(mouse.x, mouse.y, panel->rect_full)){
|
||||||
i32 my = input->mouse.y;
|
mouse_panel = panel;
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
if (!hit_check(mouse.x, mouse.y, panel->rect_inner)){
|
||||||
panel != &models->layout.used_sentinel;
|
mouse_in_margin = true;
|
||||||
panel = panel->next){
|
for (divider_panel = mouse_panel->parent;
|
||||||
if (hit_check(mx, my, panel->inner)){
|
divider_panel != 0;
|
||||||
mouse_panel = panel;
|
divider_panel = divider_panel->parent){
|
||||||
mouse_in_edit_area = true;
|
if (hit_check(mouse.x, mouse.y, divider_panel->rect_inner)){
|
||||||
}
|
break;
|
||||||
else if (hit_check(mx, my, panel->full)){
|
}
|
||||||
mouse_panel = panel;
|
|
||||||
mouse_in_margin_area = true;
|
|
||||||
|
|
||||||
if (mx >= panel->inner.x0 && mx < panel->inner.x1){
|
|
||||||
if (my > panel->inner.y0){
|
|
||||||
mouse_divider_side = -1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
mouse_divider_side = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
mouse_divider_vertical = true;
|
|
||||||
if (mx > panel->inner.x0){
|
|
||||||
mouse_divider_side = -1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
mouse_divider_side = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (models->layout.panel_count > 1){
|
|
||||||
mouse_divider_id = panel->parent;
|
|
||||||
|
|
||||||
i32 which_child = panel->which_child;
|
|
||||||
for (;;){
|
|
||||||
Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id);
|
|
||||||
if (which_child == mouse_divider_side && div.divider->v_divider == mouse_divider_vertical){
|
|
||||||
mouse_on_divider = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (mouse_divider_id == models->layout.root){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mouse_divider_id = div.divider->parent;
|
|
||||||
which_child = div.divider->which_child;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
if (mouse_panel != 0){
|
||||||
mouse_on_divider = false;
|
break;
|
||||||
mouse_divider_id = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse_panel != 0){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(allen): consume event stream
|
// NOTE(allen): consume event stream
|
||||||
Key_Event_Data *key_ptr = input->keys.keys;
|
Key_Event_Data *key_ptr = input->keys.keys;
|
||||||
Key_Event_Data *key_end = key_ptr + input->keys.count;
|
Key_Event_Data *key_end = key_ptr + input->keys.count;
|
||||||
for (;key_ptr < key_end; key_ptr += 1){
|
for (;key_ptr < key_end; key_ptr += 1){
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(layout);
|
||||||
View *view = active_panel->view;
|
View *view = active_panel->view;
|
||||||
Assert(view != 0);
|
Assert(view != 0);
|
||||||
|
|
||||||
|
@ -1344,7 +1259,7 @@ App_Step_Sig(app_step){
|
||||||
EventConsume_Command,
|
EventConsume_Command,
|
||||||
};
|
};
|
||||||
i32 event_consume_mode = EventConsume_Command;
|
i32 event_consume_mode = EventConsume_Command;
|
||||||
if (keycode == key_mouse_left && input->mouse.press_l && mouse_on_divider){
|
if (keycode == key_mouse_left && input->mouse.press_l && (divider_panel != 0)){
|
||||||
event_consume_mode = EventConsume_BeginResize;
|
event_consume_mode = EventConsume_BeginResize;
|
||||||
}
|
}
|
||||||
else if (keycode == key_mouse_left && input->mouse.press_l && mouse_panel != 0 && mouse_panel != active_panel){
|
else if (keycode == key_mouse_left && input->mouse.press_l && mouse_panel != 0 && mouse_panel != active_panel){
|
||||||
|
@ -1355,56 +1270,7 @@ App_Step_Sig(app_step){
|
||||||
case EventConsume_BeginResize:
|
case EventConsume_BeginResize:
|
||||||
{
|
{
|
||||||
vars->state = APP_STATE_RESIZING;
|
vars->state = APP_STATE_RESIZING;
|
||||||
Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id);
|
models->resizing_intermediate_panel = divider_panel;
|
||||||
vars->resizing.divider = div.divider;
|
|
||||||
|
|
||||||
f32 min = 0;
|
|
||||||
f32 max = 0;
|
|
||||||
if (mouse_divider_vertical){
|
|
||||||
max = (f32)models->layout.full_width;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
max = (f32)models->layout.full_height;
|
|
||||||
}
|
|
||||||
f32 mid = layout_get_position(&models->layout, mouse_divider_id);
|
|
||||||
|
|
||||||
i32 divider_id = div.id;
|
|
||||||
do{
|
|
||||||
Divider_And_ID other_div = layout_get_divider(&models->layout, divider_id);
|
|
||||||
b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
|
|
||||||
f32 pos = layout_get_position(&models->layout, divider_id);
|
|
||||||
if (divider_match && pos > mid && pos < max){
|
|
||||||
max = pos;
|
|
||||||
}
|
|
||||||
else if (divider_match && pos < mid && pos > min){
|
|
||||||
min = pos;
|
|
||||||
}
|
|
||||||
divider_id = other_div.divider->parent;
|
|
||||||
}while(divider_id != -1);
|
|
||||||
|
|
||||||
Temp_Memory temp = begin_temp_memory(&models->mem.part);
|
|
||||||
i32 *divider_stack = push_array(&models->mem.part, i32, models->layout.panel_count);
|
|
||||||
i32 top = 0;
|
|
||||||
divider_stack[top++] = div.id;
|
|
||||||
for (;top > 0;){
|
|
||||||
--top;
|
|
||||||
Divider_And_ID other_div = layout_get_divider(&models->layout, divider_stack[top]);
|
|
||||||
b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
|
|
||||||
f32 pos = layout_get_position(&models->layout, divider_stack[top]);
|
|
||||||
if (divider_match && pos > mid && pos < max){
|
|
||||||
max = pos;
|
|
||||||
}
|
|
||||||
else if (divider_match && pos < mid && pos > min){
|
|
||||||
min = pos;
|
|
||||||
}
|
|
||||||
if (other_div.divider->child1 != -1){
|
|
||||||
divider_stack[top++] = other_div.divider->child1;
|
|
||||||
}
|
|
||||||
if (other_div.divider->child2 != -1){
|
|
||||||
divider_stack[top++] = other_div.divider->child2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end_temp_memory(temp);
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case EventConsume_ClickChangeView:
|
case EventConsume_ClickChangeView:
|
||||||
|
@ -1422,7 +1288,7 @@ App_Step_Sig(app_step){
|
||||||
force_abort_coroutine(system, models, view);
|
force_abort_coroutine(system, models, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
models->layout.active_panel = (i32)(mouse_panel - models->layout.panels);
|
layout->active_panel = mouse_panel;
|
||||||
app_result.animating = true;
|
app_result.animating = true;
|
||||||
active_panel = mouse_panel;
|
active_panel = mouse_panel;
|
||||||
view = active_panel->view;
|
view = active_panel->view;
|
||||||
|
@ -1478,21 +1344,11 @@ App_Step_Sig(app_step){
|
||||||
}
|
}
|
||||||
else if (keycode == key_mouse_move){
|
else if (keycode == key_mouse_move){
|
||||||
if (input->mouse.l){
|
if (input->mouse.l){
|
||||||
Panel_Divider *divider = vars->resizing.divider;
|
Panel *split = models->resizing_intermediate_panel;
|
||||||
i32 mouse_position = 0;
|
Range limits = layout_get_limiting_range_on_split(layout, split);
|
||||||
|
i32 mouse_position = (split->vertical_split)?(mouse.x):(mouse.y);
|
||||||
i32 absolute_positions[MAX_VIEWS];
|
mouse_position = clamp(limits.min, mouse_position, limits.max);
|
||||||
i32 min = 0;
|
layout_set_split_absolute_position(layout, split, mouse_position);
|
||||||
i32 max = 0;
|
|
||||||
i32 div_id = (i32)(divider - models->layout.dividers);
|
|
||||||
|
|
||||||
layout_compute_absolute_positions(&models->layout, absolute_positions);
|
|
||||||
mouse_position = (divider->v_divider)?(mx):(my);
|
|
||||||
layout_get_min_max(&models->layout, divider, absolute_positions, &min, &max);
|
|
||||||
absolute_positions[div_id] = clamp(min, mouse_position, max);
|
|
||||||
layout_update_all_positions(&models->layout, absolute_positions);
|
|
||||||
|
|
||||||
layout_fix_all_panels(&models->layout);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
vars->state = APP_STATE_EDIT;
|
vars->state = APP_STATE_EDIT;
|
||||||
|
@ -1510,11 +1366,11 @@ App_Step_Sig(app_step){
|
||||||
|
|
||||||
// NOTE(allen): step panels
|
// NOTE(allen): step panels
|
||||||
{
|
{
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(layout);
|
||||||
|
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &models->layout.used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
|
|
||||||
GUI_Scroll_Vars *scroll_vars = 0;
|
GUI_Scroll_Vars *scroll_vars = 0;
|
||||||
|
@ -1533,7 +1389,7 @@ App_Step_Sig(app_step){
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 active = (panel == active_panel);
|
b32 active = (panel == active_panel);
|
||||||
Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->inner, active, dt, *scroll_vars, max_y);
|
Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->rect_inner, active, dt, *scroll_vars, max_y);
|
||||||
|
|
||||||
if (ip_result.is_animating){
|
if (ip_result.is_animating){
|
||||||
app_result.animating = true;
|
app_result.animating = true;
|
||||||
|
@ -1552,9 +1408,9 @@ App_Step_Sig(app_step){
|
||||||
|
|
||||||
// NOTE(allen): on the first frame there should be no scrolling
|
// NOTE(allen): on the first frame there should be no scrolling
|
||||||
if (input->first_step){
|
if (input->first_step){
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &models->layout.used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos.scroll;
|
GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos.scroll;
|
||||||
scroll_vars->scroll_x = (f32)scroll_vars->target_x;
|
scroll_vars->scroll_x = (f32)scroll_vars->target_x;
|
||||||
|
@ -1578,30 +1434,31 @@ App_Step_Sig(app_step){
|
||||||
Partition *scratch = &models->mem.part;
|
Partition *scratch = &models->mem.part;
|
||||||
|
|
||||||
Temp_Memory temp = begin_temp_memory(scratch);
|
Temp_Memory temp = begin_temp_memory(scratch);
|
||||||
Buffer_ID *ids = push_array(scratch, Buffer_ID, 0);
|
|
||||||
Node *first = working_set->edit_finished_list.next;
|
Node *first = working_set->edit_finished_list.next;
|
||||||
Node *stop = &working_set->edit_finished_list;
|
Node *stop = &working_set->edit_finished_list;
|
||||||
|
|
||||||
|
Editing_File **file_ptrs = push_array(scratch, Editing_File*, 0);
|
||||||
for (Node *node = first;
|
for (Node *node = first;
|
||||||
node != stop;
|
node != stop;
|
||||||
node = node->next){
|
node = node->next){
|
||||||
Editing_File *file = CastFromMember(Editing_File, edit_finished_mark_node, node);
|
Editing_File **file_ptr = push_array(scratch, Editing_File*, 1);
|
||||||
Buffer_ID *new_id = push_array(scratch, Buffer_ID, 1);
|
*file_ptr = CastFromMember(Editing_File, edit_finished_mark_node, node);
|
||||||
*new_id = file->id.id;
|
}
|
||||||
|
i32 id_count = (i32)(push_array(scratch, Editing_File*, 0) - file_ptrs);
|
||||||
|
|
||||||
|
Buffer_ID *ids = push_array(scratch, Buffer_ID, id_count);
|
||||||
|
for (i32 i = 0; i < id_count; i += 1){
|
||||||
|
ids[i] = file_ptrs[i]->id.id;
|
||||||
}
|
}
|
||||||
i32 id_count = (i32)(push_array(scratch, Buffer_ID, 0) - ids);
|
|
||||||
|
|
||||||
working_set->do_not_mark_edits = true;
|
working_set->do_not_mark_edits = true;
|
||||||
hook_file_edit_finished(&models->app_links, ids, id_count);
|
hook_file_edit_finished(&models->app_links, ids, id_count);
|
||||||
working_set->do_not_mark_edits = false;
|
working_set->do_not_mark_edits = false;
|
||||||
|
|
||||||
for (Node *node = first, *next = 0;
|
for (i32 i = 0; i < id_count; i += 1){
|
||||||
node != stop;
|
block_zero_struct(&file_ptrs[i]->edit_finished_mark_node);
|
||||||
node = next){
|
|
||||||
next = node->next;
|
|
||||||
node->next = 0;
|
|
||||||
node->prev = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dll_init_sentinel(&working_set->edit_finished_list);
|
dll_init_sentinel(&working_set->edit_finished_list);
|
||||||
working_set->time_of_next_edit_finished_signal = 0;
|
working_set->time_of_next_edit_finished_signal = 0;
|
||||||
|
|
||||||
|
@ -1630,15 +1487,15 @@ App_Step_Sig(app_step){
|
||||||
{
|
{
|
||||||
begin_render_section(target, system);
|
begin_render_section(target, system);
|
||||||
|
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(layout);
|
||||||
View *active_view = active_panel->view;
|
View *active_view = active_panel->view;
|
||||||
|
|
||||||
// NOTE(allen): render the panels
|
// NOTE(allen): render the panels
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &models->layout.used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
i32_Rect full = panel->full;
|
i32_Rect full = panel->rect_full;
|
||||||
i32_Rect inner = panel->inner;
|
i32_Rect inner = panel->rect_inner;
|
||||||
|
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
Style *style = &models->styles.styles[0];
|
Style *style = &models->styles.styles[0];
|
||||||
|
@ -1648,7 +1505,7 @@ App_Step_Sig(app_step){
|
||||||
GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos.scroll;
|
GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos.scroll;
|
||||||
|
|
||||||
b32 active = (panel == active_panel);
|
b32 active = (panel == active_panel);
|
||||||
do_render_file_view(system, view, models, scroll_vars, active_view, panel->inner, active, target);
|
do_render_file_view(system, view, models, scroll_vars, active_view, inner, active, target);
|
||||||
|
|
||||||
u32 margin_color = 0;
|
u32 margin_color = 0;
|
||||||
if (active){
|
if (active){
|
||||||
|
@ -1677,22 +1534,21 @@ App_Step_Sig(app_step){
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(allen): get cursor type
|
// NOTE(allen): get cursor type
|
||||||
if (mouse_in_edit_area){
|
if (mouse_panel != 0 && !mouse_in_margin){
|
||||||
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
|
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
|
||||||
}
|
}
|
||||||
else if (mouse_in_margin_area){
|
else if (divider_panel != 0){
|
||||||
if (mouse_on_divider){
|
if (divider_panel->vertical_split){
|
||||||
if (mouse_divider_vertical){
|
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_LEFTRIGHT;
|
||||||
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_LEFTRIGHT;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_UPDOWN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
|
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_UPDOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
|
||||||
|
}
|
||||||
|
|
||||||
models->prev_mouse_panel = mouse_panel;
|
models->prev_mouse_panel = mouse_panel;
|
||||||
|
|
||||||
app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr;
|
app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr;
|
||||||
|
|
|
@ -70,7 +70,7 @@ fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live
|
||||||
view->cursor = vptr->transient.edit_pos.cursor;
|
view->cursor = vptr->transient.edit_pos.cursor;
|
||||||
view->preferred_x = vptr->transient.edit_pos.preferred_x;
|
view->preferred_x = vptr->transient.edit_pos.preferred_x;
|
||||||
|
|
||||||
view->view_region = vptr->transient.panel->inner;
|
view->view_region = vptr->transient.panel->rect_inner;
|
||||||
view->file_region = vptr->transient.file_region;
|
view->file_region = vptr->transient.file_region;
|
||||||
if (vptr->transient.ui_mode){
|
if (vptr->transient.ui_mode){
|
||||||
view->scroll_vars = vptr->transient.ui_scroll;
|
view->scroll_vars = vptr->transient.ui_scroll;
|
||||||
|
@ -212,7 +212,7 @@ DOC_SEE(Command_ID)
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
print_message(app,literal("WARNING: An invalid Command_ID was passed to exec_command."));
|
print_message(app, literal("WARNING: An invalid Command_ID was passed to exec_command."));
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
|
@ -367,7 +367,7 @@ DOC_SEE(Command_Line_Interface_Flag)
|
||||||
|
|
||||||
done:;
|
done:;
|
||||||
if (!result){
|
if (!result){
|
||||||
do_feedback_message(system, models, feedback_str);
|
print_message(app, feedback_str.str, feedback_str.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
end_temp_memory(temp);
|
end_temp_memory(temp);
|
||||||
|
@ -1346,23 +1346,25 @@ DOC_SEE(Buffer_Identifier)
|
||||||
file_free(system, &models->app_links, &models->mem.heap, &models->lifetime_allocator, file);
|
file_free(system, &models->app_links, &models->mem.heap, &models->lifetime_allocator, file);
|
||||||
working_set_free_file(&models->mem.heap, working_set, file);
|
working_set_free_file(&models->mem.heap, working_set, file);
|
||||||
|
|
||||||
|
Layout *layout = &models->layout;
|
||||||
|
|
||||||
Node *used = &working_set->used_sentinel;
|
Node *used = &working_set->used_sentinel;
|
||||||
Node *node = used->next;
|
Node *file_node = used->next;
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &models->layout.used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
Assert(node != used);
|
Assert(file_node != used);
|
||||||
view->transient.file_data.file = 0;
|
view->transient.file_data.file = 0;
|
||||||
Editing_File *new_file = CastFromMember(Editing_File, main_chain_node, node);
|
Editing_File *new_file = CastFromMember(Editing_File, main_chain_node, file_node);
|
||||||
view_set_file(system, models, view, new_file);
|
view_set_file(system, models, view, new_file);
|
||||||
if (node->next != used){
|
if (file_node->next != used){
|
||||||
node = node->next;
|
file_node = file_node->next;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
node = node->next->next;
|
file_node = file_node->next->next;
|
||||||
Assert(node != used);
|
Assert(file_node != used);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1407,9 +1409,10 @@ Reopen_Buffer(Application_Links *app, Buffer_Summary *buffer, Buffer_Reopen_Flag
|
||||||
View *vptrs[16];
|
View *vptrs[16];
|
||||||
i32 vptr_count = 0;
|
i32 vptr_count = 0;
|
||||||
|
|
||||||
for (Panel *panel = models->layout.used_sentinel.next;
|
Layout *layout = &models->layout;
|
||||||
panel != &models->layout.used_sentinel;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel = panel->next){
|
panel != 0;
|
||||||
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view_it = panel->view;
|
View *view_it = panel->view;
|
||||||
if (view_it->transient.file_data.file != file){
|
if (view_it->transient.file_data.file != file){
|
||||||
continue;
|
continue;
|
||||||
|
@ -1455,33 +1458,31 @@ Reopen_Buffer(Application_Links *app, Buffer_Summary *buffer, Buffer_Reopen_Flag
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
get_view_first__internal(Models *models, View_Summary *view){
|
get_view_first__internal(Models *models, View_Summary *view){
|
||||||
Editing_Layout *layout = &models->layout;
|
Panel *panel = layout_get_first_open_panel(&models->layout);
|
||||||
Panel *panel = layout->used_sentinel.next;
|
|
||||||
Assert(panel != &layout->used_sentinel);
|
|
||||||
fill_view_summary(models->system, view, panel->view, models);
|
fill_view_summary(models->system, view, panel->view, models);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
get_view_next__internal(Models *models, View_Summary *view){
|
get_view_next__internal(Models *models, View_Summary *view){
|
||||||
System_Functions *system = models->system;
|
System_Functions *system = models->system;
|
||||||
Editing_Layout *layout = &models->layout;
|
Layout *layout = &models->layout;
|
||||||
Live_Views *live_set = &models->live_set;
|
Live_Views *live_set = &models->live_set;
|
||||||
i32 index = view->view_id - 1;
|
i32 index = view->view_id - 1;
|
||||||
if (index >= 0 && index < live_set->max){
|
if (index >= 0 && index < live_set->max){
|
||||||
View *vptr = live_set->views + index;
|
View *vptr = live_set->views + index;
|
||||||
Panel *panel = vptr->transient.panel;
|
Panel *panel = vptr->transient.panel;
|
||||||
if (panel != 0){
|
if (panel != 0){
|
||||||
panel = panel->next;
|
panel = layout_get_next_open_panel(layout, panel);
|
||||||
}
|
}
|
||||||
if (panel != 0 && panel != &layout->used_sentinel){
|
if (panel != 0){
|
||||||
fill_view_summary(system, view, panel->view, models);
|
fill_view_summary(system, view, panel->view, models);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
memset(view, 0, sizeof(*view));
|
block_zero_struct(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
memset(view, 0, sizeof(*view));
|
block_zero_struct(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,12 +1565,12 @@ DOC_SEE(Access_Flag)
|
||||||
*/{
|
*/{
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
System_Functions *system = models->system;
|
System_Functions *system = models->system;
|
||||||
Panel *panel = models->layout.panels + models->layout.active_panel;
|
Panel *panel = layout_get_active_panel(&models->layout);
|
||||||
Assert(panel->view != 0);
|
Assert(panel->view != 0);
|
||||||
View_Summary view = {};
|
View_Summary view = {};
|
||||||
fill_view_summary(system, &view, panel->view, &models->live_set, &models->working_set);
|
fill_view_summary(system, &view, panel->view, &models->live_set, &models->working_set);
|
||||||
if (!access_test(view.lock_flags, access)){
|
if (!access_test(view.lock_flags, access)){
|
||||||
memset(&view, 0, sizeof(view));
|
block_zero_struct(&view);
|
||||||
}
|
}
|
||||||
return(view);
|
return(view);
|
||||||
}
|
}
|
||||||
|
@ -1586,52 +1587,20 @@ DOC_SEE(View_Split_Position)
|
||||||
*/{
|
*/{
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
System_Functions *system = models->system;
|
System_Functions *system = models->system;
|
||||||
|
Layout *layout = &models->layout;
|
||||||
View *vptr = imp_get_view(models, view_location);
|
View *vptr = imp_get_view(models, view_location);
|
||||||
Panel *panel = vptr->transient.panel;
|
Panel *panel = vptr->transient.panel;
|
||||||
View_Summary result = {};
|
View_Summary result = {};
|
||||||
|
b32 vertical_split = ((position == ViewSplit_Left) || (position == ViewSplit_Right));
|
||||||
if (models->layout.panel_count < models->layout.panel_max_count){
|
b32 br_split = ((position == ViewSplit_Bottom) || (position == ViewSplit_Right));
|
||||||
b32 vsplit = ((position == ViewSplit_Left) || (position == ViewSplit_Right));
|
Panel *new_panel = layout_split_panel(layout, panel, vertical_split, br_split);
|
||||||
b32 grtsplit = ((position == ViewSplit_Bottom) || (position == ViewSplit_Right));
|
if (new_panel != 0){
|
||||||
|
View *new_view = live_set_alloc_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set);
|
||||||
Split_Result split = layout_split_panel(&models->layout, panel, vsplit);
|
new_panel->view = new_view;
|
||||||
|
new_view->transient.panel = new_panel;
|
||||||
Panel *grtpanel = split.panel;
|
view_set_file(system, models, new_view, models->scratch_buffer);
|
||||||
Panel *lsrpanel = panel;
|
fill_view_summary(system, &result, new_view, models);
|
||||||
|
|
||||||
if (!grtsplit){
|
|
||||||
Swap(i32, panel->which_child, split.panel->which_child);
|
|
||||||
Swap(Panel*, grtpanel, lsrpanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
split.panel->screen_region = panel->screen_region;
|
|
||||||
if (vsplit){
|
|
||||||
i32 x_pos = round32(lerp((f32)lsrpanel->full.x0, split.divider->pos, (f32)lsrpanel->full.x1));
|
|
||||||
|
|
||||||
grtpanel->full.x0 = x_pos;
|
|
||||||
grtpanel->full.x1 = lsrpanel->full.x1;
|
|
||||||
lsrpanel->full.x1 = x_pos;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
i32 y_pos = round32(lerp((f32)lsrpanel->full.y0, split.divider->pos, (f32)lsrpanel->full.y1));
|
|
||||||
|
|
||||||
grtpanel->full.y0 = y_pos;
|
|
||||||
grtpanel->full.y1 = lsrpanel->full.y1;
|
|
||||||
lsrpanel->full.y1 = y_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel_fix_internal_area(panel);
|
|
||||||
panel_fix_internal_area(split.panel);
|
|
||||||
split.panel->prev_inner = split.panel->inner;
|
|
||||||
|
|
||||||
models->layout.active_panel = (i32)(split.panel - models->layout.panels);
|
|
||||||
panel_make_empty(system, models, split.panel);
|
|
||||||
|
|
||||||
fill_view_summary(system, &result, split.panel->view, models);
|
|
||||||
|
|
||||||
models->layout.panel_state_dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1648,82 +1617,17 @@ in the system, the call will fail.)
|
||||||
|
|
||||||
*/{
|
*/{
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
|
Layout *layout = &models->layout;
|
||||||
View *vptr = imp_get_view(models, view);
|
View *vptr = imp_get_view(models, view);
|
||||||
|
|
||||||
bool32 result = false;
|
bool32 result = false;
|
||||||
|
if (vptr != 0){
|
||||||
if (vptr != 0 && models->layout.panel_count > 1){
|
if (layout_close_panel(layout, vptr->transient.panel)){
|
||||||
Panel *panel = vptr->transient.panel;
|
live_set_free_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set, vptr);
|
||||||
|
result = true;
|
||||||
live_set_free_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set, vptr);
|
|
||||||
panel->view = 0;
|
|
||||||
|
|
||||||
Divider_And_ID div = layout_get_divider(&models->layout, panel->parent);
|
|
||||||
|
|
||||||
// This divider cannot have two child dividers.
|
|
||||||
Assert(div.divider->child1 == -1 || div.divider->child2 == -1);
|
|
||||||
|
|
||||||
// Get the child who needs to fill in this node's spot
|
|
||||||
i32 child = div.divider->child1;
|
|
||||||
if (child == -1) child = div.divider->child2;
|
|
||||||
|
|
||||||
i32 parent = div.divider->parent;
|
|
||||||
i32 which_child = div.divider->which_child;
|
|
||||||
|
|
||||||
// Fill the child in the slot this node use to hold
|
|
||||||
if (parent == -1){
|
|
||||||
Assert(models->layout.root == div.id);
|
|
||||||
models->layout.root = child;
|
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
Divider_And_ID parent_div = layout_get_divider(&models->layout, parent);
|
|
||||||
if (which_child == -1){
|
|
||||||
parent_div.divider->child1 = child;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
parent_div.divider->child2 = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there was a child divider, give it information about it's new parent.
|
|
||||||
if (child != -1){
|
|
||||||
Divider_And_ID child_div = layout_get_divider(&models->layout, child);
|
|
||||||
child_div.divider->parent = parent;
|
|
||||||
child_div.divider->which_child = div.divider->which_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
// What is the new active panel?
|
|
||||||
i32 active = -1;
|
|
||||||
if (child == -1){
|
|
||||||
for (Panel *panel_ptr = models->layout.used_sentinel.next;
|
|
||||||
panel_ptr != &models->layout.used_sentinel;
|
|
||||||
panel_ptr = panel_ptr->next){
|
|
||||||
if (panel_ptr != panel && panel_ptr->parent == div.id){
|
|
||||||
panel_ptr->parent = parent;
|
|
||||||
panel_ptr->which_child = which_child;
|
|
||||||
active = (i32)(panel_ptr - models->layout.panels);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
Panel *panel_ptr = panel->next;
|
|
||||||
if (panel_ptr == &models->layout.used_sentinel) panel_ptr = panel_ptr->next;
|
|
||||||
Assert(panel_ptr != panel);
|
|
||||||
active = (i32)(panel_ptr - models->layout.panels);
|
|
||||||
}
|
|
||||||
Assert(active != -1 && panel != models->layout.panels + active);
|
|
||||||
|
|
||||||
// If the panel we're closing was previously active, we have to switch to it's sibling.
|
|
||||||
if (models->layout.active_panel == (i32)(panel - models->layout.panels)){
|
|
||||||
models->layout.active_panel = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
layout_free_divider(&models->layout, div.divider);
|
|
||||||
layout_free_panel(&models->layout, panel);
|
|
||||||
layout_fix_all_panels(&models->layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1741,9 +1645,8 @@ DOC_SEE(get_active_view)
|
||||||
View *vptr = imp_get_view(models, view);
|
View *vptr = imp_get_view(models, view);
|
||||||
bool32 result = false;
|
bool32 result = false;
|
||||||
if (vptr != 0){
|
if (vptr != 0){
|
||||||
|
models->layout.active_panel = vptr->transient.panel;
|
||||||
result = true;
|
result = true;
|
||||||
Panel *panel = vptr->transient.panel;
|
|
||||||
models->layout.active_panel = (i32)(panel - models->layout.panels);
|
|
||||||
}
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -1862,31 +1765,59 @@ If the view_id does not specify a valid view, the returned scope is null.)
|
||||||
}
|
}
|
||||||
|
|
||||||
API_EXPORT bool32
|
API_EXPORT bool32
|
||||||
View_Set_Split_Proportion(Application_Links *app, View_Summary *view, float t)
|
View_Set_Split(Application_Links *app, View_Summary *view, View_Split_Kind kind, float t)
|
||||||
/*
|
/*
|
||||||
DOC_PARAM(view, The view parameter specifies which view shall have it's size adjusted.)
|
DOC_PARAM(view, The view parameter specifies which view shall have it's size adjusted.)
|
||||||
DOC_PARAM(t, The t parameter specifies the proportion of the containing box that the view should occupy. t should be in [0,1].)
|
DOC_PARAM(kind, There are different kinds of split, see View_Split_Kind documentation for more information.)
|
||||||
|
DOC_PARAM(t, The t parameter specifies the proportion of the containing box that the view should occupy.
|
||||||
|
|
||||||
|
For proportion values, t will be clamped to [0,1].
|
||||||
|
|
||||||
|
For integer values, t will be rounded to the nearest integer.
|
||||||
|
)
|
||||||
|
DOC_SEE(View_Split_Kind)
|
||||||
DOC_RETURN(This call returns non-zero on success.)
|
DOC_RETURN(This call returns non-zero on success.)
|
||||||
*/{
|
*/{
|
||||||
bool32 result = false;
|
Models *models = (Models*)app->cmd_context;
|
||||||
|
Layout *layout = &models->layout;
|
||||||
|
|
||||||
if (0 <= t && t <= 1.f){
|
View *vptr = imp_get_view(models, view);
|
||||||
Models *models = (Models*)app->cmd_context;
|
bool32 result = false;
|
||||||
Editing_Layout *layout = &models->layout;
|
if (vptr != 0){
|
||||||
View *vptr = imp_get_view(models, view);
|
Panel *panel = vptr->transient.panel;
|
||||||
|
Panel *intermediate = panel->parent;
|
||||||
if (vptr != 0){
|
if (intermediate != 0){
|
||||||
result = true;
|
Assert(intermediate->kind == PanelKind_Intermediate);
|
||||||
|
switch (kind){
|
||||||
Panel *panel = vptr->transient.panel;
|
case ViewSplitKind_Ratio:
|
||||||
Panel_Divider *div = layout->dividers + panel->parent;
|
{
|
||||||
|
if (intermediate->br_panel == panel){
|
||||||
if (panel->which_child == 1){
|
intermediate->split.kind = PanelSplitKind_Ratio_BR;
|
||||||
t = 1 - t;
|
}
|
||||||
|
else{
|
||||||
|
intermediate->split.kind = PanelSplitKind_Ratio_TL;
|
||||||
|
}
|
||||||
|
intermediate->split.v_f32 = clamp(0.f, t, 1.f);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case ViewSplitKind_FixedPixels:
|
||||||
|
{
|
||||||
|
if (intermediate->br_panel == panel){
|
||||||
|
intermediate->split.kind = PanelSplitKind_FixedPixels_BR;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
intermediate->split.kind = PanelSplitKind_FixedPixels_TL;
|
||||||
|
}
|
||||||
|
intermediate->split.v_i32 = round32(t);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
print_message(app, literal("Invalid split kind passed to view_set_split, no change made to view layout"));
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
|
layout_propogate_sizes_down_from_node(layout, intermediate);
|
||||||
div->pos = t;
|
result = true;
|
||||||
layout_fix_all_panels(layout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1899,26 +1830,22 @@ View_Get_Enclosure_Rect(Application_Links *app, View_Summary *view)
|
||||||
DOC_PARAM(view, The view whose parent rent will be returned.)
|
DOC_PARAM(view, The view whose parent rent will be returned.)
|
||||||
DOC_RETURN(The rectangle of the panel containing this view.)
|
DOC_RETURN(The rectangle of the panel containing this view.)
|
||||||
*/{
|
*/{
|
||||||
// TODO(allen): do(update implementation of layout for better queries and traversals)
|
// TODO(allen): do(remove this from the API and put it in the custom helpers)
|
||||||
|
// we should just have full tree traversal API for the splits between views.
|
||||||
i32_Rect result = {};
|
|
||||||
|
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
Editing_Layout *layout = &models->layout;
|
|
||||||
View *vptr = imp_get_view(models, view);
|
View *vptr = imp_get_view(models, view);
|
||||||
|
i32_Rect result = {};
|
||||||
if (vptr != 0){
|
if (vptr != 0){
|
||||||
Panel *panel = vptr->transient.panel;
|
Panel *panel = vptr->transient.panel;
|
||||||
|
Assert(panel != 0);
|
||||||
i32_Rect a = layout_get_rect(layout, panel->parent, panel->which_child);
|
Panel *parent = panel->parent;
|
||||||
i32_Rect b = layout_get_rect(layout, panel->parent, !panel->which_child);
|
if (parent != 0){
|
||||||
|
result = parent->rect_full;
|
||||||
result.x0 = Min(a.x0, b.x0);
|
}
|
||||||
result.y0 = Min(a.y0, b.y0);
|
else{
|
||||||
result.x1 = Max(a.x0, b.x1);
|
result = panel->rect_full;
|
||||||
result.y1 = Max(a.y0, b.y1);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3091,7 +3018,6 @@ DOC_SEE(User_Input)
|
||||||
System_Functions *system = models->system;
|
System_Functions *system = models->system;
|
||||||
Coroutine_Head *coroutine = (Coroutine_Head*)app->current_coroutine;
|
Coroutine_Head *coroutine = (Coroutine_Head*)app->current_coroutine;
|
||||||
User_Input result = {};
|
User_Input result = {};
|
||||||
|
|
||||||
if (app->type_coroutine == Co_Command){
|
if (app->type_coroutine == Co_Command){
|
||||||
Assert(coroutine != 0);
|
Assert(coroutine != 0);
|
||||||
*((u32*)coroutine->out + 0) = get_type;
|
*((u32*)coroutine->out + 0) = get_type;
|
||||||
|
@ -3099,7 +3025,6 @@ DOC_SEE(User_Input)
|
||||||
system->yield_coroutine(coroutine);
|
system->yield_coroutine(coroutine);
|
||||||
result = *(User_Input*)coroutine->in;
|
result = *(User_Input*)coroutine->in;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3182,7 +3107,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
||||||
)
|
)
|
||||||
*/{
|
*/{
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||||
View *active_view = active_panel->view;
|
View *active_view = active_panel->view;
|
||||||
Query_Slot *slot = alloc_query_slot(&active_view->transient.query_set);
|
Query_Slot *slot = alloc_query_slot(&active_view->transient.query_set);
|
||||||
bool32 result = (slot != 0);
|
bool32 result = (slot != 0);
|
||||||
|
@ -3200,7 +3125,7 @@ DOC_PARAM(flags, This parameter is not currently used and should be 0 for now.)
|
||||||
DOC(Stops showing the particular query bar specified by the bar parameter.)
|
DOC(Stops showing the particular query bar specified by the bar parameter.)
|
||||||
*/{
|
*/{
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
|
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||||
View *active_view = active_panel->view;
|
View *active_view = active_panel->view;
|
||||||
free_query_slot(&active_view->transient.query_set, bar);
|
free_query_slot(&active_view->transient.query_set, bar);
|
||||||
}
|
}
|
||||||
|
@ -3213,7 +3138,12 @@ DOC_PARAM(len, The len parameter specifies the length of the str string.)
|
||||||
DOC(This call posts a string to the *messages* buffer.)
|
DOC(This call posts a string to the *messages* buffer.)
|
||||||
*/{
|
*/{
|
||||||
Models *models = (Models*)app->cmd_context;
|
Models *models = (Models*)app->cmd_context;
|
||||||
do_feedback_message(models->system, models, make_string(str, len));
|
System_Functions *system = models->system;
|
||||||
|
Editing_File *file = models->message_buffer;
|
||||||
|
if (file != 0){
|
||||||
|
output_file_append(system, models, file, make_string(str, len));
|
||||||
|
file_cursor_to_end(system, models, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
API_EXPORT int32_t
|
API_EXPORT int32_t
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct Models{
|
||||||
Style_Library styles;
|
Style_Library styles;
|
||||||
u32 *palette;
|
u32 *palette;
|
||||||
|
|
||||||
Editing_Layout layout;
|
Layout layout;
|
||||||
Working_Set working_set;
|
Working_Set working_set;
|
||||||
Live_Views live_set;
|
Live_Views live_set;
|
||||||
Parse_Context_Memory parse_context_memory;
|
Parse_Context_Memory parse_context_memory;
|
||||||
|
@ -96,6 +96,8 @@ struct Models{
|
||||||
i32 previous_mouse_x;
|
i32 previous_mouse_x;
|
||||||
i32 previous_mouse_y;
|
i32 previous_mouse_y;
|
||||||
|
|
||||||
|
Panel *resizing_intermediate_panel;
|
||||||
|
|
||||||
// System Context
|
// System Context
|
||||||
System_Functions *system;
|
System_Functions *system;
|
||||||
struct App_Vars *vars;
|
struct App_Vars *vars;
|
||||||
|
@ -132,10 +134,6 @@ enum App_State{
|
||||||
APP_STATE_COUNT
|
APP_STATE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct App_State_Resizing{
|
|
||||||
Panel_Divider *divider;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Input_Types{
|
enum Input_Types{
|
||||||
Input_AnyKey,
|
Input_AnyKey,
|
||||||
Input_Esc,
|
Input_Esc,
|
||||||
|
@ -155,7 +153,6 @@ struct App_Vars{
|
||||||
Models models;
|
Models models;
|
||||||
CLI_List cli_processes;
|
CLI_List cli_processes;
|
||||||
App_State state;
|
App_State state;
|
||||||
App_State_Resizing resizing;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Coroutine_Type{
|
enum Coroutine_Type{
|
||||||
|
|
|
@ -92,6 +92,7 @@ typedef double f64;
|
||||||
#define TentativeAssert(c) Assert(c)
|
#define TentativeAssert(c) Assert(c)
|
||||||
#define InvalidCodePath Assert(!"Invalid Code Path!")
|
#define InvalidCodePath Assert(!"Invalid Code Path!")
|
||||||
#define NotImplemented Assert(!"Not Implemented!")
|
#define NotImplemented Assert(!"Not Implemented!")
|
||||||
|
#define AssertImplies(a,b) Assert(!(a) || (b))
|
||||||
|
|
||||||
#define Swap(t,a,b) do { t x = a; a = b; b = x; } while(0)
|
#define Swap(t,a,b) do { t x = a; a = b; b = x; } while(0)
|
||||||
|
|
||||||
|
|
28
4ed_edit.cpp
28
4ed_edit.cpp
|
@ -70,7 +70,7 @@ edit_fix_markers__read_workspace_markers(Dynamic_Workspace *workspace, Buffer_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, Editing_Layout *layout, Cursor_Fix_Descriptor desc){
|
edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, Layout *layout, Cursor_Fix_Descriptor desc){
|
||||||
Partition *part = &models->mem.part;
|
Partition *part = &models->mem.part;
|
||||||
|
|
||||||
Temp_Memory cursor_temp = begin_temp_memory(part);
|
Temp_Memory cursor_temp = begin_temp_memory(part);
|
||||||
|
@ -79,7 +79,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
|
||||||
Buffer_ID file_id = file->id.id;
|
Buffer_ID file_id = file->id.id;
|
||||||
Assert(file_lifetime_object != 0);
|
Assert(file_lifetime_object != 0);
|
||||||
|
|
||||||
i32 cursor_max = layout->panel_max_count * 3;
|
i32 cursor_max = layout_get_open_panel_count(layout)*3;
|
||||||
i32 total_marker_count = 0;
|
i32 total_marker_count = 0;
|
||||||
{
|
{
|
||||||
total_marker_count += file_lifetime_object->workspace.total_marker_count;
|
total_marker_count += file_lifetime_object->workspace.total_marker_count;
|
||||||
|
@ -106,9 +106,9 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
|
||||||
Assert(cursors != 0);
|
Assert(cursors != 0);
|
||||||
Assert(r_cursors != 0);
|
Assert(r_cursors != 0);
|
||||||
|
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &layout->used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
write_cursor_with_index(cursors, &cursor_count, view->transient.edit_pos.cursor.pos);
|
write_cursor_with_index(cursors, &cursor_count, view->transient.edit_pos.cursor.pos);
|
||||||
|
@ -148,9 +148,9 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
|
||||||
|
|
||||||
cursor_count = 0;
|
cursor_count = 0;
|
||||||
r_cursor_count = 0;
|
r_cursor_count = 0;
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &layout->used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
i32 cursor_pos = cursors[cursor_count++].pos;
|
i32 cursor_pos = cursors[cursor_count++].pos;
|
||||||
|
@ -202,7 +202,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
|
||||||
internal void
|
internal void
|
||||||
edit_single__inner(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode){
|
edit_single__inner(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode){
|
||||||
Mem_Options *mem = &models->mem;
|
Mem_Options *mem = &models->mem;
|
||||||
Editing_Layout *layout = &models->layout;
|
Layout *layout = &models->layout;
|
||||||
Heap *heap = &mem->heap;
|
Heap *heap = &mem->heap;
|
||||||
Partition *part = &mem->part;
|
Partition *part = &mem->part;
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Sp
|
||||||
Mem_Options *mem = &models->mem;
|
Mem_Options *mem = &models->mem;
|
||||||
Heap *heap = &mem->heap;
|
Heap *heap = &mem->heap;
|
||||||
Partition *part = &mem->part;
|
Partition *part = &mem->part;
|
||||||
Editing_Layout *layout = &models->layout;
|
Layout *layout = &models->layout;
|
||||||
|
|
||||||
// NOTE(allen): fixing stuff "beforewards"???
|
// NOTE(allen): fixing stuff "beforewards"???
|
||||||
Assert(spec.str == 0);
|
Assert(spec.str == 0);
|
||||||
|
@ -446,10 +446,10 @@ edit_clear(System_Functions *system, Models *models, Editing_File *file){
|
||||||
|
|
||||||
b32 no_views_see_file = true;
|
b32 no_views_see_file = true;
|
||||||
|
|
||||||
Editing_Layout *layout = &models->layout;
|
Layout *layout = &models->layout;
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &layout->used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
Full_Cursor cursor = {};
|
Full_Cursor cursor = {};
|
||||||
|
|
809
4ed_layout.cpp
809
4ed_layout.cpp
|
@ -9,468 +9,439 @@
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
internal void
|
internal Panel_Split
|
||||||
panel_init(Panel *panel){
|
make_panel_split(Panel_Split_Kind kind, i32 v){
|
||||||
panel->view = 0;
|
Panel_Split split = {};
|
||||||
panel->parent = -1;
|
split.kind = kind;
|
||||||
panel->which_child = 0;
|
split.v_i32 = v;
|
||||||
panel->screen_region.full = null_i32_rect;
|
return(split);
|
||||||
panel->screen_region.inner = null_i32_rect;
|
|
||||||
panel->l_margin = 3;
|
|
||||||
panel->r_margin = 3;
|
|
||||||
panel->t_margin = 3;
|
|
||||||
panel->b_margin = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Panel_Divider
|
internal Panel_Split
|
||||||
panel_divider_zero(){
|
make_panel_split(Panel_Split_Kind kind, f32 v){
|
||||||
Panel_Divider divider={};
|
Panel_Split split = {};
|
||||||
return(divider);
|
split.kind = kind;
|
||||||
|
split.v_f32 = v;
|
||||||
|
return(split);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Divider_And_ID
|
internal Panel_Split
|
||||||
layout_alloc_divider(Editing_Layout *layout){
|
make_panel_split_50_50(void){
|
||||||
Assert(layout->free_divider);
|
return(make_panel_split(PanelSplitKind_Ratio_TL, 0.5f));
|
||||||
|
}
|
||||||
Divider_And_ID result;
|
|
||||||
result.divider = layout->free_divider;
|
internal Panel*
|
||||||
layout->free_divider = result.divider->next;
|
layout__alloc_panel(Layout *layout){
|
||||||
|
Panel *panel = 0;
|
||||||
*result.divider = panel_divider_zero();
|
Node *node = layout->free_panels.next;
|
||||||
result.divider->parent = -1;
|
if (node != &layout->free_panels){
|
||||||
result.divider->child1 = -1;
|
dll_remove(node);
|
||||||
result.divider->child2 = -1;
|
panel = CastFromMember(Panel, node, node);
|
||||||
result.id = (i32)(result.divider - layout->dividers);
|
|
||||||
if (layout->panel_count == 1){
|
|
||||||
layout->root = result.id;
|
|
||||||
}
|
}
|
||||||
|
return(panel);
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Divider_And_ID
|
|
||||||
layout_get_divider(Editing_Layout *layout, i32 id){
|
|
||||||
Assert(id >= 0 && id < layout->panel_max_count-1);
|
|
||||||
Divider_And_ID result;
|
|
||||||
result.id = id;
|
|
||||||
result.divider = layout->dividers + id;
|
|
||||||
return(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
layout_free_divider(Editing_Layout *layout, Panel_Divider *divider){
|
layout__free_panel(Layout *layout, Panel *panel){
|
||||||
divider->next = layout->free_divider;
|
Assert(panel != layout->active_panel);
|
||||||
layout->free_divider = divider;
|
Assert(panel != layout->root);
|
||||||
}
|
dll_remove(&panel->node);
|
||||||
|
dll_insert(&layout->free_panels, &panel->node);
|
||||||
internal Panel_And_ID
|
|
||||||
layout_alloc_panel(Editing_Layout *layout){
|
|
||||||
Panel_And_ID result = {};
|
|
||||||
|
|
||||||
Assert(layout->panel_count < layout->panel_max_count);
|
|
||||||
++layout->panel_count;
|
|
||||||
|
|
||||||
result.panel = layout->free_sentinel.next;
|
|
||||||
dll_remove(result.panel);
|
|
||||||
dll_insert(&layout->used_sentinel, result.panel);
|
|
||||||
|
|
||||||
panel_init(result.panel);
|
|
||||||
|
|
||||||
result.id = (i32)(result.panel - layout->panels);
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
layout_free_panel(Editing_Layout *layout, Panel *panel){
|
layout__set_panel_rectangle(Layout *layout, Panel *panel, i32_Rect rect){
|
||||||
dll_remove(panel);
|
panel->rect_full = rect;
|
||||||
dll_insert(&layout->free_sentinel, panel);
|
panel->rect_inner = get_inner_rect(rect, layout->margin);
|
||||||
--layout->panel_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Divider_And_ID
|
internal i32
|
||||||
layout_calc_divider_id(Editing_Layout *layout, Panel_Divider *divider){
|
layout__evaluate_split(Panel_Split split, i32 v0, i32 v1){
|
||||||
Divider_And_ID result;
|
i32 v = 0;
|
||||||
result.divider = divider;
|
switch (split.kind){
|
||||||
result.id = (i32)(divider - layout->dividers);
|
case PanelSplitKind_Ratio_TL:
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Split_Result{
|
|
||||||
Panel_Divider *divider;
|
|
||||||
Panel *panel;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal Split_Result
|
|
||||||
layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){
|
|
||||||
Split_Result result = {};
|
|
||||||
Divider_And_ID div = {}, parent_div = {};
|
|
||||||
Panel_And_ID new_panel = {};
|
|
||||||
|
|
||||||
div = layout_alloc_divider(layout);
|
|
||||||
if (panel->parent != -1){
|
|
||||||
parent_div = layout_get_divider(layout, panel->parent);
|
|
||||||
if (panel->which_child == -1){
|
|
||||||
parent_div.divider->child1 = div.id;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
parent_div.divider->child2 = div.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
div.divider->parent = panel->parent;
|
|
||||||
div.divider->which_child = panel->which_child;
|
|
||||||
if (vertical){
|
|
||||||
div.divider->v_divider = 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
div.divider->v_divider = 0;
|
|
||||||
}
|
|
||||||
div.divider->pos = 0.5f;
|
|
||||||
|
|
||||||
new_panel = layout_alloc_panel(layout);
|
|
||||||
panel->parent = div.id;
|
|
||||||
panel->which_child = -1;
|
|
||||||
new_panel.panel->parent = div.id;
|
|
||||||
new_panel.panel->which_child = 1;
|
|
||||||
|
|
||||||
result.divider = div.divider;
|
|
||||||
result.panel = new_panel.panel;
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
panel_fix_internal_area(Panel *panel){
|
|
||||||
panel->inner.x0 = panel->full.x0 + panel->l_margin;
|
|
||||||
panel->inner.x1 = panel->full.x1 - panel->r_margin;
|
|
||||||
panel->inner.y0 = panel->full.y0 + panel->t_margin;
|
|
||||||
panel->inner.y1 = panel->full.y1 - panel->b_margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal i32_Rect
|
|
||||||
layout_get_rect(Editing_Layout *layout, i32 id, i32 which_child){
|
|
||||||
i32 divider_chain[MAX_VIEWS];
|
|
||||||
i32 chain_count = 0;
|
|
||||||
|
|
||||||
Panel_Divider *dividers = layout->dividers;
|
|
||||||
Panel_Divider *original_div = dividers + id;
|
|
||||||
i32 root = layout->root;
|
|
||||||
|
|
||||||
Assert(0 <= id && id <= layout->panel_max_count - 1);
|
|
||||||
|
|
||||||
divider_chain[chain_count++] = id;
|
|
||||||
for (;id != root;){
|
|
||||||
Panel_Divider *div = dividers + id;
|
|
||||||
id = div->parent;
|
|
||||||
divider_chain[chain_count++] = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32_Rect r = i32R(0, 0, layout->full_width, layout->full_height);
|
|
||||||
|
|
||||||
for (i32 i = chain_count-1; i > 0; --i){
|
|
||||||
Panel_Divider *div = dividers + divider_chain[i];
|
|
||||||
if (div->v_divider){
|
|
||||||
if (div->child1 == divider_chain[i-1]){
|
|
||||||
r.x1 = round32(lerp((f32)r.x0, div->pos, (f32)r.x1));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
r.x0 = round32(lerp((f32)r.x0, div->pos, (f32)r.x1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (div->child1 == divider_chain[i-1]){
|
|
||||||
r.y1 = round32(lerp((f32)r.y0, div->pos, (f32)r.y1));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
r.y0 = round32(lerp((f32)r.y0, div->pos, (f32)r.y1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (which_child){
|
|
||||||
case 1:
|
|
||||||
{
|
{
|
||||||
if (original_div->v_divider){
|
v = round32(lerp((f32)v0, split.v_f32, (f32)v1));
|
||||||
r.x0 = round32(lerp((f32)r.x0, original_div->pos, (f32)r.x1));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
r.y0 = round32(lerp((f32)r.y0, original_div->pos, (f32)r.y1));
|
|
||||||
}
|
|
||||||
}break;
|
}break;
|
||||||
|
case PanelSplitKind_Ratio_BR:
|
||||||
|
{
|
||||||
|
v = round32(lerp((f32)v1, split.v_f32, (f32)v0));
|
||||||
|
}break;
|
||||||
|
case PanelSplitKind_FixedPixels_TL:
|
||||||
|
{
|
||||||
|
v = clamp_top(v0 + split.v_i32, v1);
|
||||||
|
}break;
|
||||||
|
case PanelSplitKind_FixedPixels_BR:
|
||||||
|
{
|
||||||
|
v = clamp_bottom(v0, v1 - split.v_i32);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
return(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
layout_propogate_sizes_down_from_node(Layout *layout, Panel *panel){
|
||||||
|
if (panel->kind == PanelKind_Intermediate){
|
||||||
|
Panel *tl_panel = panel->tl_panel;
|
||||||
|
Panel *br_panel = panel->br_panel;
|
||||||
|
|
||||||
case -1:
|
i32_Rect r1 = panel->rect_full;
|
||||||
{
|
i32_Rect r2 = panel->rect_full;
|
||||||
if (original_div->v_divider){
|
|
||||||
r.x1 = round32(lerp((f32)r.x0, original_div->pos, (f32)r.x1));
|
if (panel->vertical_split){
|
||||||
}
|
i32 x_pos = layout__evaluate_split(panel->split, r1.x0, r1.x1);
|
||||||
else{
|
r1.x1 = x_pos;
|
||||||
r.y1 = round32(lerp((f32)r.y0, original_div->pos, (f32)r.y1));
|
r2.x0 = x_pos;
|
||||||
}
|
}
|
||||||
}break;
|
else{
|
||||||
|
i32 y_pos = layout__evaluate_split(panel->split, r1.y0, r1.y1);
|
||||||
|
r1.y1 = y_pos;
|
||||||
|
r2.y0 = y_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout__set_panel_rectangle(layout, tl_panel, r1);
|
||||||
|
layout__set_panel_rectangle(layout, br_panel, r2);
|
||||||
|
|
||||||
|
layout_propogate_sizes_down_from_node(layout, tl_panel);
|
||||||
|
layout_propogate_sizes_down_from_node(layout, br_panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal i32_Rect
|
internal i32
|
||||||
layout_get_panel_rect(Editing_Layout *layout, Panel *panel){
|
layout_get_open_panel_count(Layout *layout){
|
||||||
Assert(layout->panel_count > 1);
|
return(layout->open_panel_count);
|
||||||
i32_Rect r = layout_get_rect(layout, panel->parent, panel->which_child);
|
}
|
||||||
return(r);
|
|
||||||
|
internal Panel*
|
||||||
|
layout_get_first_open_panel(Layout *layout){
|
||||||
|
Panel *panel = CastFromMember(Panel, node, layout->open_panels.next);
|
||||||
|
if (panel != 0 && &panel->node == &layout->open_panels){
|
||||||
|
panel = 0;
|
||||||
|
}
|
||||||
|
AssertImplies(panel != 0, panel->kind == PanelKind_Final);
|
||||||
|
return(panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Panel*
|
||||||
|
layout_get_next_open_panel(Layout *layout, Panel *panel){
|
||||||
|
panel = CastFromMember(Panel, node, panel->node.next);
|
||||||
|
if (&panel->node == &layout->open_panels){
|
||||||
|
panel = 0;
|
||||||
|
}
|
||||||
|
AssertImplies(panel != 0, panel->kind == PanelKind_Final);
|
||||||
|
return(panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Panel*
|
||||||
|
layout_get_active_panel(Layout *layout){
|
||||||
|
return(layout->active_panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Panel*
|
||||||
|
layout_split_panel(Layout *layout, Panel *panel, b32 vertical_split, b32 br_split){
|
||||||
|
Panel *new_panel = 0;
|
||||||
|
if (layout->open_panel_count < layout->open_panel_max_count){
|
||||||
|
Panel *intermediate = layout__alloc_panel(layout);
|
||||||
|
new_panel = layout__alloc_panel(layout);
|
||||||
|
|
||||||
|
dll_insert(&layout->open_panels, &new_panel->node);
|
||||||
|
dll_insert(&layout->intermediate_panels, &intermediate->node);
|
||||||
|
|
||||||
|
Panel *parent = panel->parent;
|
||||||
|
|
||||||
|
// link new intermediate and parent
|
||||||
|
intermediate->parent = parent;
|
||||||
|
if (parent != 0){
|
||||||
|
Assert(parent->kind == PanelKind_Intermediate);
|
||||||
|
if (parent->tl_panel == panel){
|
||||||
|
parent->tl_panel = intermediate;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Assert(parent->br_panel == panel);
|
||||||
|
parent->br_panel = intermediate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Assert(layout->root == panel);
|
||||||
|
layout->root = intermediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// link new intermediate and child panels
|
||||||
|
panel->parent = intermediate;
|
||||||
|
new_panel->parent = intermediate;
|
||||||
|
if (br_split){
|
||||||
|
intermediate->br_panel = new_panel;
|
||||||
|
intermediate->tl_panel = panel;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
intermediate->tl_panel = new_panel;
|
||||||
|
intermediate->br_panel = panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init the intermediate
|
||||||
|
intermediate->kind = PanelKind_Intermediate;
|
||||||
|
intermediate->vertical_split = vertical_split;
|
||||||
|
intermediate->split = make_panel_split_50_50();
|
||||||
|
intermediate->screen_region = panel->screen_region;
|
||||||
|
|
||||||
|
// init the new panel
|
||||||
|
new_panel->kind = PanelKind_Final;
|
||||||
|
new_panel->view = 0;
|
||||||
|
|
||||||
|
// propogate rectangle sizes down from the new intermediate to
|
||||||
|
// resize the panel and the new panel.
|
||||||
|
layout_propogate_sizes_down_from_node(layout, intermediate);
|
||||||
|
|
||||||
|
// update layout state
|
||||||
|
layout->open_panel_count += 1;
|
||||||
|
layout->active_panel = new_panel;
|
||||||
|
layout->panel_state_dirty = true;
|
||||||
|
}
|
||||||
|
return(new_panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
layout_close_panel(Layout *layout, Panel *panel){
|
||||||
|
b32 result = false;
|
||||||
|
if (layout->open_panel_count > 1){
|
||||||
|
Panel *parent = panel->parent;
|
||||||
|
Assert(parent != 0);
|
||||||
|
|
||||||
|
// find sibling
|
||||||
|
Panel *sibling = 0;
|
||||||
|
if (parent->tl_panel == panel){
|
||||||
|
sibling = parent->br_panel;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Assert(parent->br_panel == panel);
|
||||||
|
sibling = parent->tl_panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update layout state
|
||||||
|
if (layout->active_panel == panel){
|
||||||
|
Panel *new_active = sibling;
|
||||||
|
for (;new_active->kind == PanelKind_Intermediate;){
|
||||||
|
new_active = new_active->br_panel;
|
||||||
|
}
|
||||||
|
layout->active_panel = new_active;
|
||||||
|
}
|
||||||
|
layout->panel_state_dirty = true;
|
||||||
|
layout->open_panel_count -= 1;
|
||||||
|
|
||||||
|
// link grand parent and sibling
|
||||||
|
Panel *g_parent = parent->parent;
|
||||||
|
sibling->parent = g_parent;
|
||||||
|
if (g_parent != 0){
|
||||||
|
if (g_parent->tl_panel == parent){
|
||||||
|
g_parent->tl_panel = sibling;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Assert(g_parent->br_panel == parent);
|
||||||
|
g_parent->br_panel = sibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Assert(parent == layout->root);
|
||||||
|
layout->root = sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set sibling's size
|
||||||
|
sibling->screen_region = parent->screen_region;
|
||||||
|
|
||||||
|
// set the sizes down stream of sibling
|
||||||
|
layout_propogate_sizes_down_from_node(layout, sibling);
|
||||||
|
|
||||||
|
// free panel and parent
|
||||||
|
layout__free_panel(layout, panel);
|
||||||
|
layout__free_panel(layout, parent);
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Panel*
|
||||||
|
layout_initialize(Partition *part, Layout *layout){
|
||||||
|
i32 panel_alloc_count = MAX_VIEWS*2 - 1;
|
||||||
|
Panel *panels = push_array(part, Panel, panel_alloc_count);
|
||||||
|
|
||||||
|
layout->margin = 3;
|
||||||
|
layout->open_panel_count = 0;
|
||||||
|
layout->open_panel_max_count = MAX_VIEWS;
|
||||||
|
|
||||||
|
dll_init_sentinel(&layout->open_panels);
|
||||||
|
dll_init_sentinel(&layout->intermediate_panels);
|
||||||
|
|
||||||
|
Panel *panel = panels;
|
||||||
|
layout->free_panels.next = &panel->node;
|
||||||
|
panel->node.prev = &layout->free_panels;
|
||||||
|
for (i32 i = 1; i < MAX_VIEWS; i += 1, panel += 1){
|
||||||
|
panel[1].node.prev = &panel[0].node;
|
||||||
|
panel[0].node.next = &panel[1].node;
|
||||||
|
}
|
||||||
|
panel->node.next = &layout->free_panels;
|
||||||
|
layout->free_panels.prev = &panel->node;
|
||||||
|
|
||||||
|
panel = layout__alloc_panel(layout);
|
||||||
|
panel->parent = 0;
|
||||||
|
panel->kind = PanelKind_Final;
|
||||||
|
panel->view = 0;
|
||||||
|
block_zero_struct(&panel->screen_region);
|
||||||
|
|
||||||
|
dll_insert(&layout->open_panels, &panel->node);
|
||||||
|
layout->open_panel_count += 1;
|
||||||
|
layout->root = panel;
|
||||||
|
layout->active_panel = panel;
|
||||||
|
layout->panel_state_dirty = true;
|
||||||
|
|
||||||
|
return(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
layout_fix_all_panels(Editing_Layout *layout){
|
layout_set_margin(Layout *layout, i32 margin){
|
||||||
Panel_Divider *dividers = layout->dividers; AllowLocal(dividers);
|
if (layout->margin != margin){
|
||||||
i32 panel_count = layout->panel_count;
|
layout->margin = margin;
|
||||||
|
layout__set_panel_rectangle(layout, layout->root, i32R(0, 0, layout->full_dim.x, layout->full_dim.y));
|
||||||
if (panel_count > 1){
|
layout_propogate_sizes_down_from_node(layout, layout->root);
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
|
||||||
panel != &layout->used_sentinel;
|
|
||||||
panel = panel->next){
|
|
||||||
panel->full = layout_get_panel_rect(layout, panel);
|
|
||||||
panel_fix_internal_area(panel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
Panel *panel = layout->used_sentinel.next;
|
|
||||||
panel->full.x0 = 0;
|
|
||||||
panel->full.y0 = 0;
|
|
||||||
panel->full.x1 = layout->full_width;
|
|
||||||
panel->full.y1 = layout->full_height;
|
|
||||||
panel_fix_internal_area(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
layout->panel_state_dirty = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
layout_refit(Editing_Layout *layout, i32 prev_width, i32 prev_height){
|
layout_set_root_size(Layout *layout, Vec2_i32 dim){
|
||||||
Panel_Divider *dividers = layout->dividers;
|
if (layout->full_dim != dim){
|
||||||
i32 max = layout->panel_max_count - 1;
|
layout->full_dim = dim;
|
||||||
|
layout__set_panel_rectangle(layout, layout->root, i32R(0, 0, dim.x, dim.y));
|
||||||
Panel_Divider *divider = dividers;
|
layout_propogate_sizes_down_from_node(layout, layout->root);
|
||||||
if (layout->panel_count > 1){
|
|
||||||
Assert(prev_width != 0 && prev_height != 0);
|
|
||||||
for (i32 i = 0; i < max; ++i, ++divider){
|
|
||||||
// TODO(casey): Allen, is this doing something? Is it just reserved for future use I guess?
|
|
||||||
if (divider->v_divider){
|
|
||||||
divider->pos = divider->pos;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
divider->pos = divider->pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layout_fix_all_panels(layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal f32
|
internal Vec2_i32
|
||||||
layout_get_position(Editing_Layout *layout, i32 id){
|
layout_get_root_size(Layout *layout){
|
||||||
Panel_Divider *dividers = layout->dividers;
|
return(layout->full_dim);
|
||||||
Panel_Divider *original_div = dividers + id;
|
}
|
||||||
|
|
||||||
i32_Rect r = layout_get_rect(layout, id, 0);
|
internal i32
|
||||||
f32 pos = 0;
|
layout_get_absolute_position_of_split(Panel *panel){
|
||||||
if (original_div->v_divider){
|
i32 pos = 0;
|
||||||
pos = lerp((f32)r.x0, original_div->pos, (f32)r.x1);
|
if (panel->vertical_split){
|
||||||
|
pos = layout__evaluate_split(panel->split, panel->rect_full.x0, panel->rect_full.x1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
pos = lerp((f32)r.y0, original_div->pos, (f32)r.y1);
|
pos = layout__evaluate_split(panel->split, panel->rect_full.y0, panel->rect_full.y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(pos);
|
return(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal f32
|
internal Range
|
||||||
layout_compute_position(Editing_Layout *layout, Panel_Divider *divider, i32 pos){
|
layout__get_limiting_range_on_split_children(i32 mid, b32 vertical_split, Panel *panel, Range range){
|
||||||
Panel_Divider *dividers = layout->dividers;
|
if (panel->kind == PanelKind_Intermediate){
|
||||||
Panel_Divider *original_div = divider;
|
if (vertical_split == panel->vertical_split){
|
||||||
i32 id = (i32)(divider - dividers);
|
i32 pos = layout_get_absolute_position_of_split(panel);
|
||||||
|
if (mid < pos && pos < range.max){
|
||||||
i32_Rect r = layout_get_rect(layout, id, 0);
|
range.max = pos;
|
||||||
f32 l = 0;
|
|
||||||
if (original_div->v_divider){
|
|
||||||
l = unlerp((f32)r.x0, (f32)pos, (f32)r.x1);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
l = unlerp((f32)r.y0, (f32)pos, (f32)r.y1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(0.f <= l && l <= 1.f);
|
|
||||||
|
|
||||||
return(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
layout_compute_abs_step(Editing_Layout *layout, i32 divider_id, i32_Rect rect, i32 *abs_pos){
|
|
||||||
Panel_Divider *div = layout->dividers + divider_id;
|
|
||||||
|
|
||||||
i32 p0 = 0, p1 = 0;
|
|
||||||
if (div->v_divider){
|
|
||||||
p0 = rect.x0; p1 = rect.x1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
p0 = rect.y0; p1 = rect.y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 pos = lerp(p0, div->pos, p1);
|
|
||||||
i32_Rect r1 = rect, r2 = rect;
|
|
||||||
|
|
||||||
abs_pos[divider_id] = pos;
|
|
||||||
|
|
||||||
if (div->v_divider){
|
|
||||||
r1.x1 = pos; r2.x0 = pos;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
r1.y1 = pos; r2.y0 = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (div->child1 != -1){
|
|
||||||
layout_compute_abs_step(layout, div->child1, r1, abs_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (div->child2 != -1){
|
|
||||||
layout_compute_abs_step(layout, div->child2, r2, abs_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
layout_compute_absolute_positions(Editing_Layout *layout, i32 *abs_pos){
|
|
||||||
i32_Rect r = i32R(0, 0, layout->full_width, layout->full_height);
|
|
||||||
if (layout->panel_count > 1){
|
|
||||||
layout_compute_abs_step(layout, layout->root, r, abs_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
layout_get_min_max_step_up(Editing_Layout *layout, b32 v, i32 divider_id, i32 which_child,
|
|
||||||
i32 *abs_pos, i32 *min_out, i32 *max_out){
|
|
||||||
Panel_Divider *divider = layout->dividers + divider_id;
|
|
||||||
|
|
||||||
if (divider->v_divider == v){
|
|
||||||
if (which_child == -1){
|
|
||||||
if (*max_out > abs_pos[divider_id]){
|
|
||||||
*max_out = abs_pos[divider_id];
|
|
||||||
}
|
}
|
||||||
|
else if (range.min < pos && pos < mid){
|
||||||
|
range.min = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
range = layout__get_limiting_range_on_split_children(mid, vertical_split, panel->tl_panel, range);
|
||||||
|
range = layout__get_limiting_range_on_split_children(mid, vertical_split, panel->br_panel, range);
|
||||||
|
}
|
||||||
|
return(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Range
|
||||||
|
layout_get_limiting_range_on_split(Layout *layout, Panel *panel){
|
||||||
|
// root level min max
|
||||||
|
Range range = {};
|
||||||
|
if (panel->vertical_split){
|
||||||
|
range.max = layout->full_dim.x;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
range.max = layout->full_dim.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get mid
|
||||||
|
i32 mid = layout_get_absolute_position_of_split(panel);
|
||||||
|
|
||||||
|
// parents min max
|
||||||
|
for (Panel *panel_it = panel;
|
||||||
|
panel_it != 0;
|
||||||
|
panel_it = panel_it->parent){
|
||||||
|
if (panel->vertical_split == panel_it->vertical_split){
|
||||||
|
i32 pos = layout_get_absolute_position_of_split(panel_it);
|
||||||
|
if (mid < pos && pos < range.max){
|
||||||
|
range.max = pos;
|
||||||
|
}
|
||||||
|
else if (range.min < pos && pos < mid){
|
||||||
|
range.min = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// children min max
|
||||||
|
if (panel->kind == PanelKind_Intermediate){
|
||||||
|
range = layout__get_limiting_range_on_split_children(mid, panel->vertical_split, panel->tl_panel, range);
|
||||||
|
range = layout__get_limiting_range_on_split_children(mid, panel->vertical_split, panel->br_panel, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
layout__reverse_evaluate_panel_split(Panel *panel, i32 position){
|
||||||
|
i32 v0 = 0;
|
||||||
|
i32 v1 = 0;
|
||||||
|
if (panel->vertical_split){
|
||||||
|
v0 = panel->rect_full.x0;
|
||||||
|
v1 = panel->rect_full.x1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
v0 = panel->rect_full.y0;
|
||||||
|
v1 = panel->rect_full.y1;
|
||||||
|
}
|
||||||
|
switch (panel->split.kind){
|
||||||
|
case PanelSplitKind_Ratio_TL:
|
||||||
|
{
|
||||||
|
panel->split.v_f32 = unlerp((f32)v0, (f32)position, (f32)v1);
|
||||||
|
}break;
|
||||||
|
case PanelSplitKind_Ratio_BR:
|
||||||
|
{
|
||||||
|
panel->split.v_f32 = unlerp((f32)v1, (f32)position, (f32)v0);
|
||||||
|
}break;
|
||||||
|
case PanelSplitKind_FixedPixels_TL:
|
||||||
|
{
|
||||||
|
panel->split.v_i32 = clamp(v0, position, v1) - v0;
|
||||||
|
}break;
|
||||||
|
case PanelSplitKind_FixedPixels_BR:
|
||||||
|
{
|
||||||
|
panel->split.v_i32 = v1 - clamp(v0, position, v1);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
layout__set_split_absolute_position_inner(Panel *panel){
|
||||||
|
if (panel->kind == PanelKind_Intermediate){
|
||||||
|
i32_Rect r = panel->rect_full;
|
||||||
|
i32 position = 0;
|
||||||
|
if (panel->vertical_split){
|
||||||
|
position = layout__evaluate_split(panel->split, r.x0, r.x1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (*min_out < abs_pos[divider_id]){
|
position = layout__evaluate_split(panel->split, r.y0, r.y1);
|
||||||
*min_out = abs_pos[divider_id];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
layout__reverse_evaluate_panel_split(panel, position);
|
||||||
|
|
||||||
if (divider->parent != -1){
|
|
||||||
layout_get_min_max_step_up(layout, v, divider->parent, divider->which_child, abs_pos, min_out, max_out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
layout_get_min_max_step_down(Editing_Layout *layout, b32 v, i32 divider_id, i32 which_child, i32 *abs_pos, i32 *min_out, i32 *max_out){
|
layout_set_split_absolute_position(Layout *layout, Panel *panel, i32 absolute_position){
|
||||||
Panel_Divider *divider = layout->dividers + divider_id;
|
if (panel->kind == PanelKind_Intermediate){
|
||||||
|
layout__reverse_evaluate_panel_split(panel, absolute_position);
|
||||||
// NOTE(allen): The min/max is switched here, because children on the -1 side
|
layout__set_split_absolute_position_inner(panel->tl_panel);
|
||||||
// effect min, while if you are on the -1 side your parent effects max.
|
layout__set_split_absolute_position_inner(panel->br_panel);
|
||||||
if (divider->v_divider == v){
|
layout_propogate_sizes_down_from_node(layout, panel);
|
||||||
if (which_child == -1){
|
|
||||||
if (*min_out < abs_pos[divider_id]){
|
|
||||||
*min_out = abs_pos[divider_id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (*max_out > abs_pos[divider_id]){
|
|
||||||
*max_out = abs_pos[divider_id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (divider->child1 != -1){
|
|
||||||
layout_get_min_max_step_down(layout, v, divider->child1, which_child,
|
|
||||||
abs_pos, min_out, max_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (divider->child2 != -1){
|
|
||||||
layout_get_min_max_step_down(layout, v, divider->child2, which_child,
|
|
||||||
abs_pos, min_out, max_out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
layout_get_min_max(Editing_Layout *layout, Panel_Divider *divider, i32 *abs_pos, i32 *min_out, i32 *max_out){
|
|
||||||
*min_out = 0;
|
|
||||||
*max_out = max_i32;
|
|
||||||
|
|
||||||
if (layout->panel_count > 1){
|
|
||||||
if (divider->parent != -1){
|
|
||||||
layout_get_min_max_step_up(layout, divider->v_divider, divider->parent, divider->which_child,
|
|
||||||
abs_pos, min_out, max_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (divider->child1 != -1){
|
|
||||||
layout_get_min_max_step_down(layout, divider->v_divider, divider->child1, -1,
|
|
||||||
abs_pos, min_out, max_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (divider->child2 != -1){
|
|
||||||
layout_get_min_max_step_down(layout, divider->v_divider, divider->child2, 1,
|
|
||||||
abs_pos, min_out, max_out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (divider->v_divider){
|
|
||||||
*max_out = layout->full_width;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
*max_out = layout->full_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
layout_update_pos_step(Editing_Layout *layout, i32 divider_id, i32_Rect rect, i32 *abs_pos){
|
|
||||||
Panel_Divider *div = layout->dividers + divider_id;
|
|
||||||
|
|
||||||
i32 p0 = 0, p1 = 0;
|
|
||||||
if (div->v_divider){
|
|
||||||
p0 = rect.x0; p1 = rect.x1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
p0 = rect.y0; p1 = rect.y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 pos = abs_pos[divider_id];
|
|
||||||
i32_Rect r1 = rect, r2 = rect;
|
|
||||||
f32 lpos = unlerp((f32)p0, (f32)pos, (f32)p1);
|
|
||||||
lpos = clamp(0.f, lpos, 1.f);
|
|
||||||
|
|
||||||
div->pos = lpos;
|
|
||||||
|
|
||||||
if (div->v_divider){
|
|
||||||
pos = clamp(r1.x0, pos, r2.x1);
|
|
||||||
r1.x1 = pos; r2.x0 = pos;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
pos = clamp(r1.y0, pos, r2.y1);
|
|
||||||
r1.y1 = pos; r2.y0 = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (div->child1 != -1){
|
|
||||||
layout_update_pos_step(layout, div->child1, r1, abs_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (div->child2 != -1){
|
|
||||||
layout_update_pos_step(layout, div->child2, r2, abs_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
layout_update_all_positions(Editing_Layout *layout, i32 *abs_pos){
|
|
||||||
i32_Rect r = i32R(0, 0, layout->full_width, layout->full_height);
|
|
||||||
if (layout->panel_count > 1){
|
|
||||||
layout_update_pos_step(layout, layout->root, r, abs_pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
105
4ed_layout.h
105
4ed_layout.h
|
@ -12,65 +12,70 @@
|
||||||
#if !defined(FRED_LAYOUT_H)
|
#if !defined(FRED_LAYOUT_H)
|
||||||
#define FRED_LAYOUT_H
|
#define FRED_LAYOUT_H
|
||||||
|
|
||||||
struct Panel_Divider{
|
typedef i32 Panel_Split_Kind;
|
||||||
Panel_Divider *next;
|
enum{
|
||||||
i32 parent;
|
PanelSplitKind_Ratio_TL = 0,
|
||||||
i32 which_child;
|
PanelSplitKind_Ratio_BR = 1,
|
||||||
i32 child1, child2;
|
PanelSplitKind_FixedPixels_TL = 2,
|
||||||
b32 v_divider;
|
PanelSplitKind_FixedPixels_BR = 3,
|
||||||
f32 pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Screen_Region{
|
struct Panel_Split{
|
||||||
i32_Rect full;
|
Panel_Split_Kind kind;
|
||||||
i32_Rect inner;
|
|
||||||
i32 l_margin, r_margin;
|
|
||||||
i32 t_margin, b_margin;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Panel{
|
|
||||||
Panel *next;
|
|
||||||
Panel *prev;
|
|
||||||
|
|
||||||
struct View *view;
|
|
||||||
i32 parent;
|
|
||||||
i32 which_child;
|
|
||||||
|
|
||||||
union{
|
union{
|
||||||
struct{
|
f32 v_f32;
|
||||||
i32_Rect full;
|
i32 v_i32;
|
||||||
i32_Rect inner;
|
|
||||||
i32_Rect prev_inner;
|
|
||||||
i32 l_margin, r_margin;
|
|
||||||
i32 t_margin, b_margin;
|
|
||||||
};
|
|
||||||
Screen_Region screen_region;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Editing_Layout{
|
typedef i32 Panel_Kind;
|
||||||
Panel *panels;
|
enum{
|
||||||
Panel free_sentinel;
|
PanelKind_Intermediate = 0,
|
||||||
Panel used_sentinel;
|
PanelKind_Final = 1,
|
||||||
Panel_Divider *dividers;
|
};
|
||||||
Panel_Divider *free_divider;
|
|
||||||
i32 panel_count, panel_max_count;
|
struct Panel{
|
||||||
i32 root;
|
Node node;
|
||||||
i32 active_panel;
|
|
||||||
i32 full_width, full_height;
|
Panel *parent;
|
||||||
|
Panel_Kind kind;
|
||||||
|
union{
|
||||||
|
struct View *view;
|
||||||
|
struct{
|
||||||
|
struct Panel *tl_panel;
|
||||||
|
struct Panel *br_panel;
|
||||||
|
b32 vertical_split;
|
||||||
|
Panel_Split split;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
union{
|
||||||
|
struct{
|
||||||
|
i32_Rect rect_full;
|
||||||
|
i32_Rect rect_inner;
|
||||||
|
} screen_region;
|
||||||
|
struct{
|
||||||
|
i32_Rect rect_full;
|
||||||
|
i32_Rect rect_inner;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Layout{
|
||||||
|
Node free_panels;
|
||||||
|
Node open_panels;
|
||||||
|
Node intermediate_panels;
|
||||||
|
|
||||||
|
Panel *root;
|
||||||
|
Panel *active_panel;
|
||||||
|
|
||||||
|
i32 margin;
|
||||||
|
i32 open_panel_count;
|
||||||
|
i32 open_panel_max_count;
|
||||||
|
Vec2_i32 full_dim;
|
||||||
b32 panel_state_dirty;
|
b32 panel_state_dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Divider_And_ID{
|
|
||||||
Panel_Divider* divider;
|
|
||||||
i32 id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Panel_And_ID{
|
|
||||||
Panel* panel;
|
|
||||||
i32 id;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
184
4ed_math.h
184
4ed_math.h
|
@ -95,7 +95,6 @@ struct Vec4{
|
||||||
struct{
|
struct{
|
||||||
f32 r, g, b, a;
|
f32 r, g, b, a;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
f32 h, s, l, __a;
|
f32 h, s, l, __a;
|
||||||
};
|
};
|
||||||
|
@ -120,31 +119,120 @@ struct Vec4{
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Vec2_i32{
|
||||||
|
union{
|
||||||
|
struct{
|
||||||
|
i32 x, y;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 v[2];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vec3_i32{
|
||||||
|
union{
|
||||||
|
struct{
|
||||||
|
i32 x, y, z;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 r, g, b;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
Vec2 xy;
|
||||||
|
i32 _z;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 _x;
|
||||||
|
Vec2 yz;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 v[3];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vec4_i32{
|
||||||
|
union{
|
||||||
|
struct{
|
||||||
|
i32 r, g, b, a;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 h, s, l, __a;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 x, y, z, w;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
Vec3 rgb;
|
||||||
|
i32 _a;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
Vec3 xyz;
|
||||||
|
i32 _w;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 _x;
|
||||||
|
Vec3 yzw;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 v[4];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
internal Vec2
|
internal Vec2
|
||||||
V2(f32 x, f32 y){
|
V2(f32 x, f32 y){
|
||||||
Vec2 result;
|
Vec2 result = {};
|
||||||
result.x = x;
|
result.x = x;
|
||||||
result.y = y;
|
result.y = y;
|
||||||
return result;
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Vec3
|
internal Vec3
|
||||||
V3(f32 x, f32 y, f32 z){
|
V3(f32 x, f32 y, f32 z){
|
||||||
Vec3 result;
|
Vec3 result = {};
|
||||||
result.x = x;
|
result.x = x;
|
||||||
result.y = y;
|
result.y = y;
|
||||||
result.z = z;
|
result.z = z;
|
||||||
return result;
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Vec4
|
internal Vec4
|
||||||
V4(f32 x, f32 y, f32 z, f32 w){
|
V4(f32 x, f32 y, f32 z, f32 w){
|
||||||
Vec4 result;
|
Vec4 result = {};
|
||||||
result.x = x;
|
result.x = x;
|
||||||
result.y = y;
|
result.y = y;
|
||||||
result.z = z;
|
result.z = z;
|
||||||
result.w = w;
|
result.w = w;
|
||||||
return result;
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Vec2_i32
|
||||||
|
V2(i32 x, i32 y){
|
||||||
|
Vec2_i32 result = {};
|
||||||
|
result.x = x;
|
||||||
|
result.y = y;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Vec3_i32
|
||||||
|
V3(i32 x, i32 y, i32 z){
|
||||||
|
Vec3_i32 result = {};
|
||||||
|
result.x = x;
|
||||||
|
result.y = y;
|
||||||
|
result.z = z;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Vec4_i32
|
||||||
|
V4(i32 x, i32 y, i32 z, i32 w){
|
||||||
|
Vec4_i32 result = {};
|
||||||
|
result.x = x;
|
||||||
|
result.y = y;
|
||||||
|
result.z = z;
|
||||||
|
result.w = w;
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Vec2
|
internal Vec2
|
||||||
|
@ -152,7 +240,7 @@ operator+(Vec2 a, Vec2 b){
|
||||||
Vec2 result;
|
Vec2 result;
|
||||||
result.x = a.x + b.x;
|
result.x = a.x + b.x;
|
||||||
result.y = a.y + b.y;
|
result.y = a.y + b.y;
|
||||||
return(a + b);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Vec3
|
internal Vec3
|
||||||
|
@ -161,7 +249,7 @@ operator+(Vec3 a, Vec3 b){
|
||||||
result.x = a.x + b.x;
|
result.x = a.x + b.x;
|
||||||
result.y = a.y + b.y;
|
result.y = a.y + b.y;
|
||||||
result.z = a.z + b.z;
|
result.z = a.z + b.z;
|
||||||
return(a + b);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Vec4
|
internal Vec4
|
||||||
|
@ -171,7 +259,7 @@ operator+(Vec4 a, Vec4 b){
|
||||||
result.y = a.y + b.y;
|
result.y = a.y + b.y;
|
||||||
result.z = a.z + b.z;
|
result.z = a.z + b.z;
|
||||||
result.w = a.w + b.w;
|
result.w = a.w + b.w;
|
||||||
return(a + b);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Vec2
|
internal Vec2
|
||||||
|
@ -308,6 +396,66 @@ operator*=(Vec4 &a, f32 k){
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator==(Vec2 a, Vec2 b){
|
||||||
|
return(a.x == b.x && a.y == b.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator!=(Vec2 a, Vec2 b){
|
||||||
|
return(!(a.x == b.x && a.y == b.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator==(Vec3 a, Vec3 b){
|
||||||
|
return(a.x == b.x && a.y == b.y && a.z == b.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator!=(Vec3 a, Vec3 b){
|
||||||
|
return(!(a.x == b.x && a.y == b.y && a.z == b.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator==(Vec4 a, Vec4 b){
|
||||||
|
return(a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator!=(Vec4 a, Vec4 b){
|
||||||
|
return(!(a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator==(Vec2_i32 a, Vec2_i32 b){
|
||||||
|
return(a.x == b.x && a.y == b.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator!=(Vec2_i32 a, Vec2_i32 b){
|
||||||
|
return(!(a.x == b.x && a.y == b.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator==(Vec3_i32 a, Vec3_i32 b){
|
||||||
|
return(a.x == b.x && a.y == b.y && a.z == b.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator!=(Vec3_i32 a, Vec3_i32 b){
|
||||||
|
return(!(a.x == b.x && a.y == b.y && a.z == b.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator==(Vec4_i32 a, Vec4_i32 b){
|
||||||
|
return(a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
operator!=(Vec4_i32 a, Vec4_i32 b){
|
||||||
|
return(!(a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w));
|
||||||
|
}
|
||||||
|
|
||||||
internal f32
|
internal f32
|
||||||
dot(Vec2 a, Vec2 b){
|
dot(Vec2 a, Vec2 b){
|
||||||
f32 result;
|
f32 result;
|
||||||
|
@ -412,7 +560,7 @@ lerp(Vec4 a, f32 t, Vec4 b){
|
||||||
internal f32
|
internal f32
|
||||||
unlerp(f32 a, f32 x, f32 b){
|
unlerp(f32 a, f32 x, f32 b){
|
||||||
f32 r = x;
|
f32 r = x;
|
||||||
if (b > a){
|
if (b != a){
|
||||||
r = (x - a) / (b - a);
|
r = (x - a) / (b - a);
|
||||||
}
|
}
|
||||||
return(r);
|
return(r);
|
||||||
|
@ -423,7 +571,7 @@ clamp(f32 a, f32 n, f32 z){
|
||||||
if (n < a){
|
if (n < a){
|
||||||
n = a;
|
n = a;
|
||||||
}
|
}
|
||||||
else if (n > z){
|
else if (n > z){
|
||||||
n = z;
|
n = z;
|
||||||
}
|
}
|
||||||
return(n);
|
return(n);
|
||||||
|
@ -434,7 +582,7 @@ clamp(i32 a, i32 n, i32 z){
|
||||||
if (n < a){
|
if (n < a){
|
||||||
n = a;
|
n = a;
|
||||||
}
|
}
|
||||||
else if (n > z){
|
else if (n > z){
|
||||||
n = z;
|
n = z;
|
||||||
}
|
}
|
||||||
return(n);
|
return(n);
|
||||||
|
@ -445,7 +593,7 @@ clamp(i64 a, i64 n, i64 z){
|
||||||
if (n < a){
|
if (n < a){
|
||||||
n = a;
|
n = a;
|
||||||
}
|
}
|
||||||
else if (n > z){
|
else if (n > z){
|
||||||
n = z;
|
n = z;
|
||||||
}
|
}
|
||||||
return(n);
|
return(n);
|
||||||
|
@ -456,7 +604,7 @@ clamp(u32 a, u32 n, u32 z){
|
||||||
if (n < a){
|
if (n < a){
|
||||||
n = a;
|
n = a;
|
||||||
}
|
}
|
||||||
else if (n > z){
|
else if (n > z){
|
||||||
n = z;
|
n = z;
|
||||||
}
|
}
|
||||||
return(n);
|
return(n);
|
||||||
|
@ -467,7 +615,7 @@ clamp(u64 a, u64 n, u64 z){
|
||||||
if (n < a){
|
if (n < a){
|
||||||
n = a;
|
n = a;
|
||||||
}
|
}
|
||||||
else if (n > z){
|
else if (n > z){
|
||||||
n = z;
|
n = z;
|
||||||
}
|
}
|
||||||
return(n);
|
return(n);
|
||||||
|
@ -667,7 +815,7 @@ hit_check(int32_t x, int32_t y, i32_Rect rect){
|
||||||
|
|
||||||
internal i32_Rect
|
internal i32_Rect
|
||||||
get_inner_rect(i32_Rect outer, i32 margin){
|
get_inner_rect(i32_Rect outer, i32 margin){
|
||||||
i32_Rect r;
|
i32_Rect r = {};
|
||||||
r.x0 = outer.x0 + margin;
|
r.x0 = outer.x0 + margin;
|
||||||
r.y0 = outer.y0 + margin;
|
r.y0 = outer.y0 + margin;
|
||||||
r.x1 = outer.x1 - margin;
|
r.x1 = outer.x1 - margin;
|
||||||
|
@ -677,7 +825,7 @@ get_inner_rect(i32_Rect outer, i32 margin){
|
||||||
|
|
||||||
internal f32_Rect
|
internal f32_Rect
|
||||||
get_inner_rect(f32_Rect outer, f32 margin){
|
get_inner_rect(f32_Rect outer, f32 margin){
|
||||||
f32_Rect r;
|
f32_Rect r = {};
|
||||||
r.x0 = outer.x0 + margin;
|
r.x0 = outer.x0 + margin;
|
||||||
r.y0 = outer.y0 + margin;
|
r.y0 = outer.y0 + margin;
|
||||||
r.x1 = outer.x1 - margin;
|
r.x1 = outer.x1 - margin;
|
||||||
|
|
50
4ed_view.cpp
50
4ed_view.cpp
|
@ -19,27 +19,21 @@ view_get_map(View *view){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal View_And_ID
|
internal View*
|
||||||
live_set_alloc_view(Heap *heap, Lifetime_Allocator *lifetime_allocator, Live_Views *live_set, Panel *panel){
|
live_set_alloc_view(Heap *heap, Lifetime_Allocator *lifetime_allocator, Live_Views *live_set){
|
||||||
Assert(live_set->count < live_set->max);
|
Assert(live_set->count < live_set->max);
|
||||||
++live_set->count;
|
++live_set->count;
|
||||||
|
|
||||||
View_And_ID result = {};
|
View *result = live_set->free_sentinel.transient.next;
|
||||||
result.view = live_set->free_sentinel.transient.next;
|
Assert((i32)(result - live_set->views) == result->persistent.id);
|
||||||
result.id = (i32)(result.view - live_set->views);
|
|
||||||
Assert(result.id == result.view->persistent.id);
|
|
||||||
|
|
||||||
result.view->transient.next->transient.prev = result.view->transient.prev;
|
result->transient.next->transient.prev = result->transient.prev;
|
||||||
result.view->transient.prev->transient.next = result.view->transient.next;
|
result->transient.prev->transient.next = result->transient.next;
|
||||||
memset(&result.view->transient, 0, sizeof(result.view->transient));
|
block_zero_struct(&result->transient);
|
||||||
|
|
||||||
result.view->transient.in_use = true;
|
result->transient.in_use = true;
|
||||||
panel->view = result.view;
|
init_query_set(&result->transient.query_set);
|
||||||
result.view->transient.panel = panel;
|
result->transient.lifetime_object = lifetime_alloc_object(heap, lifetime_allocator, DynamicWorkspace_View, result);
|
||||||
|
|
||||||
init_query_set(&result.view->transient.query_set);
|
|
||||||
|
|
||||||
result.view->transient.lifetime_object = lifetime_alloc_object(heap, lifetime_allocator, DynamicWorkspace_View, result.view);
|
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -344,11 +338,11 @@ view_set_file(System_Functions *system, Models *models, View *view, Editing_File
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
file_is_viewed(Editing_Layout *layout, Editing_File *file){
|
file_is_viewed(Layout *layout, Editing_File *file){
|
||||||
b32 is_viewed = false;
|
b32 is_viewed = false;
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &layout->used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
is_viewed = true;
|
is_viewed = true;
|
||||||
|
@ -360,11 +354,11 @@ file_is_viewed(Editing_Layout *layout, Editing_File *file){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *models, Editing_File *file){
|
adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *models, Editing_File *file){
|
||||||
Editing_Layout *layout = &models->layout;
|
Layout *layout = &models->layout;
|
||||||
|
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &layout->used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
if (!view->transient.file_data.show_temp_highlight){
|
if (!view->transient.file_data.show_temp_highlight){
|
||||||
|
@ -388,11 +382,11 @@ file_full_remeasure(System_Functions *system, Models *models, Editing_File *file
|
||||||
file_measure_wraps(system, &models->mem, file, font);
|
file_measure_wraps(system, &models->mem, file, font);
|
||||||
adjust_views_looking_at_file_to_new_cursor(system, models, file);
|
adjust_views_looking_at_file_to_new_cursor(system, models, file);
|
||||||
|
|
||||||
Editing_Layout *layout = &models->layout;
|
Layout *layout = &models->layout;
|
||||||
|
|
||||||
for (Panel *panel = layout->used_sentinel.next;
|
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||||
panel != &layout->used_sentinel;
|
panel != 0;
|
||||||
panel = panel->next){
|
panel = layout_get_next_open_panel(layout, panel)){
|
||||||
View *view = panel->view;
|
View *view = panel->view;
|
||||||
if (view->transient.file_data.file == file){
|
if (view->transient.file_data.file == file){
|
||||||
view->transient.line_height = font.metrics->height;
|
view->transient.line_height = font.metrics->height;
|
||||||
|
|
|
@ -87,11 +87,6 @@ struct Cursor_Limits{
|
||||||
f32 delta;
|
f32 delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct View_And_ID{
|
|
||||||
View *view;
|
|
||||||
i32 id;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
GROW_FAILED,
|
GROW_FAILED,
|
||||||
GROW_NOT_NEEDED,
|
GROW_NOT_NEEDED,
|
||||||
|
|
|
@ -248,6 +248,7 @@ build(Partition *part, u32 flags, u32 arch, char *code_path, char **code_files,
|
||||||
|
|
||||||
if (flags & DEBUG_INFO){
|
if (flags & DEBUG_INFO){
|
||||||
fm_add_to_line(line, "-Zi");
|
fm_add_to_line(line, "-Zi");
|
||||||
|
fm_add_to_line(line, "-DDO_CRAZY_EXPENSIVE_ASSERTS");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & OPTIMIZATION){
|
if (flags & OPTIMIZATION){
|
||||||
|
@ -540,8 +541,7 @@ get_freetype_include(char *out, u32 max){
|
||||||
#elif defined(IS_MAC)
|
#elif defined(IS_MAC)
|
||||||
char *freetype_include = "/usr/local/include/freetype2";
|
char *freetype_include = "/usr/local/include/freetype2";
|
||||||
size = strlen(freetype_include);
|
size = strlen(freetype_include);
|
||||||
memcpy(out, freetype_include, size
|
memcpy(out, freetype_include, size);
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return(size);
|
return(size);
|
||||||
|
|
Loading…
Reference in New Issue