double-LL allocation for panels

This commit is contained in:
Allen Webster 2016-03-02 11:18:10 -05:00
parent 6575a1cccd
commit be67657aed
5 changed files with 502 additions and 577 deletions

567
4ed.cpp
View File

@ -244,27 +244,22 @@ panel_make_empty(System_Functions *system, Exchange *exchange,
App_Vars *vars, Style *style, Panel *panel){ App_Vars *vars, Style *style, Panel *panel){
Mem_Options *mem = &vars->mem; Mem_Options *mem = &vars->mem;
Live_Views *live_set = &vars->live_set;
Editing_Layout *layout = &vars->layout; Editing_Layout *layout = &vars->layout;
Working_Set *working_set = &vars->working_set; Working_Set *working_set = &vars->working_set;
// TODO(allen): vars->delay pointer for directing all delayed actions to appropriate place
Delay *delay = &vars->delay1; Delay *delay = &vars->delay1;
View *new_view;
File_View *file_view; File_View *file_view;
View_And_ID new_view;
new_view = live_set_alloc_view(live_set, mem);
if (panel->view){ Assert(panel->view == 0);
view_replace_major(system, exchange, new_view, panel, live_set); new_view = live_set_alloc_view(&vars->live_set, mem);
} panel->view = new_view.view;
else{ panel->view->panel = panel;
view_set_first(new_view, panel);
} file_view = file_view_init(panel->view, layout, working_set, delay,
file_view = file_view_init(new_view, layout, working_set, delay,
&vars->settings, &vars->hot_directory, mem, &vars->styles); &vars->settings, &vars->hot_directory, mem, &vars->styles);
view_set_file(file_view, 0, vars->font_set, style, 0, 0, 0); view_set_file(file_view, 0, vars->font_set, style, 0, 0, 0);
new_view->map = app_get_map(vars, mapid_global); panel->view->map = app_get_map(vars, mapid_global);
return(file_view); return(file_view);
} }
@ -699,12 +694,10 @@ COMMAND_DECL(paste){
USE_LAYOUT(layout); USE_LAYOUT(layout);
USE_MEM(mem); USE_MEM(mem);
Panel *current_panel; Panel *panel, *used_panels;
String *src; String *src;
File_View *current_view; File_View *current_view;
i32 pos_left, next_cursor_pos; i32 pos_left, next_cursor_pos;
i32 panel_count;
i32 i;
if (working_set->clipboard_size > 0){ if (working_set->clipboard_size > 0){
view->next_mode.rewrite = 1; view->next_mode.rewrite = 1;
@ -718,12 +711,11 @@ COMMAND_DECL(paste){
view_cursor_move(view, next_cursor_pos); view_cursor_move(view, next_cursor_pos);
view->mark = pos_left; view->mark = pos_left;
current_panel = layout->panels; used_panels = &layout->used_sentinel;
panel_count = layout->panel_count; for (dll_items(panel, used_panels)){
for (i = 0; i < panel_count; ++i, ++current_panel){ current_view = view_to_file_view(panel->view);
current_view = view_to_file_view(current_panel->view);
if (current_view->file == file){
if (current_view && current_view->file == file){
view_post_paste_effect(current_view, 20, pos_left, src->size, view_post_paste_effect(current_view, 20, pos_left, src->size,
current_view->style->main.paste_color); current_view->style->main.paste_color);
} }
@ -738,6 +730,8 @@ COMMAND_DECL(paste_next){
USE_WORKING_SET(working_set); USE_WORKING_SET(working_set);
USE_LAYOUT(layout); USE_LAYOUT(layout);
USE_MEM(mem); USE_MEM(mem);
Panel *panel, *used_panels;
if (working_set->clipboard_size > 0 && view->mode.rewrite == 1){ if (working_set->clipboard_size > 0 && view->mode.rewrite == 1){
view->next_mode.rewrite = 1; view->next_mode.rewrite = 1;
@ -751,15 +745,12 @@ COMMAND_DECL(paste_next){
view_cursor_move(view, next_cursor_pos); view_cursor_move(view, next_cursor_pos);
view->mark = range.start; view->mark = range.start;
used_panels = &layout->used_sentinel;
for (dll_items(panel, used_panels)){
File_View *current_view = view_to_file_view(panel->view);
Editing_Layout *layout = command->layout; if (current_view->file == file){
Panel *panels = layout->panels;
i32 panel_count = layout->panel_count;
for (i32 i = 0; i < panel_count; ++i){
Panel *current_panel = panels + i;
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_post_paste_effect(current_view, 20, range.start, src->size, view_post_paste_effect(current_view, 20, range.start, src->size,
current_view->style->main.paste_color); current_view->style->main.paste_color);
} }
@ -852,14 +843,7 @@ COMMAND_DECL(interactive_new){
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_interactive(system, fview, &vars->map_ui, view_show_interactive(system, fview, &vars->map_ui,
IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); IAct_New, IInt_Sys_File_List, make_lit_string("New: "));
} }
@ -916,9 +900,7 @@ COMMAND_DECL(interactive_open){
ProfileMomentFunction(); ProfileMomentFunction();
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel); USE_PANEL(panel);
USE_STYLE(style);
USE_DELAY(delay); USE_DELAY(delay);
USE_EXCHANGE(exchange);
char *filename = 0; char *filename = 0;
int filename_len = 0; int filename_len = 0;
@ -954,10 +936,6 @@ COMMAND_DECL(interactive_open){
File_View *fview = view_to_file_view(view); File_View *fview = view_to_file_view(view);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_interactive(system, fview, &vars->map_ui, view_show_interactive(system, fview, &vars->map_ui,
IAct_Open, IInt_Sys_File_List, make_lit_string("Open: ")); IAct_Open, IInt_Sys_File_List, make_lit_string("Open: "));
} }
@ -965,9 +943,7 @@ COMMAND_DECL(interactive_open){
internal void internal void
view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
Live_Views *live_set = cmd->live_set;
Mem_Options *mem = cmd->mem; Mem_Options *mem = cmd->mem;
Exchange *exchange = cmd->exchange;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
Editing_Layout *layout = cmd->layout; Editing_Layout *layout = cmd->layout;
App_Vars *vars = cmd->vars; App_Vars *vars = cmd->vars;
@ -977,17 +953,14 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
Partition old_part; Partition old_part;
Temp_Memory temp; Temp_Memory temp;
View *new_view, *old_view; View *old_view;
File_View *file_view; File_View *file_view;
new_view = live_set_alloc_view(live_set, mem);
view_replace_major(system, exchange, new_view, panel, live_set);
file_view = file_view_init(new_view, layout, working_set, delay, file_view = file_view_init(panel->view, layout, working_set, delay,
&vars->settings, &vars->hot_directory, mem, &vars->styles); &vars->settings, &vars->hot_directory, mem, &vars->styles);
old_view = cmd->view; old_view = cmd->view;
cmd->view = new_view; cmd->view = panel->view;
old_part = cmd->part; old_part = cmd->part;
temp = begin_temp_memory(&mem->part); temp = begin_temp_memory(&mem->part);
@ -1000,7 +973,7 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
end_temp_memory(temp); end_temp_memory(temp);
cmd->view = old_view; cmd->view = old_view;
new_view->map = app_get_map(vars, file->settings.base_map_id); panel->view->map = app_get_map(vars, file->settings.base_map_id);
} }
// TODO(allen): Improvements to reopen // TODO(allen): Improvements to reopen
@ -1086,14 +1059,7 @@ COMMAND_DECL(interactive_save_as){
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_interactive(system, fview, &vars->map_ui, view_show_interactive(system, fview, &vars->map_ui,
IAct_Save_As, IInt_Sys_File_List, make_lit_string("Save As: ")); IAct_Save_As, IInt_Sys_File_List, make_lit_string("Save As: "));
} }
@ -1101,25 +1067,19 @@ COMMAND_DECL(interactive_save_as){
COMMAND_DECL(change_active_panel){ COMMAND_DECL(change_active_panel){
ProfileMomentFunction(); ProfileMomentFunction();
USE_LAYOUT(layout); USE_LAYOUT(layout);
if (layout->panel_count > 1){ USE_PANEL(panel);
++layout->active_panel;
if (layout->active_panel >= layout->panel_count){ panel = panel->next;
layout->active_panel = 0; if (panel == &layout->used_sentinel){
} panel = panel->next;
} }
layout->active_panel = (i32)(panel - layout->panels);
} }
COMMAND_DECL(interactive_switch_buffer){ COMMAND_DECL(interactive_switch_buffer){
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_interactive(system, fview, &vars->map_ui, view_show_interactive(system, fview, &vars->map_ui,
IAct_Switch, IInt_Live_File_List, make_lit_string("Switch Buffer: ")); IAct_Switch, IInt_Live_File_List, make_lit_string("Switch Buffer: "));
@ -1129,13 +1089,6 @@ COMMAND_DECL(interactive_kill_buffer){
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_interactive(system, fview, &vars->map_ui, view_show_interactive(system, fview, &vars->map_ui,
IAct_Kill, IInt_Live_File_List, make_lit_string("Kill Buffer: ")); IAct_Kill, IInt_Live_File_List, make_lit_string("Kill Buffer: "));
@ -1360,20 +1313,20 @@ COMMAND_DECL(open_panel_vsplit){
if (layout->panel_count < layout->panel_max_count){ if (layout->panel_count < layout->panel_max_count){
Split_Result split = layout_split_panel(layout, panel, 1); Split_Result split = layout_split_panel(layout, panel, 1);
Panel *panel1 = panel; Panel *panel1 = panel;
Panel *panel2 = split.panel; Panel *panel2 = split.panel;
panel2->screen_region = panel1->screen_region; panel2->screen_region = panel1->screen_region;
panel2->full.x0 = split.divider->pos; panel2->full.x0 = split.divider->pos;
panel2->full.x1 = panel1->full.x1; panel2->full.x1 = panel1->full.x1;
panel1->full.x1 = split.divider->pos; panel1->full.x1 = split.divider->pos;
panel_fix_internal_area(panel1); panel_fix_internal_area(panel1);
panel_fix_internal_area(panel2); panel_fix_internal_area(panel2);
panel2->prev_inner = panel2->inner; panel2->prev_inner = panel2->inner;
layout->active_panel = (i32)(panel2 - layout->panels); layout->active_panel = (i32)(panel2 - layout->panels);
panel_make_empty(system, exchange, vars, style, panel2); panel_make_empty(system, exchange, vars, style, panel2);
} }
@ -1386,23 +1339,23 @@ COMMAND_DECL(open_panel_hsplit){
USE_EXCHANGE(exchange); USE_EXCHANGE(exchange);
USE_VARS(vars); USE_VARS(vars);
USE_STYLE(style); USE_STYLE(style);
if (layout->panel_count < layout->panel_max_count){ if (layout->panel_count < layout->panel_max_count){
Split_Result split = layout_split_panel(layout, panel, 0); Split_Result split = layout_split_panel(layout, panel, 0);
Panel *panel1 = panel; Panel *panel1 = panel;
Panel *panel2 = split.panel; Panel *panel2 = split.panel;
panel2->screen_region = panel1->screen_region; panel2->screen_region = panel1->screen_region;
panel2->full.y0 = split.divider->pos; panel2->full.y0 = split.divider->pos;
panel2->full.y1 = panel1->full.y1; panel2->full.y1 = panel1->full.y1;
panel1->full.y1 = split.divider->pos; panel1->full.y1 = split.divider->pos;
panel_fix_internal_area(panel1); panel_fix_internal_area(panel1);
panel_fix_internal_area(panel2); panel_fix_internal_area(panel2);
panel2->prev_inner = panel2->inner; panel2->prev_inner = panel2->inner;
layout->active_panel = (i32)(panel2 - layout->panels); layout->active_panel = (i32)(panel2 - layout->panels);
panel_make_empty(system, exchange, vars, style, panel2); panel_make_empty(system, exchange, vars, style, panel2);
} }
@ -1414,67 +1367,77 @@ COMMAND_DECL(close_panel){
USE_PANEL(panel); USE_PANEL(panel);
USE_VIEW(view); USE_VIEW(view);
USE_EXCHANGE(exchange); USE_EXCHANGE(exchange);
Panel *panel_ptr, *used_panels;
Divider_And_ID div, parent_div, child_div;
i32 child;
i32 parent;
i32 which_child;
i32 active;
if (layout->panel_count > 1){ if (layout->panel_count > 1){
if (view){ live_set_free_view(system, exchange, command->live_set, view);
live_set_free_view(system, exchange, command->live_set, view); panel->view = 0;
panel->view = 0;
} div = layout_get_divider(layout, panel->parent);
Divider_And_ID div = layout_get_divider(layout, panel->parent); // This divider cannot have two child dividers.
Assert(div.divider->child1 == -1 || div.divider->child2 == -1); Assert(div.divider->child1 == -1 || div.divider->child2 == -1);
i32 child; // Get the child who needs to fill in this node's spot
if (div.divider->child1 == -1){ child = div.divider->child1;
child = div.divider->child2; if (child == -1) child = div.divider->child2;
}
else{ parent = div.divider->parent;
child = div.divider->child1; which_child = div.divider->which_child;
}
// Fill the child in the slot this node use to hold
i32 parent = div.divider->parent; if (parent == -1){
i32 which_child = div.divider->which_child;
if (parent != -1){
Divider_And_ID par = layout_get_divider(layout, parent);
if (which_child == -1){
par.divider->child1 = child;
}
else{
par.divider->child2 = child;
}
}
else{
Assert(layout->root == div.id); Assert(layout->root == div.id);
layout->root = child; layout->root = child;
} }
else{
if (child != -1){ parent_div = layout_get_divider(layout, parent);
Divider_And_ID chi = layout_get_divider(layout, child); if (which_child == -1){
chi.divider->parent = parent; parent_div.divider->child1 = child;
chi.divider->which_child = div.divider->which_child; }
else{
parent_div.divider->child2 = child;
}
} }
layout_free_divider(layout, div.divider); // If there was a child divider, give it information about it's new parent.
layout_free_panel(layout, panel); if (child != -1){
child_div = layout_get_divider(layout, child);
child_div.divider->parent = parent;
child_div.divider->which_child = div.divider->which_child;
}
// What is the new active panel?
active = -1;
if (child == -1){ if (child == -1){
panel = layout->panels; used_panels = &layout->used_sentinel;
layout->active_panel = -1; for (dll_items(panel_ptr, used_panels)){
for (i32 i = 0; i < layout->panel_count; ++i){ if (panel_ptr != panel && panel_ptr->parent == div.id){
if (panel->parent == div.id){ panel_ptr->parent = parent;
panel->parent = parent; panel_ptr->which_child = which_child;
panel->which_child = which_child; active = (i32)(panel_ptr - layout->panels);
layout->active_panel = i;
break; break;
} }
++panel;
} }
Assert(layout->active_panel != -1);
} }
else{ else{
layout->active_panel = layout->active_panel % layout->panel_count; panel_ptr = panel->next;
if (panel_ptr == &layout->used_sentinel) panel_ptr = panel_ptr->next;
Assert(panel_ptr != panel);
active = (i32)(panel_ptr - layout->panels);
} }
Assert(active != -1 && panel != layout->panels + active);
layout->active_panel = active;
layout_free_divider(layout, div.divider);
layout_free_panel(layout, panel);
layout_fix_all_panels(layout); layout_fix_all_panels(layout);
} }
} }
@ -1619,40 +1582,9 @@ COMMAND_DECL(page_up){
} }
COMMAND_DECL(open_color_tweaker){ COMMAND_DECL(open_color_tweaker){
#if 0
ProfileMomentFunction();
USE_VARS(vars);
USE_LIVE_SET(live_set);
USE_MEM(mem);
USE_PANEL(panel);
USE_EXCHANGE(exchange);
{
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_minor(system, exchange, new_view, panel, live_set);
new_view->map = &vars->map_ui;
Color_View *color_view = color_view_init(new_view, &vars->working_set);
color_view->hot_directory = &vars->hot_directory;
color_view->main_style = &vars->style;
color_view->styles = &vars->styles;
color_view->palette = vars->palette;
color_view->palette_size = vars->palette_size;
color_view->font_set = vars->font_set;
}
#endif
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_theme(fview, &vars->map_ui); view_show_theme(fview, &vars->map_ui);
} }
@ -1661,13 +1593,6 @@ COMMAND_DECL(open_config){
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_config(fview, &vars->map_ui); view_show_config(fview, &vars->map_ui);
} }
@ -1676,13 +1601,6 @@ COMMAND_DECL(open_menu){
ProfileMomentFunction(); ProfileMomentFunction();
USE_FILE_VIEW(fview); USE_FILE_VIEW(fview);
USE_VARS(vars); USE_VARS(vars);
USE_PANEL(panel);
USE_STYLE(style);
USE_EXCHANGE(exchange);
if (!fview){
fview = panel_make_empty(system, exchange, vars, style, panel);
}
view_show_menu(fview, &vars->map_ui); view_show_menu(fview, &vars->map_ui);
} }
@ -3036,61 +2954,63 @@ App_Init_Sig(app_init){
Partition *partition = &vars->mem.part; Partition *partition = &vars->mem.part;
target->partition = partition; target->partition = partition;
Panel *panels; Panel *panels, *panel;
Panel_Divider *dividers, *div; Panel_Divider *dividers, *div;
i32 panel_max_count; i32 panel_max_count;
i32 divider_max_count; i32 divider_max_count;
panel_max_count = vars->layout.panel_max_count = 16; {
divider_max_count = panel_max_count - 1; i32 i;
vars->layout.panel_count = 1;
panel_max_count = vars->layout.panel_max_count = 16;
panels = push_array(partition, Panel, panel_max_count); divider_max_count = panel_max_count - 1;
vars->layout.panels = panels; vars->layout.panel_count = 0;
dividers = push_array(partition, Panel_Divider, divider_max_count); panels = push_array(partition, Panel, panel_max_count);
vars->layout.dividers = dividers; vars->layout.panels = panels;
div = dividers; dll_init_sentinel(&vars->layout.free_sentinel);
for (i32 i = 0; i < divider_max_count-1; ++i, ++div){ dll_init_sentinel(&vars->layout.used_sentinel);
div->next = (div + 1);
panel = panels;
for (i = 0; i < panel_max_count; ++i, ++panel){
dll_insert(&vars->layout.free_sentinel, panel);
}
dividers = push_array(partition, Panel_Divider, divider_max_count);
vars->layout.dividers = dividers;
div = dividers;
for (i = 0; i < divider_max_count-1; ++i, ++div){
div->next = (div + 1);
}
div->next = 0;
vars->layout.free_divider = dividers;
} }
div->next = 0;
vars->layout.free_divider = dividers;
i32 view_chunk_size = 0;
i32 view_sizes[] = {
sizeof(File_View)
};
{ {
char *vptr = 0; char *vptr = 0;
View *v = 0, *n = 0; View *v = 0;
i32 i = 0, max = 0; i32 i = 0;
i32 max = 0;
i32 view_size = sizeof(File_View);
vars->live_set.count = 0; vars->live_set.count = 0;
vars->live_set.max = panel_max_count; vars->live_set.max = panel_max_count;
for (i = 0; i < ArrayCount(view_sizes); ++i){ vars->live_set.stride = view_size;
view_chunk_size = Max(view_chunk_size, view_sizes[i]); vars->live_set.views = push_block(partition, view_size*vars->live_set.max);
}
vars->live_set.stride = view_chunk_size; dll_init_sentinel(&vars->live_set.free_sentinel);
vars->live_set.views = push_block(partition, view_chunk_size*vars->live_set.max);
max = vars->live_set.max; max = vars->live_set.max;
vptr = (char*)vars->live_set.views; vptr = (char*)vars->live_set.views;
vars->live_set.free_view = (View*)vptr; for (i = 0; i < max; ++i, vptr += view_size){
for (i = 0; i < max; ++i){
v = (View*)(vptr); v = (View*)(vptr);
n = (View*)(vptr + view_chunk_size); dll_insert(&vars->live_set.free_sentinel, v);
v->next_free = n;
vptr = (char*)n;
} }
v->next_free = 0;
} }
setup_command_table(); setup_command_table();
Command_Map *global = &vars->map_top; Command_Map *global = &vars->map_top;
@ -3302,16 +3222,17 @@ App_Init_Sig(app_init){
vars->palette_size = 40; vars->palette_size = 40;
vars->palette = push_array(partition, u32, vars->palette_size); vars->palette = push_array(partition, u32, vars->palette_size);
// NOTE(allen): init first panel // NOTE(allen): init first panel
panel_init(&panels[0]); Panel_And_ID p = layout_alloc_panel(&vars->layout);
panel_make_empty(system, exchange, vars, &vars->style, &panels[0]); panel_make_empty(system, exchange, vars, &vars->style, p.panel);
vars->layout.active_panel = p.id;
String hdbase = make_fixed_width_string(vars->hot_dir_base_); String hdbase = make_fixed_width_string(vars->hot_dir_base_);
hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash); hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash);
vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512); vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512);
// NOTE(allen): child proc list setup // NOTE(allen): child proc list setup
i32 max_children = 16; i32 max_children = 16;
partition_align(partition, 8); partition_align(partition, 8);
@ -3325,6 +3246,21 @@ App_Init_Sig(app_init){
vars->sys_app_bindings = (Sys_App_Binding*)push_array(partition, Sys_App_Binding, vars->sys_app_max); vars->sys_app_bindings = (Sys_App_Binding*)push_array(partition, Sys_App_Binding, vars->sys_app_max);
} }
// NOTE(allen): while I transition away from this view system to something that has
// more unified behavior, I will use this to add checks to the program's state so that I
// can make sure it behaving well.
internal void
correctness_check(App_Vars *vars){
Panel *panel, *used_panels;
used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
Assert(panel->view);
Assert(panel->parent != -1 || vars->layout.panel_count == 1);
}
panel = vars->layout.panels + vars->layout.active_panel;
Assert(panel->ALLOCED);
}
App_Step_Sig(app_step){ App_Step_Sig(app_step){
ProfileStart(OS_syncing); ProfileStart(OS_syncing);
Application_Step_Result app_result = *result; Application_Step_Result app_result = *result;
@ -3361,7 +3297,6 @@ App_Step_Sig(app_step){
} }
// NOTE(allen): update child processes // NOTE(allen): update child processes
Panel *panels = vars->layout.panels;
if (time_step){ if (time_step){
Temp_Memory temp = begin_temp_memory(&vars->mem.part); Temp_Memory temp = begin_temp_memory(&vars->mem.part);
u32 max = Kbytes(32); u32 max = Kbytes(32);
@ -3416,11 +3351,14 @@ App_Step_Sig(app_step){
new_cursor = spec.step.post_pos; new_cursor = spec.step.post_pos;
} }
Panel *panel = panels; Panel *panel, *used_panels;
i32 panel_count = vars->layout.panel_count; View *view;
for (i32 i = 0; i < panel_count; ++i, ++panel){ File_View *fview;
View *view = panel->view;
File_View *fview = view_to_file_view(view); used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
view = panel->view;
fview = view_to_file_view(view);
Assert(fview); Assert(fview);
if (fview->file == out_file){ if (fview->file == out_file){
view_cursor_move(fview, new_cursor); view_cursor_move(fview, new_cursor);
@ -3428,7 +3366,7 @@ App_Step_Sig(app_step){
} }
} }
} }
vars->cli_processes.count = count; vars->cli_processes.count = count;
end_temp_memory(temp); end_temp_memory(temp);
} }
@ -3439,20 +3377,18 @@ App_Step_Sig(app_step){
i32 prev_height = vars->layout.full_height; i32 prev_height = vars->layout.full_height;
i32 current_width = target->width; i32 current_width = target->width;
i32 current_height = target->height; i32 current_height = target->height;
Panel *panel; Panel *panel, *used_panels;
File_View *fview; File_View *fview;
i32 i, count;
vars->layout.full_width = current_width; vars->layout.full_width = current_width;
vars->layout.full_height = current_height; vars->layout.full_height = current_height;
if (prev_width != current_width || prev_height != current_height){ if (prev_width != current_width || prev_height != current_height){
layout_refit(&vars->layout, prev_width, prev_height); layout_refit(&vars->layout, prev_width, prev_height);
count = vars->layout.panel_count; used_panels = &vars->layout.used_sentinel;
panel = panels; for (dll_items(panel, used_panels)){
for (i = 0; i < count; ++i, ++panel){
fview = view_to_file_view(panel->view); fview = view_to_file_view(panel->view);
Assert(fview); Assert(fview);
// TODO(allen): All responses to a panel changing size should // TODO(allen): All responses to a panel changing size should
@ -3477,18 +3413,7 @@ App_Step_Sig(app_step){
ProfileEnd(OS_syncing); ProfileEnd(OS_syncing);
// NOTE(allen): while I transition away from this view system to something that has correctness_check(vars);
// more unified behavior, I will use this to add checks to the program's state so that I
// can make sure it behaving well.
ProfileStart(correctness_checks);
{
Panel *panel = panels;
i32 panel_count = vars->layout.panel_count;
for (i32 i = 0; i < panel_count; ++i, ++panel){
Assert(panel->view);
}
}
ProfileEnd(correctness_checks);
ProfileStart(hover_status); ProfileStart(hover_status);
// NOTE(allen): detect mouse hover status // NOTE(allen): detect mouse hover status
@ -3496,12 +3421,10 @@ App_Step_Sig(app_step){
i32 my = mouse->y; i32 my = mouse->y;
b32 mouse_in_edit_area = 0; b32 mouse_in_edit_area = 0;
b32 mouse_in_margin_area = 0; b32 mouse_in_margin_area = 0;
Panel *mouse_panel = 0; Panel *mouse_panel, *used_panels;
i32 mouse_panel_i = 0;
i32 panel_count = vars->layout.panel_count; used_panels = &vars->layout.used_sentinel;
for (dll_items(mouse_panel, used_panels)){
mouse_panel = panels;
for (mouse_panel_i = 0; mouse_panel_i < panel_count; ++mouse_panel_i, ++mouse_panel){
if (hit_check(mx, my, mouse_panel->inner)){ if (hit_check(mx, my, mouse_panel->inner)){
mouse_in_edit_area = 1; mouse_in_edit_area = 1;
break; break;
@ -3514,7 +3437,6 @@ App_Step_Sig(app_step){
if (!(mouse_in_edit_area || mouse_in_margin_area)){ if (!(mouse_in_edit_area || mouse_in_margin_area)){
mouse_panel = 0; mouse_panel = 0;
mouse_panel_i = 0;
} }
b32 mouse_on_divider = 0; b32 mouse_on_divider = 0;
@ -3572,13 +3494,15 @@ App_Step_Sig(app_step){
} }
ProfileEnd(hover_status); ProfileEnd(hover_status);
correctness_check(vars);
// NOTE(allen): prepare to start executing commands // NOTE(allen): prepare to start executing commands
ProfileStart(command_coroutine); ProfileStart(prepare_commands);
Command_Data *cmd = &vars->command_data; Command_Data *cmd = &vars->command_data;
cmd->mem = &vars->mem; cmd->mem = &vars->mem;
cmd->panel = panels + vars->layout.active_panel; cmd->panel = vars->layout.panels + vars->layout.active_panel;
cmd->view = cmd->panel->view; cmd->view = cmd->panel->view;
cmd->working_set = &vars->working_set; cmd->working_set = &vars->working_set;
cmd->layout = &vars->layout; cmd->layout = &vars->layout;
@ -3590,16 +3514,16 @@ App_Step_Sig(app_step){
cmd->screen_width = target->width; cmd->screen_width = target->width;
cmd->screen_height = target->height; cmd->screen_height = target->height;
cmd->system = system; cmd->system = system;
Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part); Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part);
cmd->part = partition_sub_part(&vars->mem.part, 16 << 10); cmd->part = partition_sub_part(&vars->mem.part, 16 << 10);
if (first_step){ if (first_step){
if (vars->hooks[hook_start]){ if (vars->hooks[hook_start]){
vars->hooks[hook_start](&app_links); vars->hooks[hook_start](&app_links);
cmd->part.pos = 0; cmd->part.pos = 0;
} }
i32 i; i32 i;
String file_name; String file_name;
Panel *panel = vars->layout.panels; Panel *panel = vars->layout.panels;
@ -3617,7 +3541,7 @@ App_Step_Sig(app_step){
} }
} }
} }
ProfileEnd(hover_status); ProfileEnd(prepare_commands);
// NOTE(allen): process the command_coroutine if it is unfinished // NOTE(allen): process the command_coroutine if it is unfinished
ProfileStart(command_coroutine); ProfileStart(command_coroutine);
@ -3753,6 +3677,8 @@ App_Step_Sig(app_step){
ProfileEnd(command_coroutine); ProfileEnd(command_coroutine);
correctness_check(vars);
// NOTE(allen): pass raw input to the panels // NOTE(allen): pass raw input to the panels
ProfileStart(step); ProfileStart(step);
@ -3794,22 +3720,21 @@ App_Step_Sig(app_step){
if (consumed_input[5]){ if (consumed_input[5]){
mouse_state.wheel = 0; mouse_state.wheel = 0;
} }
{ {
Panel *panel = panels; Panel *panel, *used_panels;
for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
View *view_ = panel->view; View *view_ = panel->view;
if (view_){ Assert(view_->do_view);
Assert(view_->do_view); b32 active = (panel == cmd->panel);
b32 active = (panel == cmd->panel); Input_Summary input = (active)?(active_input):(dead_input);
Input_Summary input = (active)?(active_input):(dead_input); if (panel == mouse_panel && !mouse->out_of_window){
if (panel == mouse_panel && !mouse->out_of_window){ input.mouse = mouse_state;
input.mouse = mouse_state; }
} if (view_->do_view(system, exchange, view_, panel->inner, cmd->view,
if (view_->do_view(system, exchange, view_, panel->inner, cmd->view, VMSG_STEP, 0, &input, &active_input)){
VMSG_STEP, 0, &input, &active_input)){ app_result.redraw = 1;
app_result.redraw = 1;
}
} }
} }
} }
@ -3817,6 +3742,8 @@ App_Step_Sig(app_step){
update_command_data(vars, cmd); update_command_data(vars, cmd);
ProfileEnd(step); ProfileEnd(step);
correctness_check(vars);
// NOTE(allen): command execution // NOTE(allen): command execution
ProfileStart(command); ProfileStart(command);
if (!consumed_input[0] || !consumed_input[1]){ if (!consumed_input[0] || !consumed_input[1]){
@ -3877,7 +3804,9 @@ App_Step_Sig(app_step){
update_command_data(vars, cmd); update_command_data(vars, cmd);
ProfileEnd(command); ProfileEnd(command);
correctness_check(vars);
ProfileStart(resizing); ProfileStart(resizing);
// NOTE(allen): panel resizing // NOTE(allen): panel resizing
switch (vars->state){ switch (vars->state){
@ -3976,13 +3905,15 @@ App_Step_Sig(app_step){
} }
if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){ if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){
vars->layout.active_panel = mouse_panel_i; vars->layout.active_panel = (i32)(mouse_panel - vars->layout.panels);
app_result.redraw = 1; app_result.redraw = 1;
} }
update_command_data(vars, cmd); update_command_data(vars, cmd);
ProfileEnd(resizing); ProfileEnd(resizing);
correctness_check(vars);
// NOTE(allen): processing sys app bindings // NOTE(allen): processing sys app bindings
ProfileStart(sys_app_bind_processing); ProfileStart(sys_app_bind_processing);
{ {
@ -4227,17 +4158,13 @@ App_Step_Sig(app_step){
file_create_empty(system, mem, working_set, file.file, string.str, file_create_empty(system, mem, working_set, file.file, string.str,
vars->font_set, style->font_id); vars->font_set, style->font_id);
table_add(&working_set->table, file.file->name.source_path, file.index); table_add(&working_set->table, file.file->name.source_path, file.index);
View *new_view = live_set_alloc_view(live_set, mem); View *view = panel->view;
view_replace_major(system, exchange, new_view, panel, live_set); File_View *fview = view_to_file_view(view);
File_View *file_view = file_view_init( view_set_file(fview, file.file, vars->font_set, style,
new_view, &vars->layout, working_set, &vars->delay2,
&vars->settings, &vars->hot_directory, mem, &vars->styles);
cmd->view = (View*)file_view;
view_set_file(file_view, file.file, vars->font_set, style,
system, vars->hooks[hook_open_file], &app_links); system, vars->hooks[hook_open_file], &app_links);
new_view->map = app_get_map(vars, file.file->settings.base_map_id); view->map = app_get_map(vars, file.file->settings.base_map_id);
#if BUFFER_EXPERIMENT_SCALPEL <= 0 #if BUFFER_EXPERIMENT_SCALPEL <= 0
if (file.file->settings.tokens_exist) if (file.file->settings.tokens_exist)
file_first_lex_parallel(system, general, file.file); file_first_lex_parallel(system, general, file.file);
@ -4248,18 +4175,12 @@ App_Step_Sig(app_step){
{ {
Editing_File *file = working_set_lookup_file(working_set, string); Editing_File *file = working_set_lookup_file(working_set, string);
if (file){ if (file){
View *new_view = live_set_alloc_view(live_set, mem); View *view = panel->view;
view_replace_major(system, exchange, new_view, panel, live_set); File_View *fview = view_to_file_view(view);
File_View *file_view = file_view_init( view_set_file(fview, file, vars->font_set, style,
new_view, &vars->layout, working_set, &vars->delay2,
&vars->settings, &vars->hot_directory, mem, &vars->styles);
cmd->view = (View*)file_view;
view_set_file(file_view, file, vars->font_set, style,
system, vars->hooks[hook_open_file], &app_links); system, vars->hooks[hook_open_file], &app_links);
view->map = app_get_map(vars, file->settings.base_map_id);
new_view->map = app_get_map(vars, file->settings.base_map_id);
} }
}break; }break;
@ -4308,15 +4229,18 @@ App_Step_Sig(app_step){
} }
Swap(vars->delay1, vars->delay2); Swap(vars->delay1, vars->delay2);
} }
end_temp_memory(param_stack_temp);
ProfileEnd(delayed_actions); ProfileEnd(delayed_actions);
end_temp_memory(param_stack_temp); correctness_check(vars);
ProfileStart(resize); ProfileStart(resize);
// NOTE(allen): send resize messages to panels that have changed size // NOTE(allen): send resize messages to panels that have changed size
{ {
Panel *panel = panels; Panel *panel, *used_panels;
for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
i32_Rect prev = panel->prev_inner; i32_Rect prev = panel->prev_inner;
i32_Rect inner = panel->inner; i32_Rect inner = panel->inner;
if (prev.x0 != inner.x0 || prev.y0 != inner.y0 || if (prev.x0 != inner.x0 || prev.y0 != inner.y0 ||
@ -4349,10 +4273,10 @@ App_Step_Sig(app_step){
&file->state.buffer, advance_data); &file->state.buffer, advance_data);
} }
} }
Panel *panel = panels; Panel *panel, *used_panels;
i32 count = vars->layout.panel_count; used_panels = &vars->layout.used_sentinel;
for (i32 i = 0; i < count; ++i, ++panel){ for (dll_items(panel, used_panels)){
View *view = panel->view; View *view = panel->view;
if (view){ if (view){
view->do_view(system, exchange, view->do_view(system, exchange,
@ -4362,6 +4286,8 @@ App_Step_Sig(app_step){
} }
} }
ProfileEnd(style_change); ProfileEnd(style_change);
correctness_check(vars);
ProfileStart(redraw); ProfileStart(redraw);
if (mouse_panel != vars->prev_mouse_panel) app_result.redraw = 1; if (mouse_panel != vars->prev_mouse_panel) app_result.redraw = 1;
@ -4372,11 +4298,12 @@ App_Step_Sig(app_step){
draw_push_clip(target, rect_from_target(target)); draw_push_clip(target, rect_from_target(target));
// NOTE(allen): render the panels // NOTE(allen): render the panels
Panel *panel = panels; Panel *panel, *used_panels;
for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){ used_panels = &vars->layout.used_sentinel;
for (dll_items(panel, used_panels)){
i32_Rect full = panel->full; i32_Rect full = panel->full;
i32_Rect inner = panel->inner; i32_Rect inner = panel->inner;
View *view = panel->view; View *view = panel->view;
Style *style = &vars->style; Style *style = &vars->style;
@ -4416,13 +4343,7 @@ App_Step_Sig(app_step){
ProfileStart(get_cursor); ProfileStart(get_cursor);
// NOTE(allen): get cursor type // NOTE(allen): get cursor type
if (mouse_in_edit_area){ if (mouse_in_edit_area){
View *view = mouse_panel->view;
if (view){
app_result.mouse_cursor_type = view->mouse_cursor_type;
}
else{
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 (mouse_in_margin_area){
if (mouse_on_divider){ if (mouse_on_divider){
@ -4443,6 +4364,8 @@ App_Step_Sig(app_step){
*result = app_result; *result = app_result;
result->lctrl_lalt_is_altgr = vars->settings.lctrl_lalt_is_altgr; result->lctrl_lalt_is_altgr = vars->settings.lctrl_lalt_is_altgr;
correctness_check(vars);
// end-of-app_step // end-of-app_step
} }

View File

@ -35,6 +35,7 @@
#define FCPP_LEXER_IMPLEMENTATION #define FCPP_LEXER_IMPLEMENTATION
#include "4cpp_lexer.h" #include "4cpp_lexer.h"
#include "4ed_template.cpp"
#include "4ed_exchange.cpp" #include "4ed_exchange.cpp"
#include "4ed_font_set.cpp" #include "4ed_font_set.cpp"
#include "4ed_rendering_helper.cpp" #include "4ed_rendering_helper.cpp"

View File

@ -414,27 +414,6 @@ get_opaque_font_advance(Render_Font *font){
return result; return result;
} }
#if 0
internal void
file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
i32 line_count = buffer->line_count;
if (line_count > buffer->widths_max || buffer->widths_max == 0){
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
if (new_max < Kbytes(1)) new_max = Kbytes(1);
if (buffer->line_widths){
buffer->line_widths = (f32*)
general_memory_reallocate(general, buffer->line_widths,
sizeof(f32)*buffer->widths_count, sizeof(f32)*new_max, BUBBLE_WIDTHS);
}
else{
buffer->line_widths = (f32*)
general_memory_allocate(general, sizeof(f32)*new_max, BUBBLE_WIDTHS);
}
buffer->widths_max = new_max;
}
}
#endif
internal void internal void
file_remeasure_widths_(System_Functions *system, file_remeasure_widths_(System_Functions *system,
General_Memory *general, Buffer_Type *buffer, Render_Font *font, General_Memory *general, Buffer_Type *buffer, Render_Font *font,
@ -1498,25 +1477,6 @@ view_set_widget(File_View *view, File_View_Widget_Type type){
} }
#if 0
inline i32
view_widget_height(File_View *view, i32 font_height){
i32 result = 0;
switch (view->widget.type){
case FWIDG_NONE:
{
Query_Slot *slot;
for (slot = view->query_set.used_slot; slot != 0; slot = slot->next){
result += view->font_height + 2;
}
}
break;
case FWIDG_TIMELINES: result = view->widget.height; break;
}
return result;
}
#endif
inline i32_Rect inline i32_Rect
view_widget_rect(File_View *view, i32 font_height){ view_widget_rect(File_View *view, i32 font_height){
Panel *panel = view->view_base.panel; Panel *panel = view->view_base.panel;
@ -1526,13 +1486,6 @@ view_widget_rect(File_View *view, i32 font_height){
result.y0 = result.y0 + font_height + 2; result.y0 = result.y0 + font_height + 2;
} }
#if 0
if (view->file){
result.y0 = result.y0 + font_height + 2;
}
result.y1 = result.y0 + view_widget_height(view, font_height);
#endif
return(result); return(result);
} }
@ -2869,7 +2822,6 @@ interactive_view_complete(File_View *view){
case IAct_Save_As: case IAct_Save_As:
delayed_save_as(view->delay, view->hot_directory->string, panel); delayed_save_as(view->delay, view->hot_directory->string, panel);
view_show_file(view, 0);
break; break;
case IAct_New: case IAct_New:
@ -2899,9 +2851,9 @@ interactive_view_complete(File_View *view){
delayed_kill(view->delay, view->dest, panel); delayed_kill(view->delay, view->dest, panel);
break; break;
} }
view_show_file(view, 0);
break; break;
} }
view_show_file(view, 0);
} }
internal void internal void
@ -3513,7 +3465,6 @@ config_shit(File_View *view, UI_State *state, UI_Layout *layout){
internal i32 internal i32
step_file_view(System_Functions *system, Exchange *exchange, View *view_, i32_Rect rect, step_file_view(System_Functions *system, Exchange *exchange, View *view_, i32_Rect rect,
b32 is_active, Input_Summary *user_input){ b32 is_active, Input_Summary *user_input){
view_->mouse_cursor_type = APP_MOUSE_CURSOR_IBEAM;
i32 result = 0; i32 result = 0;
File_View *view = (File_View*)view_; File_View *view = (File_View*)view_;
@ -3565,13 +3516,6 @@ step_file_view(System_Functions *system, Exchange *exchange, View *view_, i32_Re
f32 extra_top = (f32)widget_height; f32 extra_top = (f32)widget_height;
f32 taken_top_space = line_height + extra_top; f32 taken_top_space = line_height + extra_top;
if (user_input->mouse.y < rect.y0 + taken_top_space){
view_->mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
}
else{
view_->mouse_cursor_type = APP_MOUSE_CURSOR_IBEAM;
}
if (user_input->mouse.wheel != 0){ if (user_input->mouse.wheel != 0){
f32 wheel_multiplier = 3.f; f32 wheel_multiplier = 3.f;
f32 delta_target_y = delta_y*user_input->mouse.wheel*wheel_multiplier; f32 delta_target_y = delta_y*user_input->mouse.wheel*wheel_multiplier;

View File

@ -9,55 +9,6 @@
// TOP // TOP
struct Interactive_Style{
u32 bar_color;
u32 bar_active_color;
u32 base_color;
u32 pop1_color;
u32 pop2_color;
};
struct Interactive_Bar{
Interactive_Style style;
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
i16 font_id;
};
enum View_Message{
VMSG_STEP,
VMSG_DRAW,
VMSG_RESIZE,
VMSG_STYLE_CHANGE,
VMSG_FREE
};
struct View;
#define Do_View_Sig(name) \
i32 (name)(System_Functions *system, Exchange *exchange, \
View *view, i32_Rect rect, View *active, \
View_Message message, Render_Target *target, \
Input_Summary *user_input, Input_Summary *active_input)
typedef Do_View_Sig(Do_View_Function);
struct Panel;
struct View{
View *next_free;
Panel *panel;
Command_Map *map;
Do_View_Function *do_view;
Application_Mouse_Cursor mouse_cursor_type;
};
struct Live_Views{
void *views;
View *free_view;
i32 count, max;
i32 stride;
};
struct Panel_Divider{ struct Panel_Divider{
Panel_Divider *next; Panel_Divider *next;
i32 parent; i32 parent;
@ -76,9 +27,15 @@ struct Screen_Region{
}; };
struct Panel{ struct Panel{
View *view; Panel *next;
Panel *prev;
struct View *view;
i32 parent; i32 parent;
i32 which_child; i32 which_child;
int ALLOCED;
union{ union{
struct{ struct{
i32_Rect full; i32_Rect full;
@ -93,6 +50,8 @@ struct Panel{
struct Editing_Layout{ struct Editing_Layout{
Panel *panels; Panel *panels;
Panel free_sentinel;
Panel used_sentinel;
Panel_Divider *dividers; Panel_Divider *dividers;
Panel_Divider *free_divider; Panel_Divider *free_divider;
i32 panel_count, panel_max_count; i32 panel_count, panel_max_count;
@ -101,86 +60,30 @@ struct Editing_Layout{
i32 full_width, full_height; i32 full_width, full_height;
}; };
internal void struct Divider_And_ID{
intbar_draw_string(Render_Target *target, Panel_Divider* divider;
Interactive_Bar *bar, u8 *str, u32 char_color){ i32 id;
i16 font_id = bar->font_id; };
draw_string(target, font_id, (char*)str, struct Panel_And_ID{
(i32)(bar->pos_x + bar->text_shift_x), Panel* panel;
(i32)(bar->pos_y + bar->text_shift_y), i32 id;
char_color); };
bar->pos_x += font_string_width(target, font_id, (char*)str);
}
internal void
intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
String str, u32 char_color){
i16 font_id = bar->font_id;
draw_string(target, font_id, str,
(i32)(bar->pos_x + bar->text_shift_x),
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, str);
}
internal void internal void
panel_init(Panel *panel){ panel_init(Panel *panel){
*panel = {}; panel->view = 0;
panel->parent = -1; panel->parent = -1;
panel->which_child = 0;
panel->screen_region.full = {};
panel->screen_region.inner = {};
panel->screen_region.prev_inner = {};
panel->l_margin = 3; panel->l_margin = 3;
panel->r_margin = 3; panel->r_margin = 3;
panel->t_margin = 3; panel->t_margin = 3;
panel->b_margin = 3; panel->b_margin = 3;
} }
internal View*
live_set_get_view(Live_Views *live_set, i32 i){
void *result = ((char*)live_set->views + i*live_set->stride);
return (View*)result;
}
internal View*
live_set_alloc_view(Live_Views *live_set, Mem_Options *mem){
Assert(live_set->count < live_set->max);
View *result = 0;
result = live_set->free_view;
live_set->free_view = result->next_free;
memset(result, 0, live_set->stride);
++live_set->count;
return result;
}
inline void
live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){
Assert(live_set->count > 0);
view->do_view(system, exchange, view, {}, 0, VMSG_FREE, 0, {}, 0);
view->next_free = live_set->free_view;
live_set->free_view = view;
--live_set->count;
}
inline void
view_set_first(View *new_view, Panel *panel){
new_view->panel = panel;
panel->view = new_view;
}
inline void
view_replace_major(System_Functions *system, Exchange *exchange,
View *new_view, Panel *panel, Live_Views *live_set){
View *view = panel->view;
live_set_free_view(system, exchange, live_set, view);
new_view->panel = panel;
panel->view = new_view;
}
struct Divider_And_ID{
Panel_Divider* divider;
i32 id;
};
internal Divider_And_ID internal Divider_And_ID
layout_alloc_divider(Editing_Layout *layout){ layout_alloc_divider(Editing_Layout *layout){
Divider_And_ID result; Divider_And_ID result;
@ -203,20 +106,13 @@ layout_alloc_divider(Editing_Layout *layout){
internal Divider_And_ID internal Divider_And_ID
layout_get_divider(Editing_Layout *layout, i32 id){ layout_get_divider(Editing_Layout *layout, i32 id){
Assert(id >= 0 && id < layout->panel_max_count-1);
Divider_And_ID result; Divider_And_ID result;
Assert(id >= 0 && id < layout->panel_max_count-1);
result.id = id; result.id = id;
result.divider = layout->dividers + id; result.divider = layout->dividers + id;
return result;
} return(result);
internal Panel*
layout_alloc_panel(Editing_Layout *layout){
Assert(layout->panel_count < layout->panel_max_count);
Panel *result = layout->panels + layout->panel_count;
*result = {};
++layout->panel_count;
return result;
} }
internal void internal void
@ -225,19 +121,33 @@ layout_free_divider(Editing_Layout *layout, Panel_Divider *divider){
layout->free_divider = divider; layout->free_divider = divider;
} }
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);
result.panel->ALLOCED = 1;
return(result);
}
internal void internal void
layout_free_panel(Editing_Layout *layout, Panel *panel){ layout_free_panel(Editing_Layout *layout, Panel *panel){
Panel *p, *panels; dll_remove(panel);
i32 panel_count, i; dll_insert(&layout->free_sentinel, panel);
--layout->panel_count;
panels = layout->panels; panel->ALLOCED = 0;
panel_count = --layout->panel_count;
p = panel;
for (i = (i32)(panel - layout->panels); i < panel_count; ++i, ++p){
*p = panels[i+1];
p->view->panel = p;
}
} }
internal Divider_And_ID internal Divider_And_ID
@ -257,7 +167,7 @@ internal Split_Result
layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){ layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){
Split_Result result = {}; Split_Result result = {};
Divider_And_ID div = {}, parent_div = {}; Divider_And_ID div = {}, parent_div = {};
Panel *new_panel = 0; Panel_And_ID new_panel = {};
div = layout_alloc_divider(layout); div = layout_alloc_divider(layout);
if (panel->parent != -1){ if (panel->parent != -1){
@ -284,71 +194,67 @@ layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){
new_panel = layout_alloc_panel(layout); new_panel = layout_alloc_panel(layout);
panel->parent = div.id; panel->parent = div.id;
panel->which_child = -1; panel->which_child = -1;
new_panel->parent = div.id; new_panel.panel->parent = div.id;
new_panel->which_child = 1; new_panel.panel->which_child = 1;
result.divider = div.divider; result.divider = div.divider;
result.panel = new_panel; result.panel = new_panel.panel;
return result; return result;
} }
internal void internal void
panel_fix_internal_area(Panel *panel){ panel_fix_internal_area(Panel *panel){
i32 left, right, top, bottom; panel->inner.x0 = panel->full.x0 + panel->l_margin;
left = panel->l_margin; panel->inner.x1 = panel->full.x1 - panel->r_margin;
right = panel->r_margin; panel->inner.y0 = panel->full.y0 + panel->t_margin;
top = panel->t_margin; panel->inner.y1 = panel->full.y1 - panel->b_margin;
bottom = panel->b_margin;
panel->inner.x0 = panel->full.x0 + left;
panel->inner.x1 = panel->full.x1 - right;
panel->inner.y0 = panel->full.y0 + top;
panel->inner.y1 = panel->full.y1 - bottom;
} }
internal void internal void
layout_fix_all_panels(Editing_Layout *layout){ layout_fix_all_panels(Editing_Layout *layout){
Panel *panels = layout->panels; Panel *panel;
if (layout->panel_count > 1){ Panel_Divider *dividers = layout->dividers;
Panel_Divider *dividers = layout->dividers; i32 panel_count = layout->panel_count;
int panel_count = layout->panel_count; i32_Rect r;
i32 pos, which_child, action;
Panel *panel = panels; Divider_And_ID div;
for (i32 i = 0; i < panel_count; ++i){
i32 x0, x1, y0, y1; if (panel_count > 1){
x0 = 0; for (panel = layout->used_sentinel.next;
x1 = x0 + layout->full_width; panel != &layout->used_sentinel;
y0 = 0; panel = panel->next){
y1 = y0 + layout->full_height;
r.x0 = 0;
i32 pos; r.x1 = r.x0 + layout->full_width;
i32 which_child = panel->which_child; r.y0 = 0;
Divider_And_ID div; r.y1 = r.y0 + layout->full_height;
which_child = panel->which_child;
div.id = panel->parent; div.id = panel->parent;
for (;;){ for (;;){
Assert(div.id != -1);
div.divider = dividers + div.id; div.divider = dividers + div.id;
pos = div.divider->pos; pos = div.divider->pos;
div.divider = dividers + div.id;
// NOTE(allen): sorry if this is hard to read through, there are action = (div.divider->v_divider << 1) | (which_child > 0);
// two binary conditionals that combine into four possible cases.
// Why am I appologizing to you? IF YOU CANT HANDLE MY CODE GET OUT!
i32 action = (div.divider->v_divider << 1) | (which_child > 0);
switch (action){ switch (action){
case 0: // v_divider : 0, which_child : -1 case 0: // v_divider : 0, which_child : -1
if (pos < y1) y1 = pos; if (pos < r.y1) r.y1 = pos;
break; break;
case 1: // v_divider : 0, which_child : 1 case 1: // v_divider : 0, which_child : 1
if (pos > y0) y0 = pos; if (pos > r.y0) r.y0 = pos;
break; break;
case 2: // v_divider : 1, which_child : -1 case 2: // v_divider : 1, which_child : -1
if (pos < x1) x1 = pos; if (pos < r.x1) r.x1 = pos;
break; break;
case 3: // v_divider : 1, which_child : 1 case 3: // v_divider : 1, which_child : 1
if (pos > x0) x0 = pos; if (pos > r.x0) r.x0 = pos;
break; break;
} }
if (div.id != layout->root){ if (div.id != layout->root){
div.id = div.divider->parent; div.id = div.divider->parent;
which_child = div.divider->which_child; which_child = div.divider->which_child;
@ -357,22 +263,19 @@ layout_fix_all_panels(Editing_Layout *layout){
break; break;
} }
} }
panel->full.x0 = x0; panel->full = r;
panel->full.y0 = y0;
panel->full.x1 = x1;
panel->full.y1 = y1;
panel_fix_internal_area(panel); panel_fix_internal_area(panel);
++panel;
} }
} }
else{ else{
panels[0].full.x0 = 0; panel = layout->used_sentinel.next;
panels[0].full.y0 = 0; panel->full.x0 = 0;
panels[0].full.x1 = layout->full_width; panel->full.y0 = 0;
panels[0].full.y1 = layout->full_height; panel->full.x1 = layout->full_width;
panel_fix_internal_area(panels); panel->full.y1 = layout->full_height;
panel_fix_internal_area(panel);
} }
} }
@ -406,20 +309,133 @@ layout_refit(Editing_Layout *layout, i32 prev_width, i32 prev_height){
layout_fix_all_panels(layout); layout_fix_all_panels(layout);
} }
inline real32 enum View_Message{
view_base_compute_width(View *view){ VMSG_STEP,
Panel *panel = view->panel; VMSG_DRAW,
return (real32)(panel->inner.x1 - panel->inner.x0); VMSG_RESIZE,
VMSG_STYLE_CHANGE,
VMSG_FREE
};
struct View;
#define Do_View_Sig(name) \
i32 (name)(System_Functions *system, Exchange *exchange, \
View *view, i32_Rect rect, View *active, \
View_Message message, Render_Target *target, \
Input_Summary *user_input, Input_Summary *active_input)
typedef Do_View_Sig(Do_View_Function);
struct View{
View *next, *prev;
Panel *panel;
Command_Map *map;
Do_View_Function *do_view;
};
struct Live_Views{
void *views;
View free_sentinel;
i32 count, max;
i32 stride;
};
struct View_And_ID{
View *view;
i32 id;
};
internal View*
live_set_get_view(Live_Views *live_set, i32 id){
void *result = ((char*)live_set->views + id);
return (View*)result;
} }
inline real32 internal View_And_ID
live_set_alloc_view(Live_Views *live_set, Mem_Options *mem){
View_And_ID result = {};
Assert(live_set->count < live_set->max);
++live_set->count;
result.view = live_set->free_sentinel.next;
result.id = (i32)((char*)result.view - (char*)live_set->views);
dll_remove(result.view);
memset(result.view, 0, live_set->stride);
return(result);
}
inline void
live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){
Assert(live_set->count > 0);
--live_set->count;
view->do_view(system, exchange, view, {}, 0, VMSG_FREE, 0, {}, 0);
dll_insert(&live_set->free_sentinel, view);
}
inline void
view_set_first(View *new_view, Panel *panel){
new_view->panel = panel;
panel->view = new_view;
}
inline f32
view_base_compute_width(View *view){
Panel *panel = view->panel;
return (f32)(panel->inner.x1 - panel->inner.x0);
}
inline f32
view_base_compute_height(View *view){ view_base_compute_height(View *view){
Panel *panel = view->panel; Panel *panel = view->panel;
return (real32)(panel->inner.y1 - panel->inner.y0); return (f32)(panel->inner.y1 - panel->inner.y0);
} }
#define view_compute_width(view) (view_base_compute_width(&(view)->view_base)) #define view_compute_width(view) (view_base_compute_width(&(view)->view_base))
#define view_compute_height(view) (view_base_compute_height(&(view)->view_base)) #define view_compute_height(view) (view_base_compute_height(&(view)->view_base))
struct Interactive_Style{
u32 bar_color;
u32 bar_active_color;
u32 base_color;
u32 pop1_color;
u32 pop2_color;
};
struct Interactive_Bar{
Interactive_Style style;
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
i16 font_id;
};
internal void
intbar_draw_string(Render_Target *target,
Interactive_Bar *bar, u8 *str, u32 char_color){
i16 font_id = bar->font_id;
draw_string(target, font_id, (char*)str,
(i32)(bar->pos_x + bar->text_shift_x),
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, (char*)str);
}
internal void
intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
String str, u32 char_color){
i16 font_id = bar->font_id;
draw_string(target, font_id, str,
(i32)(bar->pos_x + bar->text_shift_x),
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, str);
}
// BOTTOM // BOTTOM

41
4ed_template.cpp Normal file
View File

@ -0,0 +1,41 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 01.03.2016
*
* Templated code.
*
*/
// TOP
// NOTE(allen): This is an experiment, BUT remember a lot of people shit on templates.
// So if you start getting a wiff of stupidity from this back out immediately!
template<typename T>
inline void
dll_init_sentinel(T *sentinel){
sentinel->next = sentinel;
sentinel->prev = sentinel;
}
template<typename T>
inline void
dll_insert(T *pos, T *v){
v->next = pos->next;
v->prev = pos;
pos->next = v;
v->next->prev = v;
}
template<typename T>
inline void
dll_remove(T *v){
v->next->prev = v->prev;
v->prev->next = v->next;
}
#define dll_items(it, st) ((it) = (st)->next); ((it) != (st)); ((it) = (it)->next)
// BOTTOM