From df315cd45abd63950b83f01e9e64979943a15012 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 7 Nov 2019 22:38:51 -0800 Subject: [PATCH] Tutorial framework ready to go --- 4ed_api_implementation.cpp | 4 +- 4ed_font_provider_freetype.cpp | 3 +- 4ed_layout.cpp | 3 +- custom/4coder_draw.cpp | 14 +-- custom/4coder_fancy.cpp | 8 ++ custom/4coder_lister_base.cpp | 75 +++++++--------- custom/4coder_tutorial.cpp | 132 ++++++++++++++++++++++++++-- custom/generated/command_metadata.h | 2 +- 8 files changed, 181 insertions(+), 60 deletions(-) diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index c54c128f..25d6ab56 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -2693,7 +2693,9 @@ try_create_new_face(Application_Links *app, Face_Description *description) } else{ Face *new_face = font_set_new_face(&models->font_set, description); - result = new_face->id; + if (new_face != 0){ + result = new_face->id; + } } return(result); } diff --git a/4ed_font_provider_freetype.cpp b/4ed_font_provider_freetype.cpp index 8b53a06f..36aa4b63 100644 --- a/4ed_font_provider_freetype.cpp +++ b/4ed_font_provider_freetype.cpp @@ -191,8 +191,9 @@ ft__font_make_face(Arena *arena, Face_Description *description, f32 scale_factor size.height = (pt_size << 6); FT_Request_Size(ft_face, &size); - face->description = *description; face->description.font.file_name = file_name; + face->description.font.in_4coder_font_folder = false; + face->description.parameters = description->parameters; Face_Metrics *met = &face->metrics; diff --git a/4ed_layout.cpp b/4ed_layout.cpp index 3444983c..55f36761 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -171,9 +171,10 @@ layout_split_panel(Layout *layout, Panel *panel, b32 vertical_split, Panel **new // init min_panel dll_insert(&layout->intermediate_panels, &min_panel->node); + panel->tl_panel->parent = min_panel; + panel->br_panel->parent = min_panel; min_panel->parent = panel; min_panel->kind = PanelKind_Intermediate; - min_panel->view = panel->view; min_panel->tl_panel = panel->tl_panel; min_panel->br_panel = panel->br_panel; min_panel->vertical_split = panel->vertical_split; diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index c496e1d3..1c675f44 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -172,16 +172,20 @@ layout_fps_hud_on_bottom(Rect_f32 rect, f32 line_height){ } function Rect_f32 -draw_background_and_margin(Application_Links *app, View_ID view, b32 is_active_view){ +draw_background_and_margin(Application_Links *app, View_ID view, FColor margin, FColor back){ Rect_f32 view_rect = view_get_screen_rect(app, view); Rect_f32 inner = rect_inner(view_rect, 3.f); - FColor margin_color = get_margin_color(is_active_view? - UIHighlight_Active:UIHighlight_None); - draw_rectangle(app, inner, 0.f, fcolor_id(Stag_Back)); - draw_margin(app, view_rect, inner, margin_color); + draw_rectangle(app, inner, 0.f, back); + draw_margin(app, view_rect, inner, margin); return(inner); } +function Rect_f32 +draw_background_and_margin(Application_Links *app, View_ID view, b32 is_active_view){ + FColor margin_color = get_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); + return(draw_background_and_margin(app, view, margin_color, fcolor_id(Stag_Back))); +} + function Rect_f32 draw_background_and_margin(Application_Links *app, View_ID view){ View_ID active_view = get_active_view(app, Access_Always); diff --git a/custom/4coder_fancy.cpp b/custom/4coder_fancy.cpp index 344dce7f..1b43efc6 100644 --- a/custom/4coder_fancy.cpp +++ b/custom/4coder_fancy.cpp @@ -646,6 +646,14 @@ get_fancy_line_height(Application_Links *app, Face_ID face, Fancy_Line *line){ return(get_fancy_string_height__inner(app, face, line->first)); } +function Vec2_f32 +get_fancy_line_dim(Application_Links *app, Face_ID face, Fancy_Line *line){ + if (line->face != 0){ + face = line->face; + } + return(V2f32(get_fancy_string_width__inner(app, face, line->first), get_fancy_string_height__inner(app, face, line->first))); +} + function Vec2_f32 draw_fancy_line(Application_Links *app, Face_ID face, FColor fore, Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){ diff --git a/custom/4coder_lister_base.cpp b/custom/4coder_lister_base.cpp index 846b4958..2faebeff 100644 --- a/custom/4coder_lister_base.cpp +++ b/custom/4coder_lister_base.cpp @@ -619,11 +619,25 @@ run_lister(Application_Links *app, Lister *lister){ }break; case InputEventKind_MouseMove: - case InputEventKind_Core: { lister_update_filtered_list(app, lister); }break; + case InputEventKind_Core: + { + switch (in.event.core.code){ + case CoreCode_Animate: + { + lister_update_filtered_list(app, lister); + }break; + + default: + { + handled = false; + }break; + } + }break; + default: { handled = false; @@ -671,8 +685,7 @@ lister_begin_new_item_set(Application_Links *app, Lister *lister){ } function void* -lister_add_item(Lister *lister, Lister_Prealloced_String string, - Lister_Prealloced_String status, void *user_data, umem extra_space){ +lister_add_item(Lister *lister, Lister_Prealloced_String string, Lister_Prealloced_String status, void *user_data, umem extra_space){ void *base_memory = push_array(lister->arena, u8, sizeof(Lister_Node) + extra_space); Lister_Node *node = (Lister_Node*)base_memory; node->string = string.string; @@ -688,15 +701,12 @@ lister_add_item(Lister *lister, Lister_Prealloced_String string, function void* lister_add_item(Lister *lister, Lister_Prealloced_String string, String_Const_u8 status, void *user_data, umem extra_space){ - return(lister_add_item(lister, string, lister_prealloced(push_string_copy(lister->arena, status)), - user_data, extra_space)); + return(lister_add_item(lister, string, lister_prealloced(push_string_copy(lister->arena, status)), user_data, extra_space)); } function void* -lister_add_item(Lister *lister, String_Const_u8 string, Lister_Prealloced_String status, - void *user_data, umem extra_space){ - return(lister_add_item(lister, lister_prealloced(push_string_copy(lister->arena, string)), status, - user_data, extra_space)); +lister_add_item(Lister *lister, String_Const_u8 string, Lister_Prealloced_String status, void *user_data, umem extra_space){ + return(lister_add_item(lister, lister_prealloced(push_string_copy(lister->arena, string)), status, user_data, extra_space)); } function void* @@ -738,8 +748,7 @@ lister__backspace_text_field__default(Application_Links *app){ } function void -lister__navigate__default(Application_Links *app, View_ID view, Lister *lister, - i32 delta){ +lister__navigate__default(Application_Links *app, View_ID view, Lister *lister, i32 delta){ i32 new_index = lister->item_index + delta; if (new_index < 0 && lister->item_index == 0){ lister->item_index = lister->filtered.count - 1; @@ -767,8 +776,7 @@ lister_get_default_handlers(void){ //////////////////////////////// function Lister_Result -run_lister_with_refresh_handler(Application_Links *app, Arena *arena, - String_Const_u8 query, Lister_Handlers handlers){ +run_lister_with_refresh_handler(Application_Links *app, Arena *arena, String_Const_u8 query, Lister_Handlers handlers){ Lister_Result result = {}; if (handlers.refresh != 0){ Lister *lister = begin_lister(app, arena); @@ -788,30 +796,25 @@ run_lister_with_refresh_handler(Application_Links *app, Arena *arena, } function Lister_Result -run_lister_with_refresh_handler(Application_Links *app, String_Const_u8 query, - Lister_Handlers handlers){ +run_lister_with_refresh_handler(Application_Links *app, String_Const_u8 query, Lister_Handlers handlers){ Scratch_Block scratch(app); return(run_lister_with_refresh_handler(app, scratch, query, handlers)); } function Lister_Result -run_lister_with_refresh_handler(Application_Links *app, Arena *arena, - char *query, Lister_Handlers handlers){ +run_lister_with_refresh_handler(Application_Links *app, Arena *arena, char *query, Lister_Handlers handlers){ return(run_lister_with_refresh_handler(app, arena, SCu8(query), handlers)); } function Lister_Result -run_lister_with_refresh_handler(Application_Links *app, - char *query, Lister_Handlers handlers){ +run_lister_with_refresh_handler(Application_Links *app, char *query, Lister_Handlers handlers){ return(run_lister_with_refresh_handler(app, SCu8(query), handlers)); } //////////////////////////////// function void -lister_choice(Arena *arena, Lister_Choice_List *list, - String_Const_u8 string, String_Const_u8 status, - Key_Code code, u64 user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, String_Const_u8 string, String_Const_u8 status, Key_Code code, u64 user_data){ Lister_Choice *choice = push_array(arena, Lister_Choice, 1); sll_queue_push(list->first, list->last, choice); choice->string = string; @@ -821,52 +824,38 @@ lister_choice(Arena *arena, Lister_Choice_List *list, } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - char *string, String_Const_u8 status, - Key_Code code, u64 user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, char *string, String_Const_u8 status, Key_Code code, u64 user_data){ lister_choice(arena, list, SCu8(string), status, code, (u64)PtrAsInt(user_data)); } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - String_Const_u8 string, char *status, - Key_Code code, u64 user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, String_Const_u8 string, char *status, Key_Code code, u64 user_data){ lister_choice(arena, list, string, SCu8(status), code, (u64)PtrAsInt(user_data)); } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - char *string, char *status, - Key_Code code, u64 user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, char *string, char *status, Key_Code code, u64 user_data){ lister_choice(arena, list, SCu8(string), SCu8(status), code, (u64)PtrAsInt(user_data)); } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - String_Const_u8 string, String_Const_u8 status, - Key_Code code, void *user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, String_Const_u8 string, String_Const_u8 status, Key_Code code, void *user_data){ lister_choice(arena, list, string, status, code, (u64)PtrAsInt(user_data)); } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - char *string, String_Const_u8 status, - Key_Code code, void *user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, char *string, String_Const_u8 status, Key_Code code, void *user_data){ lister_choice(arena, list, string, status, code, (u64)PtrAsInt(user_data)); } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - String_Const_u8 string, char *status, - Key_Code code, void *user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, String_Const_u8 string, char *status, Key_Code code, void *user_data){ lister_choice(arena, list, string, status, code, (u64)PtrAsInt(user_data)); } function void -lister_choice(Arena *arena, Lister_Choice_List *list, - char *string, char *status, - Key_Code code, void *user_data){ +lister_choice(Arena *arena, Lister_Choice_List *list, char *string, char *status, Key_Code code, void *user_data){ lister_choice(arena, list, string, status, code, (u64)PtrAsInt(user_data)); } diff --git a/custom/4coder_tutorial.cpp b/custom/4coder_tutorial.cpp index fb5abaa4..39e6acfd 100644 --- a/custom/4coder_tutorial.cpp +++ b/custom/4coder_tutorial.cpp @@ -5,12 +5,48 @@ // TOP global b32 in_tutorial = false; +global View_ID tutorial_view = 0; +global Face_ID tutorial_face = 0; +global b32 tutorial_is_active = false; function void kill_tutorial(Application_Links *app){ - if (in_tutorial){ - + if (!in_tutorial){ + return; } + + in_tutorial = false; + view_close(app, tutorial_view); +} + +function void +tutorial_activate(Application_Links *app){ + if (!in_tutorial){ + return; + } + + Panel_ID panel = view_get_panel(app, tutorial_view); + Panel_ID parent = panel_get_parent(app, panel); + panel_set_split(app, parent, PanelSplitKind_Ratio_Min, 0.5f); + + tutorial_is_active = true; +} + +function void +tutorial_deactivate(Application_Links *app){ + if (!in_tutorial){ + return; + } + + Face_ID face = get_face_id(app, 0); + Face_Metrics metrics = get_face_metrics(app, face); + f32 line_height = metrics.line_height; + + Panel_ID panel = view_get_panel(app, tutorial_view); + Panel_ID parent = panel_get_parent(app, panel); + panel_set_split(app, parent, PanelSplitKind_FixedPixels_Min, line_height*4.f); + + tutorial_is_active = false; } function void @@ -18,10 +54,42 @@ tutorial_default_4coder_render(Application_Links *app, Frame_Info frame_info, Vi View_ID active_view = get_active_view(app, Access_Always); b32 is_active_view = (active_view == view_id); - Rect_f32 region = draw_background_and_margin(app, view_id, is_active_view); + FColor margin_color = get_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); + Rect_f32 region = draw_background_and_margin(app, view_id, margin_color, margin_color); Rect_f32 prev_clip = draw_set_clip(app, region); - draw_rectangle(app, rect_inner(region, 10.f), 20.f, fcolor_id(Stag_Margin)); + region = rect_inner(region, 3.f); + draw_rectangle(app, region, 20.f, fcolor_id(Stag_Back)); + + if (tutorial_face == 0){ + Face_ID face = get_face_id(app, 0); + Face_Description face_description = get_face_description(app, face); + face_description.parameters.pt_size *= 2; + tutorial_face = try_create_new_face(app, &face_description); + if (tutorial_face == 0){ + tutorial_face = face; + } + } + + if (is_active_view){ + if (!tutorial_is_active){ + view_enqueue_command_function(app, view_id, tutorial_activate); + } + } + else{ + if (tutorial_is_active){ + view_enqueue_command_function(app, view_id, tutorial_deactivate); + } + } + + Scratch_Block scratch(app); + + Fancy_Line line = {}; + push_fancy_string(scratch, &line, tutorial_face, fcolor_id(Stag_Default), string_u8_litexpr("Tutorial")); + + Vec2_f32 line_dim = get_fancy_line_dim(app, 0, &line); + Vec2_f32 p = (region.p0 + region.p1 - line_dim)*0.5f; + draw_fancy_line(app, 0, fcolor_zero(), &line, p); draw_set_clip(app, prev_clip); } @@ -35,12 +103,60 @@ tutorial_default_4coder_run(Application_Links *app) ctx.hides_buffer = true; View_Context_Block ctx_block(app, view, &ctx); + in_tutorial = true; + tutorial_view = view; + for (;;){ - User_Input input = get_next_input(app, EventPropertyGroup_Any, 0); - if (input.abort){ + User_Input in = get_next_input(app, EventPropertyGroup_Any, 0); + if (in.abort){ break; } + + b32 handled = true; + switch (in.event.kind){ + case InputEventKind_Core: + { + switch (in.event.core.code){ + case CoreCode_ClickActivateView: + { + tutorial_activate(app); + }break; + + case CoreCode_ClickDeactivateView: + { + tutorial_deactivate(app); + }break; + + default: + { + handled = false; + }break; + } + }break; + + default: + { + handled = false; + }break; + } + + if (!handled){ + Mapping *mapping = ctx.mapping; + Command_Map *map = mapping_get_map(mapping, ctx.map_id); + + Fallback_Dispatch_Result disp_result = + fallback_command_dispatch(app, mapping, map, &in); + if (disp_result.code == FallbackDispatch_DelayedUICall){ + call_after_ctx_shutdown(app, view, disp_result.func); + break; + } + if (disp_result.code == FallbackDispatch_Unhandled){ + leave_current_input_unhandled(app); + } + } } + + in_tutorial = false; } CUSTOM_COMMAND_SIG(tutorial_default_4coder) @@ -51,10 +167,10 @@ CUSTOM_DOC("Tutorial for built in 4coder bindings and features.") Panel_ID root_panel = panel_get_root(app); if (panel_split(app, root_panel, Dimension_Y)){ panel_swap_children(app, root_panel); - panel_set_split(app, root_panel, PanelSplitKind_Ratio_Min, 0.5f); Panel_ID tutorial_panel = panel_get_child(app, root_panel, Side_Min); - View_ID tutorial_view = panel_get_view(app, tutorial_panel, Access_Always); + tutorial_view = panel_get_view(app, tutorial_panel, Access_Always); view_set_passive(app, tutorial_view, true); + tutorial_activate(app); view_enqueue_command_function(app, tutorial_view, tutorial_default_4coder_run); } } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 13be288d..9b9ce585 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -449,7 +449,7 @@ static Command_Metadata fcoder_metacmd_table[215] = { { PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 }, { PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, { PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 779 }, -{ PROC_LINKS(tutorial_default_4coder, 0), false, "tutorial_default_4coder", 23, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 46 }, +{ PROC_LINKS(tutorial_default_4coder, 0), false, "tutorial_default_4coder", 23, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 162 }, { PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, { PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 22 }, };