eliminated null views (I think)

This commit is contained in:
Allen Webster 2016-02-29 22:57:55 -05:00
parent 80d34d26dd
commit bbc737f7c5
7 changed files with 632 additions and 678 deletions

View File

@ -704,16 +704,10 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){
exec_command(app, cmdid_auto_tab_line_at_cursor);
}
#include "custom_casey.cpp"
extern "C" GET_BINDING_DATA(get_bindings){
Bind_Helper context_actual = begin_bind_helper(data, size);
Bind_Helper *context = &context_actual;
#if 1
casey_get_bindings(context);
#else
// NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are
// global and once set they always apply, regardless of what map is active.
set_hook(context, hook_start, my_start);
@ -850,7 +844,6 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, ' ', MDFR_SHIFT, cmdid_write_character);
end_map(context);
#endif
end_bind_helper(context);

387
4ed.cpp
View File

@ -945,6 +945,29 @@ COMMAND_DECL(interactive_open){
}
}
internal void
panel_make_empty(System_Functions *system, Exchange *exchange,
App_Vars *vars, Style *style, Panel *panel){
Mem_Options *mem = &vars->mem;
Live_Views *live_set = &vars->live_set;
Editing_Layout *layout = &vars->layout;
View *new_view;
File_View *file_view;
new_view = live_set_alloc_view(live_set, mem);
if (panel->view){
view_replace_major(system, exchange, new_view, panel, live_set);
}
else{
view_set_first(new_view, panel);
}
file_view = file_view_init(new_view, layout);
view_set_file(file_view, 0, vars->font_set, style, 0, 0, 0);
new_view->map = app_get_map(vars, mapid_global);
}
internal void
view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
Live_Views *live_set = cmd->live_set;
@ -955,20 +978,25 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
App_Vars *vars = cmd->vars;
Style *style = cmd->style;
View *new_view = live_set_alloc_view(live_set, mem);
Partition old_part;
Temp_Memory temp;
View *new_view, *old_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 = file_view_init(new_view, layout);
file_view = file_view_init(new_view, layout);
View *old_view = cmd->view;
old_view = cmd->view;
cmd->view = new_view;
Partition old_part = cmd->part;
Temp_Memory temp = begin_temp_memory(&mem->part);
old_part = cmd->part;
temp = begin_temp_memory(&mem->part);
cmd->part = partition_sub_part(&mem->part, Kbytes(16));
view_set_file(system, file_view, file, vars->font_set,
style, vars->hooks[hook_open_file], cmd, &app_links);
view_set_file(file_view, file, vars->font_set, style,
system, vars->hooks[hook_open_file], &app_links);
cmd->part = old_part;
end_temp_memory(temp);
@ -997,8 +1025,8 @@ COMMAND_DECL(reopen){
index = working_set_get_index(working_set, file);
app_push_file_binding(vars, file_id, index);
view_set_file(system, view, file, vars->font_set, style,
vars->hooks[hook_open_file], command, &app_links);
view_set_file(view, file, vars->font_set, style,
system, vars->hooks[hook_open_file], &app_links);
}
else{
// TODO(allen): feedback message
@ -1352,9 +1380,11 @@ COMMAND_DECL(open_panel_vsplit){
ProfileMomentFunction();
USE_LAYOUT(layout);
USE_PANEL(panel);
USE_EXCHANGE(exchange);
USE_VARS(vars);
USE_STYLE(style);
i32 panel_count = layout->panel_count;
if (panel_count < layout->panel_max_count){
if (layout->panel_count < layout->panel_max_count){
Split_Result split = layout_split_panel(layout, panel, 1);
Panel *panel1 = panel;
@ -1371,6 +1401,7 @@ COMMAND_DECL(open_panel_vsplit){
panel2->prev_inner = panel2->inner;
layout->active_panel = (i32)(panel2 - layout->panels);
panel_make_empty(system, exchange, vars, style, panel2);
}
}
@ -1378,9 +1409,11 @@ COMMAND_DECL(open_panel_hsplit){
ProfileMomentFunction();
USE_LAYOUT(layout);
USE_PANEL(panel);
USE_EXCHANGE(exchange);
USE_VARS(vars);
USE_STYLE(style);
i32 panel_count = layout->panel_count;
if (panel_count < layout->panel_max_count){
if (layout->panel_count < layout->panel_max_count){
Split_Result split = layout_split_panel(layout, panel, 0);
Panel *panel1 = panel;
@ -1397,6 +1430,7 @@ COMMAND_DECL(open_panel_hsplit){
panel2->prev_inner = panel2->inner;
layout->active_panel = (i32)(panel2 - layout->panels);
panel_make_empty(system, exchange, vars, style, panel2);
}
}
@ -1868,15 +1902,6 @@ build(System_Functions *system, Mem_Options *mem,
table_add(&working_set->table, file->name.source_path, index);
if (bind_to_new_view){
#if 0
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(system, exchange, new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, layout);
view_set_file(system, file_view, file, font_set, style,
vars->hooks[hook_open_file], command, &app_links);
new_view->map = app_get_map(vars, file->settings.base_map_id);
#endif
view_file_in_panel(command, panel, file);
}
@ -2429,8 +2454,8 @@ extern "C"{
if (buffer_id >= 0 && buffer_id < max){
file = working_set->files + buffer_id;
if (!file->state.is_dummy){
view_set_file(cmd->system, file_view, file, cmd->vars->font_set, cmd->style,
cmd->vars->hooks[hook_open_file], cmd, &app_links);
view_set_file(file_view, file, cmd->vars->font_set, cmd->style,
cmd->system, cmd->vars->hooks[hook_open_file], &app_links);
}
}
@ -3077,74 +3102,77 @@ App_Init_Sig(app_init){
Partition *partition = &vars->mem.part;
target->partition = partition;
i32 panel_max_count = vars->layout.panel_max_count = 16;
i32 divider_max_count = panel_max_count - 1;
Panel *panels;
Panel_Divider *dividers, *div;
i32 panel_max_count;
i32 divider_max_count;
panel_max_count = vars->layout.panel_max_count = 16;
divider_max_count = panel_max_count - 1;
vars->layout.panel_count = 1;
Panel *panels = vars->layout.panels =
push_array(partition, Panel, panel_max_count);
panels = push_array(partition, Panel, panel_max_count);
vars->layout.panels = panels;
Panel_Divider *dividers = vars->layout.dividers =
push_array(partition, Panel_Divider, divider_max_count);
dividers = push_array(partition, Panel_Divider, divider_max_count);
vars->layout.dividers = dividers;
Panel_Divider *divider = dividers;
for (i32 i = 0; i < divider_max_count-1; ++i, ++divider){
divider->next_free = (divider + 1);
div = dividers;
for (i32 i = 0; i < divider_max_count-1; ++i, ++div){
div->next = (div + 1);
}
divider->next_free = 0;
div->next = 0;
vars->layout.free_divider = dividers;
vars->live_set.count = 0;
vars->live_set.max = 1 + 2*panel_max_count;
i32 view_chunk_size = 0;
i32 view_sizes[] = {
sizeof(File_View),
sizeof(Color_View),
sizeof(Interactive_View),
sizeof(Menu_View),
#if FRED_INTERNAL
sizeof(Config_View),
sizeof(Debug_View),
#endif
};
i32 view_chunk_size = 0;
for (i32 i = 0; i < ArrayCount(view_sizes); ++i){
view_chunk_size = Max(view_chunk_size, view_sizes[i]);
}
vars->live_set.stride = view_chunk_size;
vars->live_set.views = (File_View*)
push_block(partition, view_chunk_size*vars->live_set.max);
char *views_ = (char*)vars->live_set.views;
for (i32 i = panel_max_count-2; i >= 0; --i){
View *view = (View*)(views_ + i*view_chunk_size);
View *view_next = (View*)((char*)view + view_chunk_size);
view->next_free = view_next;
}
{
View *view = (View*)(views_ + (panel_max_count-1)*view_chunk_size);
view->next_free = 0;
char *vptr = 0;
View *v = 0, *n = 0;
i32 i = 0, max = 0;
vars->live_set.count = 0;
vars->live_set.max = 1 + 2*panel_max_count;
for (i = 0; i < ArrayCount(view_sizes); ++i){
view_chunk_size = Max(view_chunk_size, view_sizes[i]);
}
vars->live_set.stride = view_chunk_size;
vars->live_set.views = push_block(partition, view_chunk_size*vars->live_set.max);
max = vars->live_set.max;
vptr = (char*)vars->live_set.views;
vars->live_set.free_view = (View*)vptr;
for (i = 0; i < max; ++i){
v = (View*)(vptr);
n = (View*)(vptr + view_chunk_size);
v->next_free = n;
vptr = (char*)n;
}
v->next_free = 0;
}
vars->live_set.free_view = (View*)views_;
setup_command_table();
Command_Map *global = &vars->map_top;
Assert(vars->config_api.get_bindings != 0);
i32 size = partition_remaining(partition);
void *data = partition_current(partition);
// TODO(allen): Use a giant bubble of general memory for this.
// So that it doesn't interfere with the command maps as they allocate
// their own memory.
i32 wanted_size = vars->config_api.get_bindings(data, size);
i32 wanted_size = vars->config_api.get_bindings(app_links.memory, app_links.memory_size);
b32 did_top = 0;
b32 did_file = 0;
if (wanted_size <= size){
partition_allocate(partition, wanted_size);
Binding_Unit *unit = (Binding_Unit*)data;
if (wanted_size <= app_links.memory_size){
Binding_Unit *unit = (Binding_Unit*)app_links.memory;
if (unit->type == unit_header && unit->header.error == 0){
Binding_Unit *end = unit + unit->header.total_size;
@ -3243,10 +3271,11 @@ App_Init_Sig(app_init){
}
}
memset(app_links.memory, 0, wanted_size);
if (!did_top) setup_top_commands(&vars->map_top, &vars->mem.part, global);
if (!did_file) setup_file_commands(&vars->map_file, &vars->mem.part, global);
#if !defined(FRED_SUPER)
#if 1 || !defined(FRED_SUPER)
vars->hooks[hook_start] = 0;
#endif
@ -3348,7 +3377,9 @@ App_Init_Sig(app_init){
vars->palette_size = 40;
vars->palette = push_array(partition, u32, vars->palette_size);
// NOTE(allen): init first panel
panel_init(&panels[0]);
panel_make_empty(system, exchange, vars, &vars->style, &panels[0]);
String hdbase = make_fixed_width_string(vars->hot_dir_base_);
hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash);
@ -3477,29 +3508,34 @@ App_Step_Sig(app_step){
}
// NOTE(allen): reorganizing panels on screen
i32 prev_width = vars->layout.full_width;
i32 prev_height = vars->layout.full_height;
i32 prev_y_off = 0;
i32 prev_x_off = 0;
{
i32 prev_width = vars->layout.full_width;
i32 prev_height = vars->layout.full_height;
i32 current_width = target->width;
i32 current_height = target->height;
i32 y_off = 0;
i32 x_off = 0;
i32 full_width = vars->layout.full_width = target->width;
i32 full_height = vars->layout.full_height = target->height;
View *view;
File_View *fview;
i32 i, view_count;
if (prev_width != full_width || prev_height != full_height ||
prev_x_off != x_off || prev_y_off != y_off){
layout_refit(&vars->layout, prev_x_off, prev_y_off, prev_width, prev_height);
int view_count = vars->layout.panel_max_count;
for (i32 view_i = 0; view_i < view_count; ++view_i){
View *view_ = live_set_get_view(&vars->live_set, view_i);
if (!view_->is_active) continue;
File_View *view = view_to_file_view(view_);
if (!view) continue;
view_measure_wraps(system, &vars->mem.general, view);
view->cursor = view_compute_cursor_from_pos(view, view->cursor.pos);
vars->layout.full_width = current_width;
vars->layout.full_height = current_height;
view_count = vars->layout.panel_max_count;
if (prev_width != current_width || prev_height != current_height){
layout_refit(&vars->layout, prev_width, prev_height);
for (i = 0; i < view_count; ++i){
view = live_set_get_view(&vars->live_set, i);
if (!view->is_active) continue;
fview = view_to_file_view(view);
if (!fview) continue;
// TODO(allen): All responses to a panel changing size should
// be handled in the same place.
view_change_size(system, &vars->mem.general, fview);
}
app_result.redraw = 1;
}
app_result.redraw = 1;
}
// NOTE(allen): prepare input information
@ -3515,6 +3551,19 @@ App_Step_Sig(app_step){
ProfileEnd(OS_syncing);
// 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.
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);
// NOTE(allen): detect mouse hover status
i32 mx = mouse->x;
@ -4010,90 +4059,95 @@ App_Step_Sig(app_step){
// NOTE(allen): processing sys app bindings
ProfileStart(sys_app_bind_processing);
for (i32 i = 0; i < vars->sys_app_count; ++i){
Sys_App_Binding *binding;
b32 remove = 0;
b32 failed = 0;
binding = vars->sys_app_bindings + i;
{
Mem_Options *mem = &vars->mem;
General_Memory *general = &mem->general;
byte *data;
i32 size, max;
Editing_File *ed_file;
Editing_File_Preload preload_settings;
char *filename;
for (i32 i = 0; i < vars->sys_app_count; ++i){
Sys_App_Binding *binding;
b32 remove = 0;
b32 failed = 0;
binding = vars->sys_app_bindings + i;
Working_Set *working_set = &vars->working_set;
byte *data;
i32 size, max;
Editing_File *ed_file;
Editing_File_Preload preload_settings;
char *filename;
if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){
ed_file = working_set->files + binding->app_id;
filename = exchange_file_filename(exchange, binding->sys_id);
preload_settings = ed_file->preload;
if (data){
String val = make_string((char*)data, size);
file_create_from_string(system, &vars->mem, working_set, ed_file, filename,
vars->font_set, vars->style.font_id, val);
Working_Set *working_set = &vars->working_set;
if (ed_file->settings.tokens_exist){
file_first_lex_parallel(system, &vars->mem.general, ed_file);
}
if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){
ed_file = working_set->files + binding->app_id;
filename = exchange_file_filename(exchange, binding->sys_id);
preload_settings = ed_file->preload;
if (data){
String val = make_string((char*)data, size);
file_create_from_string(system, mem, working_set, ed_file, filename,
vars->font_set, vars->style.font_id, val);
if ((binding->success & SysAppCreateView) && binding->panel != 0){
view_file_in_panel(cmd, binding->panel, ed_file);
}
if (ed_file->settings.tokens_exist){
file_first_lex_parallel(system, general, ed_file);
}
app_result.redraw = 1;
}
else{
if (binding->fail & SysAppCreateNewBuffer){
file_create_empty(system, &vars->mem, working_set, ed_file, filename,
vars->font_set, vars->style.font_id);
if (binding->fail & SysAppCreateView){
if ((binding->success & SysAppCreateView) && binding->panel != 0){
view_file_in_panel(cmd, binding->panel, ed_file);
}
app_result.redraw = 1;
}
else{
table_remove(&vars->working_set.table, ed_file->name.source_path);
file_get_dummy(ed_file);
if (binding->fail & SysAppCreateNewBuffer){
file_create_empty(system, mem, working_set, ed_file, filename,
vars->font_set, vars->style.font_id);
if (binding->fail & SysAppCreateView){
view_file_in_panel(cmd, binding->panel, ed_file);
}
}
else{
table_remove(&vars->working_set.table, ed_file->name.source_path);
file_get_dummy(ed_file);
}
app_result.redraw = 1;
}
app_result.redraw = 1;
}
if (!ed_file->state.is_dummy){
for (File_View_Iter iter = file_view_iter_init(&vars->layout, ed_file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
view_file_loaded_init(system, iter.view, 0);
view_cursor_move(iter.view, preload_settings.start_line, 0);
if (!ed_file->state.is_dummy){
for (File_View_Iter iter = file_view_iter_init(&vars->layout, ed_file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
view_measure_wraps(system, general, iter.view);
view_cursor_move(iter.view, preload_settings.start_line, 0);
}
}
exchange_free_file(exchange, binding->sys_id);
remove = 1;
}
exchange_free_file(exchange, binding->sys_id);
remove = 1;
}
if (exchange_file_save_complete(exchange, binding->sys_id, &data, &size, &max, &failed)){
Assert(remove == 0);
if (exchange_file_save_complete(exchange, binding->sys_id, &data, &size, &max, &failed)){
Assert(remove == 0);
if (data){
general_memory_free(general, data);
exchange_clear_file(exchange, binding->sys_id);
}
if (data){
general_memory_free(&vars->mem.general, data);
exchange_clear_file(exchange, binding->sys_id);
Editing_File *file = get_file(working_set, binding->app_id);
if (file){
file_synchronize_times(system, file, file->name.source_path.str);
}
exchange_free_file(exchange, binding->sys_id);
remove = 1;
// if (failed) { TODO(allen): saving error, now what? }
}
Editing_File *file = get_file(working_set, binding->app_id);
if (file){
file_synchronize_times(system, file, file->name.source_path.str);
if (remove){
*binding = vars->sys_app_bindings[--vars->sys_app_count];
--i;
}
exchange_free_file(exchange, binding->sys_id);
remove = 1;
// if (failed) { TODO(allen): saving error, now what? }
}
if (remove){
*binding = vars->sys_app_bindings[--vars->sys_app_count];
--i;
}
}
ProfileEnd(sys_app_bind_processing);
@ -4173,8 +4227,8 @@ App_Step_Sig(app_step){
// TODO(allen): deduplicate
View *view = panel->view;
File_View *fview = view_to_file_view(view);
if (!fview && view->is_minor) fview = view_to_file_view(view->major);
if (!file){
if (!fview && view->is_minor) fview = view_to_file_view(view->major);
if (fview){
file = working_set_lookup_file(working_set, string);
}
@ -4194,8 +4248,8 @@ App_Step_Sig(app_step){
// TODO(allen): deduplicate
View *view = panel->view;
File_View *fview = view_to_file_view(view);
if (!fview && view->is_minor) fview = view_to_file_view(view->major);
if (!file){
if (!fview && view->is_minor) fview = view_to_file_view(view->major);
if (fview){
file = working_set_lookup_file(working_set, string);
}
@ -4215,8 +4269,12 @@ App_Step_Sig(app_step){
{
if (!file){
if (panel){
View *view = panel->view;
File_View *fview = view_to_file_view(view);
View *view;
File_View *fview;
view = panel->view;
Assert(view);
if (view->is_minor) view = view->major;
fview = view_to_file_view(view);
if (fview){
file = fview->file;
}
@ -4225,9 +4283,13 @@ App_Step_Sig(app_step){
file = working_set_lookup_file(working_set, string);
}
}
if (!file->state.is_dummy && buffer_needs_save(file)){
// TODO(allen): We could handle the case where someone tries to save the same thing
// twice... that would be nice to have under control.
if (file && !file->state.is_dummy && buffer_needs_save(file)){
i32 sys_id = file_save(system, exchange, mem, file, file->name.source_path.str);
if (sys_id){
// TODO(allen): This is fishy! Shouldn't we bind it to a file name instead? This file
// might be killed before we get notified that the saving is done!
app_push_file_binding(vars, sys_id, get_file_id(working_set, file));
}
else{
@ -4248,8 +4310,8 @@ App_Step_Sig(app_step){
File_View *file_view = file_view_init(new_view, &vars->layout);
cmd->view = (View*)file_view;
view_set_file(system, file_view, file.file, vars->font_set, style,
vars->hooks[hook_open_file], cmd, &app_links);
view_set_file(file_view, file.file, vars->font_set, style,
system, vars->hooks[hook_open_file], &app_links);
new_view->map = app_get_map(vars, file.file->settings.base_map_id);
#if BUFFER_EXPERIMENT_SCALPEL <= 0
if (file.file->settings.tokens_exist)
@ -4267,8 +4329,8 @@ App_Step_Sig(app_step){
File_View *file_view = file_view_init(new_view, &vars->layout);
cmd->view = (View*)file_view;
view_set_file(system, file_view, file, vars->font_set, style,
vars->hooks[hook_open_file], cmd, &app_links);
view_set_file(file_view, file, vars->font_set, style,
system, vars->hooks[hook_open_file], &app_links);
new_view->map = app_get_map(vars, file->settings.base_map_id);
}
@ -4313,11 +4375,6 @@ App_Step_Sig(app_step){
view_remove_minor(system, exchange, panel, live_set);
}break;
case DACT_CLOSE_MAJOR:
{
view_remove_major(system, exchange, panel, live_set);
}break;
case DACT_THEME_OPTIONS:
{
open_theme_options(system, exchange, vars, live_set, mem, panel);

View File

@ -9,7 +9,6 @@ enum Action_Type{
DACT_TRY_KILL,
DACT_KILL,
DACT_CLOSE_MINOR,
DACT_CLOSE_MAJOR,
DACT_THEME_OPTIONS,
DACT_KEYBOARD_OPTIONS,
};
@ -115,6 +114,5 @@ delayed_action_repush(Delay *delay, Delayed_Action *act){
#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__)
#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__)
#define delayed_close_minor(delay, ...) delayed_action_(delay, DACT_CLOSE_MINOR, __VA_ARGS__)
#define delayed_close_major(delay, ...) delayed_action_(delay, DACT_CLOSE_MAJOR, __VA_ARGS__)
#define delayed_theme_options(delay, ...) delayed_action_(delay, DACT_THEME_OPTIONS, __VA_ARGS__)
#define delayed_keyboard_options(delay, ...) delayed_action_(delay, DACT_KEYBOARD_OPTIONS, __VA_ARGS__)

View File

@ -45,13 +45,6 @@ enum Link_Type{
link_type_count
};
struct Hyper_Link{
char *file_name;
i32 line_number;
i32 start, end;
Link_Type link_type;
};
struct File_View{
View view_base;
@ -94,9 +87,6 @@ struct File_View{
i32 line_count, line_max;
f32 *line_wrap_y;
Hyper_Link *links;
i32 link_count, link_max;
};
inline File_View*
@ -1311,67 +1301,87 @@ view_get_cursor_y(File_View *view){
}
internal void
view_file_loaded_init(System_Functions *system, File_View *view, i32 cursor_pos){
General_Memory *general = &view->view_base.mem->general;
view_set_file(
// NOTE(allen): These parameters are always meaningful
File_View *view,
Editing_File *file,
Font_Set *set,
Style *style,
view_measure_wraps(system, general, view);
view->cursor = view_compute_cursor_from_pos(view, cursor_pos);
}
// NOTE(allen): Necessary when file != 0
System_Functions *system,
Hook_Function *open_hook,
Application_Links *app){
internal void
view_set_file(System_Functions *system, File_View *view,
Editing_File *file, Font_Set *set, Style *style,
Hook_Function *open_hook, void *cmd_context, Application_Links *app){
Panel *panel = view->view_base.panel;
view->file = file;
view->locked = file->settings.super_locked;
Panel *panel;
Font_Info *fnt_info;
Font_Info *info = get_font_info(set, style->font_id);
view->style = style;
view->font_advance = info->advance;
view->font_height = info->height;
view->font_set = set;
view->unwrapped_lines = file->settings.unwrapped_lines;
file->settings.set = set;
view->cursor = {};
if (!file->state.is_loading){
view_file_loaded_init(system, view, file->state.cursor_pos);
}
f32 cursor_x, cursor_y;
f32 w, h;
f32 cursor_x, cursor_y;
f32 target_x, target_y;
cursor_x = view_get_cursor_x(view);
cursor_y = view_get_cursor_y(view);
panel = view->view_base.panel;
w = (f32)(panel->inner.x1 - panel->inner.x0);
h = (f32)(panel->inner.y1 - panel->inner.y0);
// NOTE(allen): This is actually more like view_set_style right?
fnt_info = get_font_info(set, style->font_id);
view->style = style;
view->font_advance = fnt_info->advance;
view->font_height = fnt_info->height;
view->font_set = set;
// NOTE(allen): Stuff that doesn't assume file exists.
view->file = file;
view->cursor = {};
view->vel_y = 1.f;
view->vel_x = 1.f;
target_x = 0;
if (cursor_x < target_x){
target_x = (f32)Max(0, cursor_x - w*.5f);
}
else if (cursor_x >= target_x + w){
target_x = (f32)(cursor_x - w*.5f);
target_y = 0;
// NOTE(allen): Stuff that does assume file exists.
if (file){
// NOTE(allen): Isn't this a bit clumsy?
file->settings.set = set;
view->locked = file->settings.super_locked;
view->unwrapped_lines = file->settings.unwrapped_lines;
if (file_is_ready(file)){
view_measure_wraps(system, &view->view_base.mem->general, view);
view->cursor = view_compute_cursor_from_pos(view, file->state.cursor_pos);
cursor_x = view_get_cursor_x(view);
cursor_y = view_get_cursor_y(view);
w = (f32)(panel->inner.x1 - panel->inner.x0);
h = (f32)(panel->inner.y1 - panel->inner.y0);
Assert(cursor_x >= target_x);
if (cursor_x >= target_x + w){
target_x = (f32)(cursor_x - w*.5f);
}
target_y = (f32)FLOOR32(cursor_y - h*.5f);
if (target_y < 0) target_y = 0;
}
}
target_y = (f32)FLOOR32(cursor_y - h*.5f);
if (target_y < 0) target_y = 0;
// NOTE(allen): More stuff that doesn't assume file exists, but that
// has to come after computing target_x, target_y
view->target_x = target_x;
view->target_y = target_y;
view->scroll_x = target_x;
view->scroll_y = target_y;
view->vel_y = 1.f;
view->vel_x = 1.f;
if (open_hook && file->settings.is_initialized == 0){
open_hook(app);
file->settings.is_initialized = 1;
// TODO(allen): Bypass all this nonsense, it's a hack! Hooks need parameters!
// Just accept it and pass the file to the open hook when it is loaded.
if (file){
if (open_hook && file->settings.is_initialized == 0){
open_hook(app);
file->settings.is_initialized = 1;
}
}
}
@ -1461,11 +1471,11 @@ view_widget_height(File_View *view, i32 font_height){
inline i32_Rect
view_widget_rect(File_View *view, i32 font_height){
Panel *panel = view->view_base.panel;
i32_Rect whole = panel->inner;
i32_Rect result;
result.x0 = whole.x0;
result.x1 = whole.x1;
result.y0 = whole.y0 + font_height + 2;
i32_Rect result = panel->inner;
if (view->file){
result.y0 = result.y0 + font_height + 2;
}
result.y1 = result.y0 + view_widget_height(view, font_height);
return result;
@ -1481,7 +1491,7 @@ debug_edit_step_check(Edit_Step a, Edit_Step b){
Assert(a.edit.start == b.edit.start);
Assert(a.edit.end == b.edit.end);
Assert(a.edit.len == b.edit.len);
return 1;
return(1);
}
#endif
@ -2587,13 +2597,6 @@ struct Get_Link_Result{
i32 index;
};
internal Get_Link_Result
get_link(Hyper_Link *links, i32 link_count, i32 pos){
Get_Link_Result result = {};
// TODO TODO TODO TODO TODO TODO TODO TODO
return result;
}
internal u32*
style_get_link_color(Style *style, Link_Type type){
u32 *result;
@ -2728,6 +2731,66 @@ remeasure_file_view(System_Functions *system, View *view_, i32_Rect rect){
}
}
internal void
undo_shit(System_Functions *system, File_View *view, UI_State *state, UI_Layout *layout,
i32 total_count, i32 undo_count, i32 scrub_max){
View *view_ = (View*)view;
Editing_File *file = view->file;
if (view->widget.timeline.undo_line){
if (do_button(1, state, layout, "- Undo", 1)){
view->widget.timeline.undo_line = 0;
}
if (view->widget.timeline.undo_line){
Widget_ID wid = make_id(state, 2);
i32 new_count;
if (do_undo_slider(wid, state, layout, total_count, undo_count, 0, &new_count)){
for (i32 i = 0; i < scrub_max && new_count < undo_count; ++i){
view_undo(system, view_->mem, view->layout, view);
--undo_count;
}
for (i32 i = 0; i < scrub_max && new_count > undo_count; ++i){
view_redo(system, view_->mem, view->layout, view);
++undo_count;
}
}
}
}
else{
if (do_button(1, state, layout, "+ Undo", 1)){
view->widget.timeline.undo_line = 1;
}
}
if (view->widget.timeline.history_line){
if (do_button(3, state, layout, "- History", 1)){
view->widget.timeline.history_line = 0;
}
Widget_ID wid = make_id(state, 4);
if (view->widget.timeline.history_line){
i32 new_count;
i32 mid = ((file->state.undo.history.edit_count + file->state.undo.edit_history_cursor) >> 1);
i32 count = file->state.undo.edit_history_cursor;
if (do_undo_slider(wid, state, layout, mid, count, &file->state.undo, &new_count)){
for (i32 i = 0; i < scrub_max && new_count < count; ++i){
view_history_step(system, view_->mem, view->layout, view, hist_backward);
}
for (i32 i = 0; i < scrub_max && new_count > count; ++i){
view_history_step(system, view_->mem, view->layout, view, hist_forward);
}
}
}
}
else{
if (do_button(3, state, layout, "+ History", 1)){
view->widget.timeline.history_line = 1;
}
}
}
internal i32
step_file_view(System_Functions *system, View *view_, i32_Rect rect,
b32 is_active, Input_Summary *user_input){
@ -2736,179 +2799,122 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect,
File_View *view = (File_View*)view_;
Editing_File *file = view->file;
if (file->state.is_loading){
return result;
}
if (file && !file->state.is_loading){
f32 line_height = (f32)view->font_height;
f32 cursor_y = view_get_cursor_y(view);
f32 target_y = view->target_y;
f32 max_y = view_compute_height(view) - line_height*2;
i32 lowest_line = view_compute_lowest_line(view);
f32 max_target_y = view_compute_max_target_y(lowest_line, (i32)line_height, max_y);
f32 delta_y = 3.f*line_height;
f32 extra_top = (f32)view_widget_height(view, (i32)line_height);
f32 taken_top_space = line_height + extra_top;
f32 line_height = (f32)view->font_height;
f32 cursor_y = view_get_cursor_y(view);
f32 target_y = view->target_y;
f32 max_y = view_compute_height(view) - line_height*2;
i32 lowest_line = view_compute_lowest_line(view);
f32 max_target_y = view_compute_max_target_y(lowest_line, (i32)line_height, max_y);
f32 delta_y = 3.f*line_height;
f32 extra_top = 0.f;
extra_top += view_widget_height(view, (i32)line_height);
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){
f32 wheel_multiplier = 3.f;
f32 delta_target_y = delta_y*user_input->mouse.wheel*wheel_multiplier;
target_y += delta_target_y;
if (target_y < -taken_top_space) target_y = -taken_top_space;
if (target_y > max_target_y) target_y = max_target_y;
real32 old_cursor_y = cursor_y;
if (cursor_y >= target_y + max_y) cursor_y = target_y + max_y;
if (cursor_y < target_y + taken_top_space) cursor_y = target_y + taken_top_space;
if (cursor_y != old_cursor_y){
view->cursor =
view_compute_cursor_from_xy(view,
view->preferred_x,
cursor_y);
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;
}
result = 1;
}
if (user_input->mouse.wheel != 0){
f32 wheel_multiplier = 3.f;
f32 delta_target_y = delta_y*user_input->mouse.wheel*wheel_multiplier;
target_y += delta_target_y;
if (cursor_y > target_y + max_y){
target_y = cursor_y - max_y + delta_y;
}
if (cursor_y < target_y + taken_top_space){
target_y = cursor_y - delta_y - taken_top_space;
}
if (target_y < -taken_top_space) target_y = -taken_top_space;
if (target_y > max_target_y) target_y = max_target_y;
if (target_y > max_target_y) target_y = max_target_y;
if (target_y < -extra_top) target_y = -extra_top;
view->target_y = target_y;
real32 old_cursor_y = cursor_y;
if (cursor_y >= target_y + max_y) cursor_y = target_y + max_y;
if (cursor_y < target_y + taken_top_space) cursor_y = target_y + taken_top_space;
f32 cursor_x = view_get_cursor_x(view);
f32 target_x = view->target_x;
f32 max_x = view_compute_width(view);
if (cursor_x < target_x){
target_x = (f32)Max(0, cursor_x - max_x/2);
}
else if (cursor_x >= target_x + max_x){
target_x = (f32)(cursor_x - max_x/2);
}
view->target_x = target_x;
if (smooth_camera_step(&view->target_y, &view->scroll_y, &view->vel_y, 40.f, 1.f/4.f)){
result = 1;
}
if (smooth_camera_step(&view->target_x, &view->scroll_x, &view->vel_x, 40.f, 1.f/4.f)){
result = 1;
}
if (file->state.paste_effect.tick_down > 0){
--file->state.paste_effect.tick_down;
result = 1;
}
if (is_active && user_input->mouse.press_l){
f32 max_y = view_compute_height(view);
f32 rx = (f32)(user_input->mouse.x - rect.x0);
f32 ry = (f32)(user_input->mouse.y - rect.y0 - line_height - 2);
if (ry >= extra_top){
view_set_widget(view, FWIDG_NONE);
if (rx >= 0 && rx < max_x && ry >= 0 && ry < max_y){
view_cursor_move(view, rx + view->scroll_x, ry + view->scroll_y, 1);
view->mode = {};
if (cursor_y != old_cursor_y){
view->cursor =
view_compute_cursor_from_xy(view,
view->preferred_x,
cursor_y);
}
result = 1;
}
result = 1;
}
if (!is_active) view_set_widget(view, FWIDG_NONE);
if (cursor_y > target_y + max_y){
target_y = cursor_y - max_y + delta_y;
}
if (cursor_y < target_y + taken_top_space){
target_y = cursor_y - delta_y - taken_top_space;
}
// NOTE(allen): framely undo stuff
if (file){
if (target_y > max_target_y) target_y = max_target_y;
if (target_y < -extra_top) target_y = -extra_top;
view->target_y = target_y;
f32 cursor_x = view_get_cursor_x(view);
f32 target_x = view->target_x;
f32 max_x = view_compute_width(view);
if (cursor_x < target_x){
target_x = (f32)Max(0, cursor_x - max_x/2);
}
else if (cursor_x >= target_x + max_x){
target_x = (f32)(cursor_x - max_x/2);
}
view->target_x = target_x;
if (smooth_camera_step(&view->target_y, &view->scroll_y, &view->vel_y, 40.f, 1.f/4.f)){
result = 1;
}
if (smooth_camera_step(&view->target_x, &view->scroll_x, &view->vel_x, 40.f, 1.f/4.f)){
result = 1;
}
if (file->state.paste_effect.tick_down > 0){
--file->state.paste_effect.tick_down;
result = 1;
}
if (is_active && user_input->mouse.press_l){
f32 max_y = view_compute_height(view);
f32 rx = (f32)(user_input->mouse.x - rect.x0);
f32 ry = (f32)(user_input->mouse.y - rect.y0 - line_height - 2);
if (ry >= extra_top){
view_set_widget(view, FWIDG_NONE);
if (rx >= 0 && rx < max_x && ry >= 0 && ry < max_y){
view_cursor_move(view, rx + view->scroll_x, ry + view->scroll_y, 1);
view->mode = {};
}
}
result = 1;
}
if (!is_active) view_set_widget(view, FWIDG_NONE);
// NOTE(allen): framely undo stuff
i32 scrub_max = view->scrub_max;
i32 undo_count, redo_count, total_count;
undo_count = file->state.undo.undo.edit_count;
redo_count = file->state.undo.redo.edit_count;
total_count = undo_count + redo_count;
i32 undo_count = file->state.undo.undo.edit_count;
i32 redo_count = file->state.undo.redo.edit_count;
i32 total_count = undo_count + redo_count;
switch (view->widget.type){
case FWIDG_TIMELINES:
{
i32_Rect widg_rect = view_widget_rect(view, view->font_height);
case FWIDG_TIMELINES:
{
i32_Rect widg_rect = view_widget_rect(view, view->font_height);
UI_State state =
ui_state_init(&view->widget.state, 0, user_input,
view->style, view->font_set, 0, 1);
UI_State state =
ui_state_init(&view->widget.state, 0, user_input,
view->style, view->font_set, 0, 1);
UI_Layout layout;
begin_layout(&layout, widg_rect);
UI_Layout layout;
begin_layout(&layout, widg_rect);
undo_shit(system, view, &state, &layout, total_count, undo_count, scrub_max);
if (view->widget.timeline.undo_line){
if (do_button(1, &state, &layout, "- Undo", 1)){
view->widget.timeline.undo_line = 0;
view->widget.height = layout.y - widg_rect.y0;
if (ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0)){
result = 1;
}
if (view->widget.timeline.undo_line){
Widget_ID wid = make_id(&state, 2);
i32 new_count;
if (do_undo_slider(wid, &state, &layout, total_count, undo_count, 0, &new_count)){
for (i32 i = 0; i < scrub_max && new_count < undo_count; ++i){
view_undo(system, view_->mem, view->layout, view);
--undo_count;
}
for (i32 i = 0; i < scrub_max && new_count > undo_count; ++i){
view_redo(system, view_->mem, view->layout, view);
++undo_count;
}
}
}
}
else{
if (do_button(1, &state, &layout, "+ Undo", 1)){
view->widget.timeline.undo_line = 1;
}
}
if (view->widget.timeline.history_line){
if (do_button(3, &state, &layout, "- History", 1)){
view->widget.timeline.history_line = 0;
}
Widget_ID wid = make_id(&state, 4);
if (view->widget.timeline.history_line){
i32 new_count;
i32 mid = ((file->state.undo.history.edit_count + file->state.undo.edit_history_cursor) >> 1);
i32 count = file->state.undo.edit_history_cursor;
if (do_undo_slider(wid, &state, &layout, mid, count, &file->state.undo, &new_count)){
for (i32 i = 0; i < scrub_max && new_count < count; ++i){
view_history_step(system, view_->mem, view->layout, view, hist_backward);
}
for (i32 i = 0; i < scrub_max && new_count > count; ++i){
view_history_step(system, view_->mem, view->layout, view, hist_forward);
}
}
}
}
else{
if (do_button(3, &state, &layout, "+ History", 1)){
view->widget.timeline.history_line = 1;
}
}
view->widget.height = layout.y - widg_rect.y0;
if (ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0)){
result = 1;
}
}break;
}break;
}
}
@ -2969,16 +2975,26 @@ draw_file_bar(File_View *view, Interactive_Bar *bar, Render_Target *target){
}
}
internal void
draw_file_view_queries(File_View *view, UI_State *state, UI_Layout *layout){
Widget_ID wid;
Query_Slot *slot;
Query_Bar *bar;
i32 i = 1;
for (slot = view->query_set.used_slot; slot != 0; slot = slot->next){
wid = make_id(state, i++);
bar = slot->query_bar;
do_text_field(wid, state, layout, bar->prompt, bar->string);
}
}
internal i32
draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *target){
Editing_File *file = view->file;
Style *style = view->style;
i32 line_height = view->font_height;
Interactive_Bar bar;
draw_file_setup_bar(style, line_height, &bar, &rect);
#if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 max_x = rect.x1 - rect.x0;
i32 max_y = rect.y1 - rect.y0 + line_height;
@ -2991,17 +3007,6 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
token_stack = file->state.token_stack;
}
b32 links_use = 0;
Hyper_Link *links = 0;
i32 link_count = 0;
if (view->links){
if (view->link_count > 0){
links_use = 1;
links = view->links;
link_count = view->link_count;
}
}
Partition *part = &view->view_base.mem->part;
Temp_Memory temp = begin_temp_memory(part);
@ -3056,22 +3061,13 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
}
i32 token_i = 0;
i32 link_i = 0;
u32 main_color = style->main.default_color;
u32 special_color = style->main.special_character_color;
u32 link_color = 0;
if (tokens_use){
Cpp_Get_Token_Result result = cpp_get_token(&token_stack, items->index);
main_color = *style_get_color(style, token_stack.tokens[result.token_index]);
token_i = result.token_index + 1;
}
if (links_use){
Get_Link_Result result = get_link(links, link_count, items->index);
if (result.in_link){
link_color = *style_get_link_color(style, links[result.index].link_type);
}
link_i = result.index;
}
u32 mark_color = style->main.mark_color;
Buffer_Render_Item *item = items;
@ -3156,12 +3152,27 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
}
end_temp_memory(temp);
#endif
#if 0
ui_render(target, view->gui_target);
#else
UI_Style ui_style = get_ui_style_upper(style);
return(0);
}
internal i32
draw_file_view(View *view_, i32_Rect rect, bool32 is_active, Render_Target *target){
File_View *view = (File_View*)view_;
i32 result = 0;
if (view->file){
Interactive_Bar bar;
draw_file_setup_bar(view->style, view->font_height, &bar, &rect);
if (file_is_ready(view->file)){
result = draw_file_loaded(view, rect, is_active, target);
}
draw_file_bar(view, &bar, target);
}
UI_Style ui_style = get_ui_style_upper(view->style);
i32_Rect widg_rect = view_widget_rect(view, view->font_height);
@ -3178,122 +3189,60 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
switch (view->widget.type){
case FWIDG_NONE:
{
Widget_ID wid;
Query_Slot *slot;
Query_Bar *bar;
int i = 1;
for (slot = view->query_set.used_slot; slot != 0; slot = slot->next, ++i){
wid = make_id(&state, i);
bar = slot->query_bar;
do_text_field(wid, &state, &layout, bar->prompt, bar->string);
}
draw_file_view_queries(view, &state, &layout);
}break;
case FWIDG_TIMELINES:
{
Assert(file);
if (view->widget.timeline.undo_line){
do_button(1, &state, &layout, "- Undo", 1);
Widget_ID wid = make_id(&state, 2);
i32 undo_count, redo_count, total_count;
undo_count = file->state.undo.undo.edit_count;
redo_count = file->state.undo.redo.edit_count;
total_count = undo_count + redo_count;
do_undo_slider(wid, &state, &layout, total_count, undo_count, 0, 0);
if (view->file){
Editing_File *file = view->file;
i32 undo_count = file->state.undo.undo.edit_count;
i32 redo_count = file->state.undo.redo.edit_count;
i32 total_count = undo_count + redo_count;
undo_shit(0, view, &state, &layout, total_count, undo_count, 0);
}
else{
do_button(1, &state, &layout, "+ Undo", 1);
}
if (view->widget.timeline.history_line){
do_button(3, &state, &layout, "- History", 1);
Widget_ID wid = make_id(&state, 4);
i32 new_count;
i32 mid = ((file->state.undo.history.edit_count + file->state.undo.edit_history_cursor) >> 1);
do_undo_slider(wid, &state, &layout, mid,
file->state.undo.edit_history_cursor, &file->state.undo, &new_count);
}
else{
do_button(3, &state, &layout, "+ History", 1);
view->widget.type = FWIDG_NONE;
}
}break;
}
ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0);
#endif
draw_file_bar(view, &bar, target);
return(0);
}
internal i32
draw_file_loading(File_View *view, i32_Rect rect, b32 is_active, Render_Target *target){
Interactive_Bar bar;
draw_file_setup_bar(view->style, view->font_height, &bar, &rect);
draw_file_bar(view, &bar, target);
return(0);
}
internal i32
draw_file_view(View *view_, i32_Rect rect, bool32 is_active,
Render_Target *target){
File_View *view = (File_View*)view_;
i32 result = 0;
if (view->file){
if (view->file->state.is_loading){
result = draw_file_loading(view, rect, is_active, target);
}
else{
result = draw_file_loaded(view, rect, is_active, target);
}
}
return (result);
}
internal void
kill_file(System_Functions *system, Exchange *exchange,
General_Memory *general, Editing_File *file, Live_Views *live_set, Editing_Layout *layout){
i32 panel_count = layout->panel_count;
Panel *panels = layout->panels, *panel;
panel = panels;
kill_file(
System_Functions *system, Exchange *exchange,
General_Memory *general, Editing_File *file,
Live_Views *live_set, Editing_Layout *layout){
for (i32 i = 0; i < panel_count; ++i){
View *view = panel->view;
if (view){
View *to_kill = view;
if (view->is_minor) to_kill = view->major;
File_View *fview = view_to_file_view(to_kill);
if (fview && fview->file == file){
live_set_free_view(system, exchange, live_set, &fview->view_base);
if (to_kill == view) panel->view = 0;
else view->major = 0;
}
View *view, *to_kill;
File_View *fview;
Panel *panel;
i32 panel_count, i;
panel_count = layout->panel_count;
panel = layout->panels;
for (i = 0; i < panel_count; ++i, ++panel){
view = panel->view;
to_kill = view;
if (view->is_minor) to_kill = view->major;
fview = view_to_file_view(to_kill);
if (fview && fview->file == file){
fview->file = 0;
}
++panel;
}
file_close(system, general, file);
file_get_dummy(file);
}
internal void
command_search(System_Functions*,Command_Data*,Command_Binding);
internal void
command_reverse_search(System_Functions*,Command_Data*,Command_Binding);
inline void
free_file_view(View *view){
File_View *fview = (File_View*)view;
if (fview->line_wrap_y)
general_memory_free(&view->mem->general, fview->line_wrap_y);
if (fview->links)
general_memory_free(&view->mem->general, fview->links);
}
internal
@ -3581,5 +3530,13 @@ search_next_match(Partition *part, Search_Set *set, Search_Iter *iter_){
return(result);
}
inline void
view_change_size(System_Functions *system, General_Memory *general, File_View *view){
if (view->file){
view_measure_wraps(system, general, view);
view->cursor = view_compute_cursor_from_pos(view, view->cursor.pos);
}
}
// BOTTOM

View File

@ -19,8 +19,8 @@ struct Interactive_Style{
struct Interactive_Bar{
Interactive_Style style;
real32 pos_x, pos_y;
real32 text_shift_x, text_shift_y;
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
i16 font_id;
};
@ -79,11 +79,11 @@ struct Live_Views{
};
struct Panel_Divider{
Panel_Divider *next_free;
Panel_Divider *next;
i32 parent;
i32 which_child;
i32 child1, child2;
bool32 v_divider;
b32 v_divider;
i32 pos;
};
@ -131,17 +131,6 @@ intbar_draw_string(Render_Target *target,
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, (char*)str);
#if 0
for (i32 i = 0; str[i]; ++i){
char c = str[i];
font_draw_glyph(target, font_id, c,
bar->pos_x + bar->text_shift_x,
bar->pos_y + bar->text_shift_y,
char_color);
bar->pos_x += font_get_glyph_width(target, font_id, c);
}
#endif
}
internal void
@ -154,17 +143,6 @@ intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
(i32)(bar->pos_y + bar->text_shift_y),
char_color);
bar->pos_x += font_string_width(target, font_id, str);
#if 0
for (i32 i = 0; i < str.size; ++i){
char c = str.str[i];
font_draw_glyph(target, font_id, c,
bar->pos_x + bar->text_shift_x,
bar->pos_y + bar->text_shift_y,
char_color);
bar->pos_x += font_get_glyph_width(target, font_id, c);
}
#endif
}
internal void
@ -206,16 +184,21 @@ live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *liv
view->is_active = 0;
}
inline void
view_set_first(View *new_view, Panel *panel){
new_view->panel = panel;
new_view->minor = 0;
panel->view = new_view;
}
inline void
view_replace_major(System_Functions *system, Exchange *exchange,
View *new_view, Panel *panel, Live_Views *live_set){
View *new_view, Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view){
if (view->is_minor && view->major){
live_set_free_view(system, exchange, live_set, view->major);
}
live_set_free_view(system, exchange, live_set, view);
if (view->is_minor && view->major){
live_set_free_view(system, exchange, live_set, view->major);
}
live_set_free_view(system, exchange, live_set, view);
new_view->panel = panel;
new_view->minor = 0;
panel->view = new_view;
@ -223,76 +206,34 @@ view_replace_major(System_Functions *system, Exchange *exchange,
inline void
view_replace_minor(System_Functions *system, Exchange *exchange,
View *new_view, Panel *panel, Live_Views *live_set){
View *new_view, Panel *panel, Live_Views *live_set){
View *view = panel->view;
new_view->is_minor = 1;
if (view){
if (view->is_minor){
new_view->major = view->major;
live_set_free_view(system, exchange, live_set, view);
}
else{
new_view->major = view;
view->is_active = 0;
}
if (view->is_minor){
new_view->major = view->major;
live_set_free_view(system, exchange, live_set, view);
}
else{
new_view->major = 0;
new_view->major = view;
view->is_active = 0;
}
new_view->panel = panel;
panel->view = new_view;
}
inline void
view_remove_major(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
view_remove_minor(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view){
if (view->is_minor && view->major){
live_set_free_view(system, exchange, live_set, view->major);
}
View *major = view;
if (view->is_minor){
major = view->major;
live_set_free_view(system, exchange, live_set, view);
}
panel->view = 0;
}
inline void
view_remove_major_leave_minor(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view){
if (view->is_minor && view->major){
live_set_free_view(system, exchange, live_set, view->major);
view->major = 0;
}
else{
live_set_free_view(system, exchange, live_set, view);
panel->view = 0;
}
}
}
inline void
view_remove_minor(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
View *major = 0;
if (view){
if (view->is_minor){
major = view->major;
live_set_free_view(system, exchange, live_set, view);
}
}
Assert(major);
panel->view = major;
if (major) major->is_active = 1;
}
inline void
view_remove(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view->is_minor) view_remove_minor(system, exchange, panel, live_set);
else view_remove_major(system, exchange, panel, live_set);
major->is_active = 1;
}
struct Divider_And_ID{
@ -302,10 +243,12 @@ struct Divider_And_ID{
internal Divider_And_ID
layout_alloc_divider(Editing_Layout *layout){
Assert(layout->free_divider);
Divider_And_ID result;
Assert(layout->free_divider);
result.divider = layout->free_divider;
layout->free_divider = result.divider->next_free;
layout->free_divider = result.divider->next;
*result.divider = {};
result.divider->parent = -1;
result.divider->child1 = -1;
@ -314,7 +257,8 @@ layout_alloc_divider(Editing_Layout *layout){
if (layout->panel_count == 1){
layout->root = result.id;
}
return result;
return(result);
}
internal Divider_And_ID
@ -337,21 +281,22 @@ layout_alloc_panel(Editing_Layout *layout){
internal void
layout_free_divider(Editing_Layout *layout, Panel_Divider *divider){
divider->next_free = layout->free_divider;
divider->next = layout->free_divider;
layout->free_divider = divider;
}
internal void
layout_free_panel(Editing_Layout *layout, Panel *panel){
Panel *panels = layout->panels;
i32 panel_count = --layout->panel_count;
i32 panel_i = (i32)(panel - layout->panels);
for (i32 i = panel_i; i < panel_count; ++i){
Panel *p = panels + i;
Panel *p, *panels;
i32 panel_count, i;
panels = layout->panels;
panel_count = --layout->panel_count;
p = panel;
for (i = (i32)(panel - layout->panels); i < panel_count; ++i, ++p){
*p = panels[i+1];
if (p->view){
p->view->panel = p;
}
p->view->panel = p;
}
}
@ -369,15 +314,19 @@ struct Split_Result{
};
internal Split_Result
layout_split_panel(Editing_Layout *layout, Panel *panel, bool32 vertical){
Divider_And_ID div = layout_alloc_divider(layout);
layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){
Split_Result result = {};
Divider_And_ID div = {}, parent_div = {};
Panel *new_panel = 0;
div = layout_alloc_divider(layout);
if (panel->parent != -1){
Divider_And_ID pdiv = layout_get_divider(layout, panel->parent);
parent_div = layout_get_divider(layout, panel->parent);
if (panel->which_child == -1){
pdiv.divider->child1 = div.id;
parent_div.divider->child1 = div.id;
}
else{
pdiv.divider->child2 = div.id;
parent_div.divider->child2 = div.id;
}
}
@ -392,13 +341,12 @@ layout_split_panel(Editing_Layout *layout, Panel *panel, bool32 vertical){
div.divider->pos = (panel->full.y0 + panel->full.y1) / 2;
}
Panel *new_panel = layout_alloc_panel(layout);
new_panel = layout_alloc_panel(layout);
panel->parent = div.id;
panel->which_child = -1;
new_panel->parent = div.id;
new_panel->which_child = 1;
Split_Result result;
result.divider = div.divider;
result.panel = new_panel;
return result;
@ -489,25 +437,29 @@ layout_fix_all_panels(Editing_Layout *layout){
}
internal void
layout_refit(Editing_Layout *layout,
i32 prev_x_off, i32 prev_y_off,
i32 prev_width, i32 prev_height){
layout_refit(Editing_Layout *layout, i32 prev_width, i32 prev_height){
Panel_Divider *dividers = layout->dividers;
i32 divider_max_count = layout->panel_max_count - 1;
i32 max = layout->panel_max_count - 1;
i32 x_off = 0;
i32 y_off = 0;
f32 h_ratio, v_ratio;
real32 h_ratio = ((real32)layout->full_width) / prev_width;
real32 v_ratio = ((real32)layout->full_height) / prev_height;
Panel_Divider *divider = dividers;
i32 i;
for (i32 divider_id = 0; divider_id < divider_max_count; ++divider_id){
Panel_Divider *divider = dividers + divider_id;
if (divider->v_divider){
divider->pos = x_off + ROUND32((divider->pos - prev_x_off) * h_ratio);
}
else{
divider->pos = y_off + ROUND32((divider->pos - prev_y_off) * v_ratio);
if (layout->panel_count > 1){
Assert(prev_width != 0 && prev_height != 0);
h_ratio = ((f32)layout->full_width) / prev_width;
v_ratio = ((f32)layout->full_height) / prev_height;
for (i = 0; i < max; ++i, ++divider){
if (divider->v_divider){
divider->pos = ROUND32((divider->pos) * h_ratio);
}
else{
divider->pos = ROUND32((divider->pos) * v_ratio);
}
}
}

View File

@ -121,7 +121,6 @@ char *daction_enum[] = {
"TRY_KILL",
"KILL",
"CLOSE_MINOR",
"CLOSE_MAJOR",
"THEME_OPTIONS",
"KEYBOARD_OPTIONS"
};

View File

@ -26,8 +26,6 @@
#include <stdlib.h>
#undef Assert
#undef internal
#include "4coder_custom.cpp"
#undef exec_command