Tutorial framework ready to go
parent
cbb707fc27
commit
df315cd45a
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue