Tutorial framework ready to go

master
Allen Webster 2019-11-07 22:38:51 -08:00
parent cbb707fc27
commit df315cd45a
8 changed files with 181 additions and 60 deletions

View File

@ -2693,8 +2693,10 @@ try_create_new_face(Application_Links *app, Face_Description *description)
}
else{
Face *new_face = font_set_new_face(&models->font_set, description);
if (new_face != 0){
result = new_face->id;
}
}
return(result);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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){

View File

@ -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));
}

View File

@ -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);
}
}

View File

@ -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 },
};