diff --git a/4coder_API/4coder_types.h b/4coder_API/4coder_types.h index c7a28b79..96bde82f 100644 --- a/4coder_API/4coder_types.h +++ b/4coder_API/4coder_types.h @@ -1109,6 +1109,8 @@ ENUM(i32, Special_Hook_ID){ /* DOC(TODO) */ special_hook_modify_color_table, /* DOC(TODO) */ + special_hook_clipboard_change, + /* DOC(TODO) */ special_hook_get_view_buffer_region, }; @@ -1142,6 +1144,12 @@ STRUCT Color_Table{ TYPEDEF_FUNC Color_Table Modify_Color_Table_Function(struct Application_Links *app, Frame_Info frame); #define MODIFY_COLOR_TABLE_SIG(name) Color_Table name(struct Application_Links *app, Frame_Info frame) +ENUM(i32, Clipboard_Change_Flag){ + clipboard_from_os = 0x1, +}; +TYPEDEF_FUNC void Clipboard_Change_Hook_Function(struct Application_Links *app, String contents, u32 flags); +#define CLIPBOARD_CHANGE_HOOK_SIG(name) void name(struct Application_Links *app, String contents, u32 flags) + TYPEDEF_FUNC Rect_i32 Get_View_Buffer_Region_Function(struct Application_Links *app, View_ID view_id, Rect_i32 sub_region); #define GET_VIEW_BUFFER_REGION_SIG(name) Rect_i32 name(struct Application_Links *app, View_ID view_id, Rect_i32 sub_region) @@ -1239,5 +1247,10 @@ STRUCT Found_String_List{ i32 count; }; +STRUCT Process_State { + b32 is_updating; + i64 return_code; +}; + #endif diff --git a/4coder_base_types.cpp b/4coder_base_types.cpp index 43aec8c2..e04f61bb 100644 --- a/4coder_base_types.cpp +++ b/4coder_base_types.cpp @@ -984,5 +984,49 @@ rect_width(f32_Rect rect){ return(rect.x1 - rect.x0); } +static i32_Rect +intersection_of(i32_Rect a, i32_Rect b) +{ + i32_Rect result; + result.x0 = Max(a.x0, b.x0); + result.y0 = Max(a.y0, b.y0); + result.x1 = Min(a.x1, b.x1); + result.y1 = Min(a.y1, b.y1); + return(result); +} + +static i32_Rect +union_of(i32_Rect a, i32_Rect b) +{ + i32_Rect result; + result.x0 = Max(a.x0, b.x0); + result.y0 = Max(a.y0, b.y0); + result.x1 = Min(a.x1, b.x1); + result.y1 = Min(a.y1, b.y1); + return(result); +} + +static f32_Rect +intersection_of(f32_Rect a, f32_Rect b) +{ + f32_Rect result; + result.x0 = Max(a.x0, b.x0); + result.y0 = Max(a.y0, b.y0); + result.x1 = Min(a.x1, b.x1); + result.y1 = Min(a.y1, b.y1); + return(result); +} + +static f32_Rect +union_of(f32_Rect a, f32_Rect b) +{ + f32_Rect result; + result.x0 = Max(a.x0, b.x0); + result.y0 = Max(a.y0, b.y0); + result.x1 = Min(a.x1, b.x1); + result.y1 = Min(a.y1, b.y1); + return(result); +} + // BOTTOM diff --git a/4coder_helper.cpp b/4coder_helper.cpp index cf659e4c..7be01503 100644 --- a/4coder_helper.cpp +++ b/4coder_helper.cpp @@ -143,6 +143,15 @@ set_modify_color_table_hook(Bind_Helper *helper, Modify_Color_Table_Function *fu write_unit(helper, unit); } +static void +set_clipboard_change_hook(Bind_Helper *helper, Clipboard_Change_Hook_Function *func){ + Binding_Unit unit = {}; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_clipboard_change; + unit.hook.func = (void*)func; + write_unit(helper, unit); +} + static void set_get_view_buffer_region_hook(Bind_Helper *helper, Get_View_Buffer_Region_Function *func){ Binding_Unit unit = {}; diff --git a/4ed.cpp b/4ed.cpp index c1d28c7d..503cb7a5 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -397,6 +397,11 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){ models->modify_color_table = (Modify_Color_Table_Function*)unit->hook.func; }break; + case special_hook_clipboard_change: + { + models->clipboard_change = (Clipboard_Change_Hook_Function*)unit->hook.func; + }break; + case special_hook_get_view_buffer_region: { models->get_view_buffer_region = (Get_View_Buffer_Region_Function*)unit->hook.func; @@ -956,6 +961,9 @@ App_Step_Sig(app_step){ if (clipboard.str != 0){ String *dest = working_set_next_clipboard_string(&models->mem.heap, &models->working_set, clipboard.size); dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size); + if(input->clipboard_changed && models->clipboard_change) { + models->clipboard_change(&models->app_links, *dest, clipboard_from_os); + } } // NOTE(allen): check files are up to date @@ -1043,6 +1051,9 @@ App_Step_Sig(app_step){ append_int_to_str(&str, cli->exit); output_file_append(system, models, file, str); edited_file = true; + + file->is_updating = false; + file->return_code = cli->exit; } procs_to_free[proc_free_count++] = proc_ptr; } diff --git a/4ed.h b/4ed.h index cf8f2edc..9602c995 100644 --- a/4ed.h +++ b/4ed.h @@ -97,6 +97,7 @@ struct Application_Step_Input{ Key_Input_Data keys; Mouse_State mouse; String clipboard; + b32 clipboard_changed; b32 trying_to_kill; u32 debug_number; }; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 7225fd21..f7be80b1 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -362,6 +362,7 @@ DOC_SEE(The_4coder_Clipboard) return(true); } +// TODO(casey): Allen, why does this return a bool? Like, shouldn't it just return the count? If there's nothing in that clipboard, it'd just be 0? API_EXPORT b32 Clipboard_Count(Application_Links *app, i32 clipboard_id, i32 *count_out) /* @@ -4212,6 +4213,26 @@ draw_helper__view_space_to_screen_space(Models *models, f32_Rect rect){ return(rect); } +internal Vec2 +draw_helper__screen_space_to_view_space(Models *models, Vec2 point){ + i32_Rect region = models->render_view_rect; + point.x -= (f32)region.x0; + point.y -= (f32)region.y0; + return(point); +} + +internal f32_Rect +draw_helper__screen_space_to_view_space(Models *models, f32_Rect rect){ + i32_Rect region = models->render_view_rect; + f32 x_corner = (f32)region.x0; + f32 y_corner = (f32)region.y0; + rect.x0 -= x_corner; + rect.y0 -= y_corner; + rect.x1 -= x_corner; + rect.y1 -= y_corner; + return(rect); +} + // NOTE(allen): Coordinate space of draw calls: // The render space is such that 0,0 is _always_ the top left corner of the renderable region of the view. // To make text scroll with the buffer users should read the view's scroll position and subtract it first. @@ -4219,18 +4240,18 @@ draw_helper__view_space_to_screen_space(Models *models, f32_Rect rect){ API_EXPORT Vec2 Draw_String(Application_Links *app, Face_ID font_id, String str, Vec2 point, int_color color, u32 flags, Vec2 delta) { - Vec2 result = {}; + Vec2 result = point; Models *models = (Models*)app->cmd_context; if (models->render_view == 0){ f32 width = font_string_width(models->system, models->target, font_id, str); - result = delta*width; + result += delta*width; } else{ Color_Table color_table = models->color_table; point = draw_helper__view_space_to_screen_space(models, point); u32 actual_color = finalize_color(color_table, color); f32 width = draw_string(models->system, models->target, font_id, str, point, actual_color, flags, delta); - result = delta*width; + result += delta*width; } return(result); } @@ -4269,6 +4290,21 @@ Draw_Rectangle_Outline(Application_Links *app, f32_Rect rect, int_color color) } } +API_EXPORT void +Draw_Clip_Push(Application_Links *app, f32_Rect clip_box){ + Models *models = (Models*)app->cmd_context; + clip_box = draw_helper__view_space_to_screen_space(models, clip_box); + render_push_clip(models->target, i32R(clip_box)); +} + +API_EXPORT f32_Rect +Draw_Clip_Pop(Application_Links *app){ + Models *models = (Models*)app->cmd_context; + f32_Rect result = f32R(render_pop_clip(models->target)); + result = draw_helper__screen_space_to_view_space(models, result); + return(result); +} + API_EXPORT Face_ID Get_Default_Font_For_View(Application_Links *app, View_ID view_id) { @@ -4507,4 +4543,20 @@ Find_All_In_Range_Insensitive(Application_Links *app, Buffer_ID buffer_id, i32 s return(result); } +API_EXPORT Process_State +Get_Process_State(Application_Links *app, Buffer_ID buffer_id) +{ + Process_State result = {}; + + Models *models = (Models*)app->cmd_context; + Editing_File *file = imp_get_file(models, buffer_id); + if(file != 0) + { + result.is_updating = file->is_updating; + result.return_code = file->return_code; + } + + return(result); +} + // BOTTOM diff --git a/4ed_app_models.h b/4ed_app_models.h index 6f777c1e..0988591b 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -56,6 +56,7 @@ struct Models{ Scroll_Rule_Function *scroll_rule; Buffer_Name_Resolver_Function *buffer_name_resolver; Modify_Color_Table_Function *modify_color_table; + Clipboard_Change_Hook_Function *clipboard_change; Get_View_Buffer_Region_Function *get_view_buffer_region; Color_Table fallback_color_table; diff --git a/4ed_cli.cpp b/4ed_cli.cpp index 48dfa14a..c69bda35 100644 --- a/4ed_cli.cpp +++ b/4ed_cli.cpp @@ -24,6 +24,7 @@ cli_list_call(System_Functions *system, CLI_List *list, char *path, char *comman if (list->count < list->max){ CLI_Process *proc = &list->procs[list->count++]; + file->is_updating = true; proc->out_file = file; proc->cursor_at_end = cursor_at_end; result = system->cli_call(path, command, &proc->cli); diff --git a/4ed_edit.cpp b/4ed_edit.cpp index 2188555b..e89a861f 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -453,6 +453,11 @@ file_end_file(Models *models, Editing_File *file){ internal void edit_clear(System_Functions *system, Models *models, Editing_File *file){ file_end_file(models, file); + if(file) + { + file->is_updating = false; + file->return_code = 0; + } b32 no_views_see_file = true; diff --git a/4ed_file.h b/4ed_file.h index 560b7057..a1ead003 100644 --- a/4ed_file.h +++ b/4ed_file.h @@ -113,6 +113,10 @@ struct Editing_File{ Editing_File_Name canon; Node main_chain_node; Node edit_finished_mark_node; + + // NOTE(casey): Allen, these are for tracking whether a process is currently executing and what it's result was + b32 is_updating; + int64_t return_code; }; #endif diff --git a/4ed_render_target.cpp b/4ed_render_target.cpp index 18528239..853593e0 100644 --- a/4ed_render_target.cpp +++ b/4ed_render_target.cpp @@ -82,7 +82,13 @@ Render_Change_Clip_Sig(render_change_clip, t, clip_box){ internal Render_Push_Clip_Sig(render_push_clip, t, clip_box){ - Assert(t->clip_top == -1 || fits_inside(clip_box, t->clip_boxes[t->clip_top])); + // NOTE(casey): Allen, I nerfed this assertion because really people should be able to push any clip region they want, it + // should just be "restricted" to the previous clip regions, right? +// Assert(t->clip_top == -1 || fits_inside(clip_box, t->clip_boxes[t->clip_top])); + if(t->clip_top != -1) + { + clip_box = intersection_of(clip_box, t->clip_boxes[t->clip_top]); + } Assert(t->clip_top + 1 < ArrayCount(t->clip_boxes)); t->clip_boxes[++t->clip_top] = clip_box; render_internal_push_clip(t, clip_box); diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index cea0738c..10b618ad 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -2337,23 +2337,22 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS // NOTE(allen): Frame Clipboard Input memset(&win32vars.clipboard_contents, 0, sizeof(win32vars.clipboard_contents)); + input.clipboard_changed = false; if (win32vars.clipboard_sequence != 0){ DWORD new_number = GetClipboardSequenceNumber(); if (new_number != win32vars.clipboard_sequence){ if (win32vars.next_clipboard_is_self){ win32vars.next_clipboard_is_self = false; - win32vars.clipboard_sequence = new_number; } else{ - b32 got_contents = false; for (i32 R = 0; R < 4; ++R){ if (win32_read_clipboard_contents()){ - win32vars.clipboard_sequence = new_number; - got_contents = true; + input.clipboard_changed = true; break; } } } + win32vars.clipboard_sequence = new_number; } } input.clipboard = win32vars.clipboard_contents;