goto line implemented in custom.cpp

This commit is contained in:
Allen Webster 2016-02-27 02:44:17 -05:00
parent 0fe6447102
commit bc9dac52ae
12 changed files with 631 additions and 392 deletions

View File

@ -31,6 +31,15 @@ typedef struct Key_Event_Data{
char modifiers[MDFR_INDEX_COUNT];
} Key_Event_Data;
typedef struct Mouse_State{
char l, r;
char press_l, press_r;
char release_l, release_r;
char wheel;
char out_of_window;
int x, y;
} Mouse_State;
typedef struct Full_Cursor{
int pos;
@ -102,7 +111,6 @@ seek_line_char(int line, int character){
return(result);
}
typedef union Range{
struct{
int min, max;
@ -120,8 +128,8 @@ make_range(int p1, int p2){
range.max = p2;
}
else{
range.max = p2;
range.min = p1;
range.min = p2;
range.max = p1;
}
return(range);
}

View File

@ -135,6 +135,30 @@ CUSTOM_COMMAND_SIG(open_long_braces_semicolon){
exec_command(app, cmdid_auto_tab_range);
}
CUSTOM_COMMAND_SIG(paren_wrap){
File_View_Summary view;
Buffer_Summary buffer;
char text1[] = "(";
int size1 = sizeof(text1) - 1;
char text2[] = ")";
int size2 = sizeof(text2) - 1;
Range range;
int pos;
view = app->get_active_file_view(app);
buffer = app->get_active_buffer(app);
range = get_range(&view);
pos = range.max;
app->buffer_replace_range(app, &buffer, pos, pos, text2, size2);
pos = range.min;
app->buffer_replace_range(app, &buffer, pos, pos, text1, size1);
}
CUSTOM_COMMAND_SIG(if0_off){
File_View_Summary view;
Buffer_Summary buffer;
@ -279,26 +303,47 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){
CUSTOM_COMMAND_SIG(goto_line){
User_Input in;
Query bar;
int line_number = 0;
Query_Bar bar;
char string_space[256];
int line_number;
bar.prompt = make_lit_string("Goto Line: ");
bar.string = make_fixed_width_string(string_space);
// NOTE(allen): It will not cause an *error* if we continue on after failing to.
// start a query bar, but it will be unusual behavior from the point of view of the
// user, if this command starts intercepting input even though no prompt is shown.
if (app->start_query_bar(app, &bar, 0) == 0) return;
in = {};
bar = app->create_query(app, make_lit_string("Line Number: "), QueryBar);
while (1){
in = app->get_user_input(app, AbortOnEsc | AbortOnClick);
in = app->get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
if (in.abort) break;
if (in.key.character >= '0' && in.key.character <= '9' || in.key.character == 0){
app->update_query(app, &bar, in.key);
if (bar.complete) break;
if (in.type == UserInputKey){
if (in.key.character >= '0' && in.key.character <= '9'){
append(&bar.string, in.key.character);
}
else if (in.key.keycode == key_back){
--bar.string.size;
}
else if (in.key.keycode == '\n' || in.key.keycode == '\t'){
break;
}
}
}
app->close_query(app, &bar);
if (in.abort) return;
line_number = str_to_int(bar.string);
line_number = str_to_int(bar.string);
active_view_to_line(app, line_number);
}
CUSTOM_COMMAND_SIG(search){
}
CUSTOM_COMMAND_SIG(reverse_search){
}
CUSTOM_COMMAND_SIG(open_in_other){
exec_command(app, cmdid_change_active_panel);
exec_command(app, cmdid_interactive_open);
@ -467,6 +512,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, '-', MDFR_CTRL, write_decrement);
bind(context, '[', MDFR_CTRL, open_long_braces);
bind(context, '{', MDFR_CTRL, open_long_braces);
bind(context, '9', MDFR_CTRL, paren_wrap);
bind(context, 'i', MDFR_ALT, if0_off);
bind(context, '1', MDFR_ALT, switch_to_file_in_quotes);
@ -525,8 +571,8 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, '1', MDFR_CTRL, cmdid_eol_dosify);
bind(context, '!', MDFR_CTRL, cmdid_eol_nixify);
bind(context, 'f', MDFR_CTRL, cmdid_search);
bind(context, 'r', MDFR_CTRL, cmdid_reverse_search);
bind(context, 'f', MDFR_CTRL, search);
bind(context, 'r', MDFR_CTRL, reverse_search);
bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer);

View File

@ -22,8 +22,8 @@ enum Command_ID{
cmdid_seek_alphanumeric_right,
cmdid_seek_alphanumeric_or_camel_left,
cmdid_seek_alphanumeric_or_camel_right,
cmdid_search,
cmdid_reverse_search,
//cmdid_search,
//cmdid_reverse_search,
cmdid_word_complete,
//cmdid_goto_line,
cmdid_set_mark,
@ -135,28 +135,23 @@ struct File_View_Summary{
int unwrapped_lines;
};
#define UserInputKey 0
#define UserInputMouse 1
struct User_Input{
int type;
union{
Key_Event_Data key;
Mouse_State mouse;
};
int abort;
};
struct Query{
int query_id;
int complete;
int type;
struct Query_Bar{
String prompt;
String string;
};
#ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT
struct String{
char *str;
int size;
int memory_size;
};
#endif
#define GET_BINDING_DATA(name) int name(void *data, int size)
#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out)
#define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app)
@ -204,20 +199,23 @@ struct Application_Links;
#define VIEW_SET_BUFFER_SIG(name) int name(Application_Links *context, File_View_Summary *view, int buffer_id)
// Directly get user input
#define AbortOnEsc 0x1
#define AbortOnClick 0x2
#define GET_USER_INPUT_SIG(name) User_Input name(Application_Links *context, unsigned int flags)
#define EventOnAnyKey 0x1
#define EventOnEsc 0x2
#define EventOnLeftButton 0x4
#define EventOnRightButton 0x8
#define EventOnWheel 0x10
#define EventOnButton (EventOnLeftButton | EventOnRightButton | EventOnWheel)
#define EventOnMouseMove 0x20
#define EventOnMouse (EventOnButton | EventOnMouseMove)
#define GET_USER_INPUT_SIG(name) User_Input name(Application_Links *context, unsigned int get_type, unsigned int abort_type)
// Queries
#define QueryForFile 0x1
#define QueryForBuffer 0x2
#define QueryEffectImmediate 0x0
#define QueryEffectSmooth 0x1
#define QueryBar 0x0
#define QueryScreen 0x010000
#define CREATE_QUERY_SIG(name) Query name(Application_Links *context, String prompt, unsigned int flags)
#define UPDATE_QUERY_SIG(name) void name(Application_Links *context, Query *query, Key_Event_Data key)
#define CLOSE_QUERY_SIG(name) void name(Application_Links *context, Query *query)
#define START_QUERY_BAR_SIG(name) int name(Application_Links *context, Query_Bar *bar, unsigned int flags)
#define END_QUERY_BAR_SIG(name) void name(Application_Links *context, Query_Bar *bar, unsigned int flags)
extern "C"{
// Command exectuion
@ -257,9 +255,8 @@ extern "C"{
typedef GET_USER_INPUT_SIG(Get_User_Input_Function);
// Queries
typedef CREATE_QUERY_SIG(Create_Query_Function);
typedef UPDATE_QUERY_SIG(Update_Query_Function);
typedef CLOSE_QUERY_SIG(Close_Query_Function);
typedef START_QUERY_BAR_SIG(Start_Query_Bar_Function);
typedef END_QUERY_BAR_SIG(End_Query_Bar_Function);
}
struct Application_Links{
@ -300,12 +297,11 @@ struct Application_Links{
View_Set_Buffer_Function *view_set_buffer;
// Directly get user input
Get_User_Input_Function* get_user_input;
Get_User_Input_Function *get_user_input;
// Queries
Create_Query_Function* create_query;
Update_Query_Function* update_query;
Close_Query_Function* close_query;
Start_Query_Bar_Function *start_query_bar;
End_Query_Bar_Function *end_query_bar;
};
struct Custom_API{

478
4ed.cpp
View File

@ -59,6 +59,7 @@ struct Command_Data{
struct App_Vars *vars;
Exchange *exchange;
System_Functions *system;
Coroutine *current_coroutine;
i32 screen_width, screen_height;
Key_Event_Data key;
@ -81,7 +82,9 @@ struct App_Vars{
i32 *map_id_table;
i32 user_map_count;
Command_Binding prev_command;
Coroutine *command_coroutine;
u32 command_coroutine_flags[2];
Sys_App_Binding *sys_app_bindings;
i32 sys_app_count, sys_app_max;
@ -104,9 +107,6 @@ struct App_Vars{
CLI_List cli_processes;
char query_[256];
char dest_[256];
Delay delay;
String mini_str;
@ -417,34 +417,6 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){
view_cursor_move(view, pos);
}
COMMAND_DECL(search){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_SEARCH);
view->isearch.str = vars->mini_str;
view->isearch.reverse = 0;
view->isearch.pos = view->cursor.pos - 1;
#endif
}
COMMAND_DECL(reverse_search){
#if 0
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_SEARCH);
view->isearch.str = vars->mini_str;
view->isearch.reverse = 1;
view->isearch.pos = view->cursor.pos + 1;
#endif
}
COMMAND_DECL(word_complete){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
@ -1488,8 +1460,7 @@ COMMAND_DECL(delete){
start = cursor_pos;
end = cursor_pos+1;
i32 shift = (end - start);
Assert(shift > 0);
Assert(end - start > 0);
i32 next_cursor_pos = start;
view_replace_range(system, mem, view, layout, start, end, 0, 0, next_cursor_pos);
@ -1961,24 +1932,9 @@ COMMAND_DECL(build){
internal void
update_command_data(App_Vars *vars, Command_Data *cmd){
Command_Data command_data;
command_data.vars = vars;
command_data.mem = &vars->mem;
command_data.working_set = &vars->working_set;
command_data.layout = &vars->layout;
command_data.panel = command_data.layout->panels + command_data.layout->active_panel;
command_data.view = command_data.panel->view;
command_data.live_set = &vars->live_set;
command_data.style = &vars->style;
command_data.delay = &vars->delay;
command_data.screen_width = cmd->screen_width;
command_data.screen_height = cmd->screen_height;
command_data.key = cmd->key;
command_data.part = cmd->part;
command_data.system = cmd->system;
command_data.exchange = cmd->exchange;
*cmd = command_data;
cmd->panel = cmd->layout->panels + cmd->layout->active_panel;
cmd->view = cmd->panel->view;
cmd->style = &vars->style;
}
globalvar Command_Function command_table[cmdid_count];
@ -2355,6 +2311,51 @@ extern "C"{
return(result);
}
GET_USER_INPUT_SIG(external_get_user_input){
Command_Data *cmd = (Command_Data*)context->data;
System_Functions *system = cmd->system;
Coroutine *coroutine = cmd->current_coroutine;
User_Input result;
Assert(coroutine);
*((u32*)coroutine->out+0) = get_type;
*((u32*)coroutine->out+1) = abort_type;
system->yield_coroutine(coroutine);
result = *(User_Input*)coroutine->in;
return(result);
}
START_QUERY_BAR_SIG(external_start_query_bar){
Command_Data *cmd = (Command_Data*)context->data;
Query_Slot *slot = 0;
View *vptr;
File_View *file_view;
vptr = cmd->view;
file_view = view_to_file_view(vptr);
if (file_view){
slot = alloc_query_slot(&file_view->query_set);
slot->query_bar = bar;
}
return(slot != 0);
}
END_QUERY_BAR_SIG(external_end_query_bar){
Command_Data *cmd = (Command_Data*)context->data;
View *vptr;
File_View *file_view;
vptr = cmd->view;
file_view = view_to_file_view(vptr);
if (file_view){
free_query_slot(&file_view->query_set, bar);
}
}
}
struct Command_In{
@ -2364,8 +2365,9 @@ struct Command_In{
internal void
command_caller(Coroutine *coroutine){
Command_In *cmd = (Command_In*)coroutine->in;
cmd->bind.function(cmd->cmd->system, cmd->cmd, cmd->bind);
Command_In *cmd_in = (Command_In*)coroutine->in;
Command_Data *cmd = cmd_in->cmd;
cmd_in->bind.function(cmd->system, cmd, cmd_in->bind);
}
internal void
@ -2399,11 +2401,10 @@ app_links_init(System_Functions *system){
app_links.view_set_mark = external_view_set_mark;
app_links.view_set_buffer = external_view_set_buffer;
app_links.get_user_input = 0;//external_get_user_input;
app_links.get_user_input = external_get_user_input;
app_links.create_query = 0;//external_create_query;
app_links.update_query = 0;//external_update_query;
app_links.close_query = 0;//external_close_query;
app_links.start_query_bar = external_start_query_bar;
app_links.end_query_bar = external_end_query_bar;
}
#if FRED_INTERNAL
@ -2465,8 +2466,6 @@ setup_command_table(){
SET(seek_alphanumeric_left);
SET(seek_alphanumeric_or_camel_right);
SET(seek_alphanumeric_or_camel_left);
SET(search);
SET(reverse_search);
SET(word_complete);
SET(set_mark);
SET(copy);
@ -3354,7 +3353,7 @@ App_Step_Sig(app_step){
app_result.redraw = 1;
}
// NOTE(allen): collect input information
// NOTE(allen): prepare input information
Key_Summary key_data = {};
for (i32 i = 0; i < input->press_count; ++i){
key_data.keys[key_data.count++] = input->press[i];
@ -3363,56 +3362,35 @@ App_Step_Sig(app_step){
key_data.keys[key_data.count++] = input->hold[i];
}
Mouse_Summary mouse_data;
mouse_data.mx = mouse->x;
mouse_data.my = mouse->y;
mouse->wheel = -mouse->wheel;
mouse_data.l = mouse->left_button;
mouse_data.r = mouse->right_button;
mouse_data.press_l = mouse->left_button_pressed;
mouse_data.press_r = mouse->right_button_pressed;
mouse_data.release_l = mouse->left_button_released;
mouse_data.release_r = mouse->right_button_released;
mouse_data.out_of_window = mouse->out_of_window;
mouse_data.wheel_used = (mouse->wheel != 0);
mouse_data.wheel_amount = -mouse->wheel;
ProfileEnd(OS_syncing);
ProfileStart(hover_status);
// NOTE(allen): detect mouse hover status
i32 mx = mouse_data.mx;
i32 my = mouse_data.my;
i32 mx = mouse->x;
i32 my = mouse->y;
b32 mouse_in_edit_area = 0;
b32 mouse_in_margin_area = 0;
Panel *mouse_panel = 0;
i32 mouse_panel_i = 0;
{
Panel *panel = 0;
b32 in_edit_area = 0;
b32 in_margin_area = 0;
i32 panel_count = vars->layout.panel_count;
i32 panel_i;
for (panel_i = 0; panel_i < panel_count; ++panel_i){
panel = panels + panel_i;
if (hit_check(mx, my, panel->inner)){
in_edit_area = 1;
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)){
mouse_in_edit_area = 1;
break;
}
else if (hit_check(mx, my, panel->full)){
in_margin_area = 1;
else if (hit_check(mx, my, mouse_panel->full)){
mouse_in_margin_area = 1;
break;
}
}
mouse_in_edit_area = in_edit_area;
mouse_in_margin_area = in_margin_area;
if (in_edit_area || in_margin_area){
mouse_panel = panel;
mouse_panel_i = panel_i;
}
if (!(mouse_in_edit_area || mouse_in_margin_area)){
mouse_panel = 0;
mouse_panel_i = 0;
}
b32 mouse_on_divider = 0;
@ -3421,66 +3399,201 @@ App_Step_Sig(app_step){
i32 mouse_divider_side = 0;
if (mouse_in_margin_area){
b32 resize_area = 0;
i32 divider_id = 0;
b32 seeking_v_divider = 0;
i32 seeking_child_on_side = 0;
Panel *panel = mouse_panel;
if (mx >= panel->inner.x0 && mx < panel->inner.x1){
seeking_v_divider = 0;
mouse_divider_vertical = 0;
if (my > panel->inner.y0){
seeking_child_on_side = -1;
mouse_divider_side = -1;
}
else{
seeking_child_on_side = 1;
mouse_divider_side = 1;
}
}
else{
seeking_v_divider = 1;
mouse_divider_vertical = 1;
if (mx > panel->inner.x0){
seeking_child_on_side = -1;
mouse_divider_side = -1;
}
else{
seeking_child_on_side = 1;
mouse_divider_side = 1;
}
}
mouse_divider_vertical = seeking_v_divider;
mouse_divider_side = seeking_child_on_side;
if (vars->layout.panel_count > 1){
i32 which_child;
divider_id = panel->parent;
mouse_divider_id = panel->parent;
which_child = panel->which_child;
for (;;){
Divider_And_ID div = layout_get_divider(&vars->layout, divider_id);
Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id);
if (which_child == seeking_child_on_side &&
div.divider->v_divider == seeking_v_divider){
resize_area = 1;
if (which_child == mouse_divider_side &&
div.divider->v_divider == mouse_divider_vertical){
mouse_on_divider = 1;
break;
}
if (divider_id == vars->layout.root){
if (mouse_divider_id == vars->layout.root){
break;
}
else{
divider_id = div.divider->parent;
mouse_divider_id = div.divider->parent;
which_child = div.divider->which_child;
}
}
mouse_on_divider = resize_area;
mouse_divider_id = divider_id;
}
else{
mouse_on_divider = 0;
mouse_divider_id = 0;
}
}
ProfileEnd(hover_status);
// NOTE(allen): process the command_coroutine if it is unfinished
ProfileStart(command_coroutine);
Command_Data *cmd = &vars->command_data;
cmd->mem = &vars->mem;
cmd->panel = active_panel;
cmd->view = active_panel->view;
cmd->working_set = &vars->working_set;
cmd->layout = &vars->layout;
cmd->live_set = &vars->live_set;
cmd->style = &vars->style;
cmd->delay = &vars->delay;
cmd->vars = vars;
cmd->exchange = exchange;
cmd->screen_width = target->width;
cmd->screen_height = target->height;
cmd->system = system;
Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part);
cmd->part = partition_sub_part(&vars->mem.part, 16 << 10);
b8 consumed_input[6] = {0};
if (vars->command_coroutine != 0){
Coroutine *command_coroutine = vars->command_coroutine;
u32 get_flags = vars->command_coroutine_flags[0];
u32 abort_flags = vars->command_coroutine_flags[1];
get_flags |= abort_flags;
if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){
for (i32 key_i = 0; key_i < key_data.count; ++key_i){
Key_Event_Data key = get_single_key(&key_data, key_i);
View *view = active_panel->view;
b32 pass_in = 0;
User_Input user_in;
user_in.type = UserInputKey;
user_in.key = key;
user_in.abort = 0;
if ((EventOnEsc & abort_flags) && key.keycode == key_esc){
user_in.abort = 1;
}
else if (EventOnAnyKey & abort_flags){
user_in.abort = 1;
}
if (EventOnAnyKey & get_flags){
pass_in = 1;
consumed_input[0] = 1;
}
if (key.keycode == key_esc){
if (EventOnEsc & get_flags){
pass_in = 1;
}
consumed_input[1] = 1;
}
if (pass_in){
cmd->current_coroutine = vars->command_coroutine;
vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in,
vars->command_coroutine_flags);
app_result.redraw = 1;
// TOOD(allen): Deduplicate
// TODO(allen): Allow a view to clean up however it wants after a command finishes,
// or after transfering to another view mid command.
File_View *fview = view_to_file_view(view);
if (fview != 0 && vars->command_coroutine == 0){
init_query_set(&fview->query_set);
}
if (vars->command_coroutine == 0) break;
}
}
}
if (vars->command_coroutine != 0 && (get_flags & EventOnMouse)){
View *view = active_panel->view;
b32 pass_in = 0;
User_Input user_in;
user_in.type = UserInputMouse;
user_in.mouse = *mouse;
user_in.abort = 0;
if (abort_flags & EventOnMouseMove){
user_in.abort = 1;
}
if (get_flags & EventOnMouseMove){
pass_in = 1;
consumed_input[2] = 1;
}
if (mouse->press_l || mouse->release_l || mouse->l){
if (abort_flags & EventOnLeftButton){
user_in.abort = 1;
}
if (get_flags & EventOnLeftButton){
pass_in = 1;
consumed_input[3] = 1;
}
}
if (mouse->press_r || mouse->release_r || mouse->r){
if (abort_flags & EventOnRightButton){
user_in.abort = 1;
}
if (get_flags & EventOnRightButton){
pass_in = 1;
consumed_input[4] = 1;
}
}
if (mouse->wheel != 0){
if (abort_flags & EventOnWheel){
user_in.abort = 1;
}
if (get_flags & EventOnWheel){
pass_in = 1;
consumed_input[5] = 1;
}
}
cmd->current_coroutine = vars->command_coroutine;
vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in,
vars->command_coroutine_flags);
app_result.redraw = 1;
// TOOD(allen): Deduplicate
// TODO(allen): Allow a view to clean up however it wants after a command finishes,
// or after transfering to another view mid command.
File_View *fview = view_to_file_view(view);
if (fview != 0 && vars->command_coroutine == 0){
init_query_set(&fview->query_set);
}
}
}
ProfileEnd(command_coroutine);
ProfileStart(resizing);
// NOTE(allen): panel resizing
switch (vars->state){
case APP_STATE_EDIT:
{
if (mouse_data.press_l && mouse_on_divider){
if (mouse->press_l && mouse_on_divider){
vars->state = APP_STATE_RESIZING;
Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id);
vars->resizing.divider = div.divider;
@ -3548,7 +3661,7 @@ App_Step_Sig(app_step){
case APP_STATE_RESIZING:
{
app_result.redraw = 1;
if (mouse_data.l){
if (mouse->l){
Panel_Divider *divider = vars->resizing.divider;
if (divider->v_divider){
divider->pos = mx;
@ -3571,34 +3684,19 @@ App_Step_Sig(app_step){
}
}break;
}
ProfileEnd(resizing);
ProfileStart(command);
// NOTE(allen): update active panel
if (mouse_in_edit_area && mouse_panel != 0 && mouse_data.press_l){
if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){
active_panel = mouse_panel;
vars->layout.active_panel = mouse_panel_i;
app_result.redraw = 1;
}
ProfileEnd(resizing);
Command_Data *cmd = &vars->command_data;
// NOTE(allen): command input to active view
ProfileStart(command);
cmd->mem = &vars->mem;
cmd->panel = active_panel;
cmd->view = active_panel->view;
cmd->working_set = &vars->working_set;
cmd->layout = &vars->layout;
cmd->live_set = &vars->live_set;
cmd->style = &vars->style;
cmd->delay = &vars->delay;
cmd->vars = vars;
cmd->exchange = exchange;
cmd->screen_width = target->width;
cmd->screen_height = target->height;
cmd->system = system;
Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part);
cmd->part = partition_sub_part(&vars->mem.part, 16 << 10);
if (first_step){
if (vars->hooks[hook_start]){
@ -3632,13 +3730,29 @@ App_Step_Sig(app_step){
}
}
// NOTE(allen): command input to active view
if (!consumed_input[0] || !consumed_input[1]){
b32 consumed_input2[2] = {0};
for (i32 key_i = 0; key_i < key_data.count; ++key_i){
Command_Binding cmd_bind = {};
Command_Map *map = 0;
switch (vars->state){
case APP_STATE_EDIT:
{
Key_Event_Data key = get_single_key(&key_data, key_i);
b32 hit_esc = (key.keycode == key_esc);
if (hit_esc || !consumed_input[0]){
if (hit_esc){
consumed_input[0] = 1;
}
else{
consumed_input[1] = 1;
}
View *view = active_panel->view;
Key_Event_Data key = get_single_key(&key_data, key_i);
Command_Binding cmd_bind = {};
Command_Map *map = 0;
cmd->key = key;
Command_Map *visited_maps[16] = {};
@ -3664,39 +3778,20 @@ App_Step_Sig(app_step){
else map = 0;
}
switch (vars->state){
case APP_STATE_EDIT:
{
if (cmd_bind.function){
Coroutine *command_coroutine = system->create_coroutine(command_caller);
vars->command_coroutine = command_coroutine;
Command_In cmd_in;
cmd_in.cmd = cmd;
cmd_in.bind = cmd_bind;
vars->command_coroutine = system->launch_coroutine(command_caller, &cmd_in, 0);
app_result.redraw = 1;
}
#if 0
if (cmd_bind.function){
cmd_bind.function(system, cmd, cmd_bind);
app_result.redraw = 1;
}
#endif
#if 0
Handle_Command_Function *handle_command = 0;
if (view) handle_command = view->handle_command;
if (handle_command){
handle_command(system, view, cmd, cmd_bind, key);
app_result.redraw = 1;
}
else{
if (cmd_bind.function){
cmd_bind.function(system, cmd, cmd_bind);
cmd->current_coroutine = vars->command_coroutine;
vars->command_coroutine = system->launch_coroutine(vars->command_coroutine,
&cmd_in, vars->command_coroutine_flags);
app_result.redraw = 1;
}
}
vars->prev_command = cmd_bind;
#endif
}break;
case APP_STATE_RESIZING:
@ -3708,22 +3803,56 @@ App_Step_Sig(app_step){
}
}
consumed_input[0] |= consumed_input2[0];
consumed_input[1] |= consumed_input2[1];
}
active_panel = panels + vars->layout.active_panel;
ProfileEnd(command);
// NOTE(allen): pass raw input to the panels
ProfileStart(step);
View *active_view = active_panel->view;
Input_Summary dead_input = {};
dead_input.mouse.mx = mouse_data.mx;
dead_input.mouse.my = mouse_data.my;
dead_input.mouse.x = mouse->x;
dead_input.mouse.y = mouse->y;
Input_Summary active_input = {};
dead_input.mouse.mx = mouse_data.mx;
dead_input.mouse.my = mouse_data.my;
active_input.mouse.x = mouse->x;
active_input.mouse.y = mouse->y;
if (!consumed_input[0]){
active_input.keys = key_data;
}
else if (!consumed_input[1]){
for (i32 i = 0; i < key_data.count; ++i){
Key_Event_Data key = get_single_key(&key_data, i);
if (key.keycode == key_esc){
active_input.keys.count = 1;
active_input.keys.keys[0] = key;
break;
}
}
}
Mouse_State mouse_state = *mouse;
if (consumed_input[3]){
mouse_state.l = 0;
mouse_state.press_l = 0;
mouse_state.release_l = 0;
}
if (consumed_input[4]){
mouse_state.r = 0;
mouse_state.press_r = 0;
mouse_state.release_r = 0;
}
if (consumed_input[5]){
mouse_state.wheel = 0;
}
// NOTE(allen): pass raw input to the panels
{
Panel *panel = panels;
for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){
@ -3732,8 +3861,8 @@ App_Step_Sig(app_step){
Assert(view_->do_view);
b32 active = (panel == active_panel);
Input_Summary input = (active)?(active_input):(dead_input);
if (panel == mouse_panel && !mouse_data.out_of_window){
input.mouse = mouse_data;
if (panel == mouse_panel && !mouse->out_of_window){
input.mouse = mouse_state;
}
if (view_->do_view(system, exchange, view_, panel->inner, active_view,
VMSG_STEP, 0, &input, &active_input)){
@ -3744,6 +3873,7 @@ App_Step_Sig(app_step){
}
ProfileEnd(step);
// NOTE(allen): process as many delayed actions as possible
ProfileStart(delayed_actions);
if (vars->delay.count > 0){
Style *style = &vars->style;
@ -4106,6 +4236,7 @@ App_Step_Sig(app_step){
// end-of-app_step
}
#if 0
internal
App_Alloc_Sig(app_alloc){
Mem_Options *mem = (Mem_Options*)(handle);
@ -4118,6 +4249,7 @@ App_Free_Sig(app_free){
Mem_Options *mem = (Mem_Options*)(handle);
general_memory_free(&mem->general, block);
}
#endif
external App_Get_Functions_Sig(app_get_functions){
App_Functions result = {};
@ -4126,8 +4258,10 @@ external App_Get_Functions_Sig(app_get_functions){
result.init = app_init;
result.step = app_step;
#if 0
result.alloc = app_alloc;
result.free = app_free;
#endif
return(result);
}

21
4ed.h
View File

@ -42,27 +42,8 @@ get_single_key(Key_Summary *summary, i32 index){
return key;
}
struct Mouse_State{
b32 out_of_window;
b8 left_button, right_button;
b8 left_button_pressed, right_button_pressed;
b8 left_button_released, right_button_released;
i16 wheel;
i32 x, y;
};
struct Mouse_Summary{
i32 mx, my;
b32 l, r;
b32 press_l, press_r;
b32 release_l, release_r;
b32 out_of_window;
b32 wheel_used;
i16 wheel_amount;
};
struct Input_Summary{
Mouse_Summary mouse;
Mouse_State mouse;
Key_Summary keys;
};

View File

@ -267,9 +267,9 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
char c[16];
String s = make_fixed_width_string(c);
append_int_to_str(active_input->mouse.mx, &s);
append_int_to_str(active_input->mouse.x, &s);
append(&s, ", ");
append_int_to_str(active_input->mouse.my, &s);
append_int_to_str(active_input->mouse.y, &s);
terminate_with_null(&s);
draw_string(target, font_id, c, x, y, color);
y += line_height;
@ -290,7 +290,7 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
append_int_to_str(view->prev_mouse_wheel, &s);
terminate_with_null(&s);
if (active_input->mouse.wheel_used) btn_color = color;
if (active_input->mouse.wheel != 0) btn_color = color;
else btn_color = 0xFF444444;
draw_string(target, font_id, c, x, y, btn_color);
@ -327,34 +327,7 @@ internal void
step_debug_view(Debug_View *view, i32_Rect rect, Render_Target *target,
Input_Summary *active_input){
persist i32 max_past = ArrayCount(view->past_keys);
#if 0
b8 *modifiers = active_input->keys.modifiers;
for (i32 i = 0; i < active_input->keys.count; ++i){
Dbg_Past_Key *past_key = view->past_keys + view->past_key_pos;
++view->past_key_pos;
view->past_key_pos = view->past_key_pos % max_past;
past_key->key = active_input->keys.keys[i];
past_key->modifiers[0] = modifiers[0];
past_key->modifiers[1] = modifiers[1];
past_key->modifiers[2] = modifiers[2];
#if 0
i32 this_index = view->past_key_pos;
past_key->frame_index = INTERNAL_frame_index;
if (profile_frame.first_key == -1){
profile_frame.first_key = this_index;
}
#endif
past_key->frame_index = -1;
if (view->past_key_count < max_past) ++view->past_key_count;
}
if (active_input->mouse.wheel_used)
view->prev_mouse_wheel = active_input->mouse.wheel_amount;
#endif
AllowLocal(max_past);
}
internal

View File

@ -121,7 +121,11 @@ struct File_View{
File_View_Mode mode, next_mode;
File_View_Widget widget;
i32 rewind_max, scrub_max;
Query_Set query_set;
i32 scrub_max;
b32 unwrapped_lines;
b32 show_whitespace;
b32 locked;
@ -1473,7 +1477,14 @@ inline i32
view_widget_height(File_View *view, i32 font_height){
i32 result = 0;
switch (view->widget.type){
case FWIDG_NONE: break;
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_SEARCH: result = font_height + 2; break;
//case FWIDG_GOTO_LINE: result = font_height + 2; break;
case FWIDG_TIMELINES: result = view->widget.height; break;
@ -2784,16 +2795,16 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect,
extra_top += view_widget_height(view, (i32)line_height);
f32 taken_top_space = line_height + extra_top;
if (user_input->mouse.my < rect.y0 + taken_top_space){
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_used){
real32 wheel_multiplier = 3.f;
real32 delta_target_y = delta_y*user_input->mouse.wheel_amount*wheel_multiplier;
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;
@ -2849,8 +2860,8 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect,
if (is_active && user_input->mouse.press_l){
f32 max_y = view_compute_height(view);
f32 rx = (f32)(user_input->mouse.mx - rect.x0);
f32 ry = (f32)(user_input->mouse.my - rect.y0 - line_height - 2);
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);
@ -3216,7 +3227,6 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
end_temp_memory(temp);
#endif
if (view->widget.type != FWIDG_NONE){
#if 0
ui_render(target, view->gui_target);
#else
@ -3235,6 +3245,19 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
begin_layout(&layout, widg_rect);
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);
}
}break;
case FWIDG_TIMELINES:
{
Assert(file);
@ -3292,7 +3315,6 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t
ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0);
#endif
}
draw_file_bar(view, &bar, target);
@ -3527,9 +3549,10 @@ file_view_init(View *view, Editing_Layout *layout){
File_View *result = (File_View*)view;
result->layout = layout;
result->rewind_max = 4;
result->scrub_max = 1;
return result;
init_query_set(&result->query_set);
return(result);
}
struct File_View_Iter{

View File

@ -9,6 +9,61 @@
// TOP
struct Query_Slot{
Query_Slot *next;
Query_Bar *query_bar;
};
struct Query_Set{
Query_Slot slots[8];
Query_Slot *free_slot;
Query_Slot *used_slot;
};
internal void
init_query_set(Query_Set *set){
Query_Slot *slot = set->slots;
int i;
set->free_slot = slot;
set->used_slot = 0;
for (i = 0; i+1 < ArrayCount(set->slots); ++i, ++slot){
slot->next = slot + 1;
}
}
internal Query_Slot*
alloc_query_slot(Query_Set *set){
Query_Slot *slot = set->free_slot;
if (slot != 0){
set->free_slot = slot->next;
slot->next = set->used_slot;
set->used_slot = slot;
}
return(slot);
}
internal void
free_query_slot(Query_Set *set, Query_Bar *match_bar){
Query_Slot *slot = 0, *prev = 0;
for (slot = set->used_slot; slot != 0; slot = slot->next){
if (slot->query_bar == match_bar) break;
prev = slot;
}
if (slot){
if (prev){
prev->next = slot->next;
}
else{
set->used_slot = slot->next;
}
slot->next = set->free_slot;
set->free_slot = slot;
}
}
#if 0
enum GUI_Piece_Type{
gui_type_text_input,
@ -302,7 +357,7 @@ struct UI_State{
Render_Target *target;
Style *style;
Font_Set *font_set;
Mouse_Summary *mouse;
Mouse_State *mouse;
Key_Summary *keys;
Working_Set *working_set;
i16 font_id;
@ -518,7 +573,7 @@ ui_state_init(UI_State *state_in, Render_Target *target, Input_Summary *user_inp
return state;
}
inline bool32
inline b32
ui_state_match(UI_State a, UI_State b){
return (widget_match(a.selected, b.selected) &&
widget_match(a.hot, b.hot) &&
@ -536,12 +591,12 @@ ui_finish_frame(UI_State *persist_state, UI_State *state, UI_Layout *layout, i32
persist_state->view_y = state->view_y;
if (state->input_stage){
Mouse_Summary *mouse = state->mouse;
Mouse_State *mouse = state->mouse;
Font_Set *font_set = state->font_set;
if (mouse->wheel_used && do_wheel){
if (mouse->wheel != 0 && do_wheel){
i32 height = get_font_info(font_set, state->font_id)->height;
persist_state->view_y += mouse->wheel_amount*height;
persist_state->view_y += mouse->wheel*height;
result = 1;
}
if (mouse->release_l && widget_match(state->hot, state->hover)){
@ -567,11 +622,11 @@ ui_finish_frame(UI_State *persist_state, UI_State *state, UI_Layout *layout, i32
return result;
}
internal bool32
internal b32
ui_do_button_input(UI_State *state, i32_Rect rect, Widget_ID id, bool32 activate, bool32 *right = 0){
bool32 result = 0;
Mouse_Summary *mouse = state->mouse;
bool32 hover = hit_check(mouse->mx, mouse->my, rect);
b32 result = 0;
Mouse_State *mouse = state->mouse;
b32 hover = hit_check(mouse->x, mouse->y, rect);
if (hover){
state->hover = id;
if (activate) state->activate_me = 1;
@ -620,9 +675,9 @@ internal real32
ui_do_vscroll_input(UI_State *state, i32_Rect top, i32_Rect bottom, i32_Rect slider,
Widget_ID id, real32 val, real32 step_amount,
real32 smin, real32 smax, real32 vmin, real32 vmax){
Mouse_Summary *mouse = state->mouse;
i32 mx = mouse->mx;
i32 my = mouse->my;
Mouse_State *mouse = state->mouse;
i32 mx = mouse->x;
i32 my = mouse->y;
if (hit_check(mx, my, top)){
state->hover = id;
state->hover.sub_id2 = 1;
@ -647,8 +702,8 @@ ui_do_vscroll_input(UI_State *state, i32_Rect top, i32_Rect bottom, i32_Rect sli
state->redraw = 1;
}
if (state->hot.sub_id2 == 3){
real32 S, L;
S = (real32)mouse->my - (slider.y1 - slider.y0) / 2;
f32 S, L;
S = (f32)mouse->y - (slider.y1 - slider.y0) / 2;
if (S < smin) S = smin;
if (S > smax) S = smax;
L = unlerp(smin, S, smax);
@ -717,15 +772,15 @@ ui_do_line_field_input(System_Functions *system,
return result;
}
internal bool32
internal b32
ui_do_slider_input(UI_State *state, i32_Rect rect, Widget_ID wid,
real32 min, real32 max, real32 *v){
bool32 result = 0;
b32 result = 0;
ui_do_button_input(state, rect, wid, 0);
Mouse_Summary *mouse = state->mouse;
Mouse_State *mouse = state->mouse;
if (is_hot(state, wid)){
result = 1;
*v = unlerp(min, (real32)mouse->mx, max);
*v = unlerp(min, (f32)mouse->x, max);
state->redraw = 1;
}
return result;

View File

@ -74,7 +74,10 @@ struct Coroutine{
void *out;
};
#define Sys_Launch_Coroutine_Sig(name) Coroutine *name(Coroutine_Function *func, void *in, void *out)
#define Sys_Create_Coroutine_Sig(name) Coroutine *name(Coroutine_Function *func)
typedef Sys_Create_Coroutine_Sig(System_Create_Coroutine);
#define Sys_Launch_Coroutine_Sig(name) Coroutine *name(Coroutine *coroutine, void *in, void *out)
typedef Sys_Launch_Coroutine_Sig(System_Launch_Coroutine);
#define Sys_Resume_Coroutine_Sig(name) Coroutine *name(Coroutine *coroutine, void *in, void *out)
@ -194,6 +197,7 @@ struct System_Functions{
System_Time *time;
// coroutine: 4
System_Create_Coroutine *create_coroutine;
System_Launch_Coroutine *launch_coroutine;
System_Resume_Coroutine *resume_coroutine;
System_Yield_Coroutine *yield_coroutine;

View File

@ -1,3 +1,4 @@
@echo off
call "w:\4ed\misc\builddbg.bat"
"w:\4ed\misc\build_all.bat" /DFRED_NOT_PACKAGE /Zi
REM "w:\4ed\misc\build_all.bat" /O2 /Zi

View File

@ -8,8 +8,9 @@ SET WARNINGS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512
SET STUFF=/GR- /nologo
SET DEBUG=/Zi
SET EXPORTS=/EXPORT:get_bindings
SET SRC=4coder_custom.cpp
cl %WARNINGS% %STUFF% %DEBUG% 4coder_custom.cpp /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS%
cl %WARNINGS% %STUFF% %DEBUG% %SRC% /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS%
REM file spammation preventation
del *.exp

View File

@ -78,8 +78,8 @@ struct Win32_Input_Chunk_Transient{
b8 mouse_l_press, mouse_l_release;
b8 mouse_r_press, mouse_r_release;
b32 out_of_window;
i16 mouse_wheel;
b8 out_of_window;
i8 mouse_wheel;
b32 redraw;
};
@ -772,7 +772,7 @@ Win32CoroutineMain(void *arg_){
}
internal
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
Sys_Create_Coroutine_Sig(system_create_coroutine){
Win32_Coroutine *c;
Coroutine *coroutine;
void *fiber;
@ -786,6 +786,16 @@ Sys_Launch_Coroutine_Sig(system_launch_coroutine){
coroutine->plat_handle = Win32GenHandle(fiber);
coroutine->func = func;
return(coroutine);
}
internal
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
void *fiber;
fiber = Win32Handle(coroutine->plat_handle);
coroutine->yield_handle = GetCurrentFiber();
coroutine->in = in;
coroutine->out = out;
@ -1043,6 +1053,7 @@ Win32LoadSystemCode(){
win32vars.system->post_clipboard = system_post_clipboard;
win32vars.system->time = system_time;
win32vars.system->create_coroutine = system_create_coroutine;
win32vars.system->launch_coroutine = system_launch_coroutine;
win32vars.system->resume_coroutine = system_resume_coroutine;
win32vars.system->yield_coroutine = system_yield_coroutine;
@ -1058,9 +1069,11 @@ Win32LoadSystemCode(){
win32vars.system->acquire_lock = system_acquire_lock;
win32vars.system->release_lock = system_release_lock;
#ifdef FRED_NOT_PACKAGE
win32vars.system->internal_sentinel = INTERNAL_system_sentinel;
win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states;
win32vars.system->internal_debug_message = INTERNAL_system_debug_message;
#endif
win32vars.system->slash = '\\';
}
@ -1468,13 +1481,13 @@ UpdateLoop(LPVOID param){
input_data = input_chunk.trans.key_data;
mouse.out_of_window = input_chunk.trans.out_of_window;
mouse.left_button = input_chunk.pers.mouse_l;
mouse.left_button_pressed = input_chunk.trans.mouse_l_press;
mouse.left_button_released = input_chunk.trans.mouse_l_release;
mouse.l = input_chunk.pers.mouse_l;
mouse.press_l = input_chunk.trans.mouse_l_press;
mouse.release_l = input_chunk.trans.mouse_l_release;
mouse.right_button = input_chunk.pers.mouse_r;
mouse.right_button_pressed = input_chunk.trans.mouse_r_press;
mouse.right_button_released = input_chunk.trans.mouse_r_release;
mouse.r = input_chunk.pers.mouse_r;
mouse.press_r = input_chunk.trans.mouse_r_press;
mouse.release_r = input_chunk.trans.mouse_r_release;
mouse.wheel = input_chunk.trans.mouse_wheel;
@ -1580,6 +1593,10 @@ UpdateLoop(LPVOID param){
return(0);
}
#ifndef FRED_NOT_PACKAGE
#include <stdio.h>
#endif
#if 0
int
WinMain(HINSTANCE hInstance,