Clipboard, Process, and Cliprect Changes

- Added clipboard change hook
- Added Process_State query for getting the state of exec_system_command operations, retrieved via Get_Process_State
- Added intersection_of and union_of for i32_Rect and f32_Rect
- Fixed what I believe is a bug in the clipboard number updating in the win32 layer (it didn't used to record the new number correctly)
- Added screen_space_to_view_space for Vec2 and f32_Rect
- Made Draw_String return the ending point, as we decided
- Added Draw_Clip_Push and Draw_Clip_Pop
- Changed the behavior of Render_Push_Clip_Sig to allow input clipping rectangles to be anything, and they are simply intersected with the parent rectangle, rather than asserted to not go outside.
-
This commit is contained in:
Casey Muratori 2019-03-15 01:38:28 -07:00
parent cd299761e9
commit bc6fa9d9f2
12 changed files with 154 additions and 8 deletions

View File

@ -1109,6 +1109,8 @@ ENUM(i32, Special_Hook_ID){
/* DOC(TODO) */ /* DOC(TODO) */
special_hook_modify_color_table, special_hook_modify_color_table,
/* DOC(TODO) */ /* DOC(TODO) */
special_hook_clipboard_change,
/* DOC(TODO) */
special_hook_get_view_buffer_region, 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); 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) #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); 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) #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; i32 count;
}; };
STRUCT Process_State {
b32 is_updating;
i64 return_code;
};
#endif #endif

View File

@ -984,5 +984,49 @@ rect_width(f32_Rect rect){
return(rect.x1 - rect.x0); 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 // BOTTOM

View File

@ -143,6 +143,15 @@ set_modify_color_table_hook(Bind_Helper *helper, Modify_Color_Table_Function *fu
write_unit(helper, unit); 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 static void
set_get_view_buffer_region_hook(Bind_Helper *helper, Get_View_Buffer_Region_Function *func){ set_get_view_buffer_region_hook(Bind_Helper *helper, Get_View_Buffer_Region_Function *func){
Binding_Unit unit = {}; Binding_Unit unit = {};

11
4ed.cpp
View File

@ -397,6 +397,11 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){
models->modify_color_table = (Modify_Color_Table_Function*)unit->hook.func; models->modify_color_table = (Modify_Color_Table_Function*)unit->hook.func;
}break; }break;
case special_hook_clipboard_change:
{
models->clipboard_change = (Clipboard_Change_Hook_Function*)unit->hook.func;
}break;
case special_hook_get_view_buffer_region: case special_hook_get_view_buffer_region:
{ {
models->get_view_buffer_region = (Get_View_Buffer_Region_Function*)unit->hook.func; 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){ if (clipboard.str != 0){
String *dest = working_set_next_clipboard_string(&models->mem.heap, &models->working_set, clipboard.size); 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); 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 // NOTE(allen): check files are up to date
@ -1043,6 +1051,9 @@ App_Step_Sig(app_step){
append_int_to_str(&str, cli->exit); append_int_to_str(&str, cli->exit);
output_file_append(system, models, file, str); output_file_append(system, models, file, str);
edited_file = true; edited_file = true;
file->is_updating = false;
file->return_code = cli->exit;
} }
procs_to_free[proc_free_count++] = proc_ptr; procs_to_free[proc_free_count++] = proc_ptr;
} }

1
4ed.h
View File

@ -97,6 +97,7 @@ struct Application_Step_Input{
Key_Input_Data keys; Key_Input_Data keys;
Mouse_State mouse; Mouse_State mouse;
String clipboard; String clipboard;
b32 clipboard_changed;
b32 trying_to_kill; b32 trying_to_kill;
u32 debug_number; u32 debug_number;
}; };

View File

@ -362,6 +362,7 @@ DOC_SEE(The_4coder_Clipboard)
return(true); 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 API_EXPORT b32
Clipboard_Count(Application_Links *app, i32 clipboard_id, i32 *count_out) 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); 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: // 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. // 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. // 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 API_EXPORT Vec2
Draw_String(Application_Links *app, Face_ID font_id, String str, Vec2 point, int_color color, u32 flags, Vec2 delta) 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; Models *models = (Models*)app->cmd_context;
if (models->render_view == 0){ if (models->render_view == 0){
f32 width = font_string_width(models->system, models->target, font_id, str); f32 width = font_string_width(models->system, models->target, font_id, str);
result = delta*width; result += delta*width;
} }
else{ else{
Color_Table color_table = models->color_table; Color_Table color_table = models->color_table;
point = draw_helper__view_space_to_screen_space(models, point); point = draw_helper__view_space_to_screen_space(models, point);
u32 actual_color = finalize_color(color_table, color); u32 actual_color = finalize_color(color_table, color);
f32 width = draw_string(models->system, models->target, font_id, str, point, actual_color, flags, delta); f32 width = draw_string(models->system, models->target, font_id, str, point, actual_color, flags, delta);
result = delta*width; result += delta*width;
} }
return(result); 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 API_EXPORT Face_ID
Get_Default_Font_For_View(Application_Links *app, View_ID view_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); 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 // BOTTOM

View File

@ -56,6 +56,7 @@ struct Models{
Scroll_Rule_Function *scroll_rule; Scroll_Rule_Function *scroll_rule;
Buffer_Name_Resolver_Function *buffer_name_resolver; Buffer_Name_Resolver_Function *buffer_name_resolver;
Modify_Color_Table_Function *modify_color_table; Modify_Color_Table_Function *modify_color_table;
Clipboard_Change_Hook_Function *clipboard_change;
Get_View_Buffer_Region_Function *get_view_buffer_region; Get_View_Buffer_Region_Function *get_view_buffer_region;
Color_Table fallback_color_table; Color_Table fallback_color_table;

View File

@ -24,6 +24,7 @@ cli_list_call(System_Functions *system, CLI_List *list, char *path, char *comman
if (list->count < list->max){ if (list->count < list->max){
CLI_Process *proc = &list->procs[list->count++]; CLI_Process *proc = &list->procs[list->count++];
file->is_updating = true;
proc->out_file = file; proc->out_file = file;
proc->cursor_at_end = cursor_at_end; proc->cursor_at_end = cursor_at_end;
result = system->cli_call(path, command, &proc->cli); result = system->cli_call(path, command, &proc->cli);

View File

@ -453,6 +453,11 @@ file_end_file(Models *models, Editing_File *file){
internal void internal void
edit_clear(System_Functions *system, Models *models, Editing_File *file){ edit_clear(System_Functions *system, Models *models, Editing_File *file){
file_end_file(models, file); file_end_file(models, file);
if(file)
{
file->is_updating = false;
file->return_code = 0;
}
b32 no_views_see_file = true; b32 no_views_see_file = true;

View File

@ -113,6 +113,10 @@ struct Editing_File{
Editing_File_Name canon; Editing_File_Name canon;
Node main_chain_node; Node main_chain_node;
Node edit_finished_mark_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 #endif

View File

@ -82,7 +82,13 @@ Render_Change_Clip_Sig(render_change_clip, t, clip_box){
internal internal
Render_Push_Clip_Sig(render_push_clip, t, clip_box){ 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)); Assert(t->clip_top + 1 < ArrayCount(t->clip_boxes));
t->clip_boxes[++t->clip_top] = clip_box; t->clip_boxes[++t->clip_top] = clip_box;
render_internal_push_clip(t, clip_box); render_internal_push_clip(t, clip_box);

View File

@ -2337,23 +2337,22 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// NOTE(allen): Frame Clipboard Input // NOTE(allen): Frame Clipboard Input
memset(&win32vars.clipboard_contents, 0, sizeof(win32vars.clipboard_contents)); memset(&win32vars.clipboard_contents, 0, sizeof(win32vars.clipboard_contents));
input.clipboard_changed = false;
if (win32vars.clipboard_sequence != 0){ if (win32vars.clipboard_sequence != 0){
DWORD new_number = GetClipboardSequenceNumber(); DWORD new_number = GetClipboardSequenceNumber();
if (new_number != win32vars.clipboard_sequence){ if (new_number != win32vars.clipboard_sequence){
if (win32vars.next_clipboard_is_self){ if (win32vars.next_clipboard_is_self){
win32vars.next_clipboard_is_self = false; win32vars.next_clipboard_is_self = false;
win32vars.clipboard_sequence = new_number;
} }
else{ else{
b32 got_contents = false;
for (i32 R = 0; R < 4; ++R){ for (i32 R = 0; R < 4; ++R){
if (win32_read_clipboard_contents()){ if (win32_read_clipboard_contents()){
win32vars.clipboard_sequence = new_number; input.clipboard_changed = true;
got_contents = true;
break; break;
} }
} }
} }
win32vars.clipboard_sequence = new_number;
} }
} }
input.clipboard = win32vars.clipboard_contents; input.clipboard = win32vars.clipboard_contents;