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:
parent
cd299761e9
commit
bc6fa9d9f2
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
11
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;
|
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
1
4ed.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue