2 slides of the HMS demo tutorial ready
This commit is contained in:
parent
b8ed99c9b8
commit
9129e5898b
|
@ -51,6 +51,7 @@
|
||||||
#include "4coder_combined_write_commands.h"
|
#include "4coder_combined_write_commands.h"
|
||||||
#include "4coder_log_parser.h"
|
#include "4coder_log_parser.h"
|
||||||
#include "4coder_profile_inspect.h"
|
#include "4coder_profile_inspect.h"
|
||||||
|
#include "4coder_tutorial.h"
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -689,46 +689,66 @@ draw_fancy_string(Application_Links *app, Face_ID face, FColor fore,
|
||||||
|
|
||||||
function f32
|
function f32
|
||||||
get_fancy_line_width(Application_Links *app, Face_ID face, Fancy_Line *line){
|
get_fancy_line_width(Application_Links *app, Face_ID face, Fancy_Line *line){
|
||||||
|
f32 result = 0.f;
|
||||||
|
if (line != 0){
|
||||||
if (line->face != 0){
|
if (line->face != 0){
|
||||||
face = line->face;
|
face = line->face;
|
||||||
}
|
}
|
||||||
return(get_fancy_string_width__inner(app, face, line->first));
|
result = get_fancy_string_width__inner(app, face, line->first);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f32
|
function f32
|
||||||
get_fancy_line_height(Application_Links *app, Face_ID face, Fancy_Line *line){
|
get_fancy_line_height(Application_Links *app, Face_ID face, Fancy_Line *line){
|
||||||
|
f32 result = 0.f;
|
||||||
|
if (line != 0){
|
||||||
if (line->face != 0){
|
if (line->face != 0){
|
||||||
face = line->face;
|
face = line->face;
|
||||||
}
|
}
|
||||||
return(get_fancy_string_height__inner(app, face, line->first));
|
result = get_fancy_string_height__inner(app, face, line->first);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f32
|
function f32
|
||||||
get_fancy_line_text_height(Application_Links *app, Face_ID face, Fancy_Line *line){
|
get_fancy_line_text_height(Application_Links *app, Face_ID face, Fancy_Line *line){
|
||||||
|
f32 result = 0.f;
|
||||||
|
if (line != 0){
|
||||||
if (line->face != 0){
|
if (line->face != 0){
|
||||||
face = line->face;
|
face = line->face;
|
||||||
}
|
}
|
||||||
return(get_fancy_string_text_height__inner(app, face, line->first));
|
result = get_fancy_string_text_height__inner(app, face, line->first);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Vec2_f32
|
function Vec2_f32
|
||||||
get_fancy_line_dim(Application_Links *app, Face_ID face, Fancy_Line *line){
|
get_fancy_line_dim(Application_Links *app, Face_ID face, Fancy_Line *line){
|
||||||
|
Vec2_f32 result = {};
|
||||||
|
if (line != 0){
|
||||||
if (line->face != 0){
|
if (line->face != 0){
|
||||||
face = line->face;
|
face = line->face;
|
||||||
}
|
}
|
||||||
return(V2f32(get_fancy_string_width__inner(app, face, line->first), get_fancy_string_height__inner(app, face, line->first)));
|
result = V2f32(get_fancy_string_width__inner(app, face, line->first), get_fancy_string_height__inner(app, face, line->first));
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Vec2_f32
|
function Vec2_f32
|
||||||
draw_fancy_line(Application_Links *app, Face_ID face, FColor fore,
|
draw_fancy_line(Application_Links *app, Face_ID face, FColor fore,
|
||||||
Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){
|
Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){
|
||||||
|
Vec2_f32 result = {};
|
||||||
|
if (line != 0){
|
||||||
if (line->face != 0){
|
if (line->face != 0){
|
||||||
face = line->face;
|
face = line->face;
|
||||||
}
|
}
|
||||||
if (fcolor_is_valid(line->fore)){
|
if (fcolor_is_valid(line->fore)){
|
||||||
fore = line->fore;
|
fore = line->fore;
|
||||||
}
|
}
|
||||||
return(draw_fancy_string__inner(app, face, fore, line->first, p, flags, delta));
|
result = draw_fancy_string__inner(app, face, fore, line->first, p, flags, delta);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f32
|
function f32
|
||||||
|
|
|
@ -4,47 +4,35 @@
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
typedef i32 Tutorial_Action;
|
global Tutorial_State tutorial = {};
|
||||||
enum{
|
|
||||||
TutorialAction_None,
|
|
||||||
TutorialAction_Prev,
|
|
||||||
TutorialAction_Next,
|
|
||||||
};
|
|
||||||
|
|
||||||
global b32 in_tutorial = false;
|
|
||||||
global View_ID tutorial_view = 0;
|
|
||||||
global Face_ID tutorial_face = 0;
|
|
||||||
global b32 tutorial_is_active = false;
|
|
||||||
global Tutorial_Action tutorial_hover_action = TutorialAction_None;
|
|
||||||
global Tutorial_Action tutorial_depressed_action = TutorialAction_None;
|
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(kill_tutorial)
|
CUSTOM_COMMAND_SIG(kill_tutorial)
|
||||||
CUSTOM_DOC("If in the tutorial state - kill it.")
|
CUSTOM_DOC("If there is an active tutorial, kill it.")
|
||||||
{
|
{
|
||||||
if (!in_tutorial){
|
if (!tutorial.in_tutorial){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_tutorial = false;
|
tutorial.in_tutorial = false;
|
||||||
view_close(app, tutorial_view);
|
view_close(app, tutorial.view);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
tutorial_activate(Application_Links *app){
|
tutorial_activate(Application_Links *app){
|
||||||
if (!in_tutorial){
|
if (!tutorial.in_tutorial){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel_ID panel = view_get_panel(app, tutorial_view);
|
Panel_ID panel = view_get_panel(app, tutorial.view);
|
||||||
Panel_ID parent = panel_get_parent(app, panel);
|
Panel_ID parent = panel_get_parent(app, panel);
|
||||||
panel_set_split(app, parent, PanelSplitKind_Ratio_Min, 0.5f);
|
panel_set_split(app, parent, PanelSplitKind_Ratio_Min, 0.5f);
|
||||||
|
|
||||||
tutorial_is_active = true;
|
tutorial.is_active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
tutorial_deactivate(Application_Links *app){
|
tutorial_deactivate(Application_Links *app){
|
||||||
if (!in_tutorial){
|
if (!tutorial.in_tutorial){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,20 +40,73 @@ tutorial_deactivate(Application_Links *app){
|
||||||
Face_Metrics metrics = get_face_metrics(app, face);
|
Face_Metrics metrics = get_face_metrics(app, face);
|
||||||
f32 line_height = metrics.line_height;
|
f32 line_height = metrics.line_height;
|
||||||
|
|
||||||
Panel_ID panel = view_get_panel(app, tutorial_view);
|
Panel_ID panel = view_get_panel(app, tutorial.view);
|
||||||
Panel_ID parent = panel_get_parent(app, panel);
|
Panel_ID parent = panel_get_parent(app, panel);
|
||||||
panel_set_split(app, parent, PanelSplitKind_FixedPixels_Min, line_height*4.f);
|
panel_set_split(app, parent, PanelSplitKind_FixedPixels_Min, line_height*4.f);
|
||||||
|
|
||||||
tutorial_is_active = false;
|
tutorial.is_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
tutorial_action(Application_Links *app, Tutorial_Action action){
|
tutorial_action(Application_Links *app, Tutorial_Action action){
|
||||||
|
switch (action){
|
||||||
|
case TutorialAction_Prev:
|
||||||
|
{
|
||||||
|
tutorial.slide_index -= 1;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case TutorialAction_Next:
|
||||||
|
{
|
||||||
|
tutorial.slide_index += 1;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case TutorialAction_Exit:
|
||||||
|
{
|
||||||
|
kill_tutorial(app);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case TutorialAction_Restart:
|
||||||
|
{
|
||||||
|
tutorial.slide_index = 0;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
tutorial_default_4coder_render(Application_Links *app, Frame_Info frame_info, View_ID view_id){
|
tutorial_init_title_face(Application_Links *app){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
default_4coder_tutorial_render(Application_Links *app, Frame_Info frame_info, View_ID view_id){
|
||||||
|
Face_ID face = get_face_id(app, 0);
|
||||||
|
tutorial_init_title_face(app);
|
||||||
|
Face_Metrics metrics = get_face_metrics(app, face);
|
||||||
|
Face_Metrics tut_metrics = get_face_metrics(app, tutorial.face);
|
||||||
|
|
||||||
|
////////
|
||||||
|
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
tutorial.slide_index = clamp(0, tutorial.slide_index, tutorial.slide_count - 1);
|
||||||
|
Tutorial_Slide_Function *slide_func = tutorial.slide_func_ptrs[tutorial.slide_index];
|
||||||
|
Tutorial_Slide slide = slide_func(app, scratch);
|
||||||
|
|
||||||
|
////////
|
||||||
|
|
||||||
|
f32 h0 = get_fancy_line_height(app, 0, &slide.short_details);
|
||||||
|
f32 h1 = get_fancy_line_height(app, 0, slide.long_details.first);
|
||||||
|
f32 title_height = max(h0, h1);
|
||||||
|
|
||||||
|
////////
|
||||||
|
|
||||||
View_ID active_view = get_active_view(app, Access_Always);
|
View_ID active_view = get_active_view(app, Access_Always);
|
||||||
b32 is_active_view = (active_view == view_id);
|
b32 is_active_view = (active_view == view_id);
|
||||||
|
|
||||||
|
@ -79,170 +120,93 @@ tutorial_default_4coder_render(Application_Links *app, Frame_Info frame_info, Vi
|
||||||
draw_rectangle(app, region, 20.f, fcolor_id(Stag_Back));
|
draw_rectangle(app, region, 20.f, fcolor_id(Stag_Back));
|
||||||
region = rect_inner(region, 10.f);
|
region = rect_inner(region, 10.f);
|
||||||
|
|
||||||
Face_ID face = get_face_id(app, 0);
|
Vec2_f32 title_p = V2f32(region.x0, panel_y0 + (metrics.line_height*2.f) - title_height*0.5f);
|
||||||
|
|
||||||
if (tutorial_face == 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Face_Metrics metrics = get_face_metrics(app, face);
|
|
||||||
Face_Metrics tut_metrics = get_face_metrics(app, tutorial_face);
|
|
||||||
|
|
||||||
Vec2_f32 title_p = V2f32(region.x0, panel_y0 + (metrics.line_height*2.f) - tut_metrics.line_height*0.5f);
|
|
||||||
|
|
||||||
if (is_active_view){
|
if (is_active_view){
|
||||||
if (!tutorial_is_active){
|
if (!tutorial.is_active){
|
||||||
view_enqueue_command_function(app, view_id, tutorial_activate);
|
view_enqueue_command_function(app, view_id, tutorial_activate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (tutorial_is_active){
|
if (tutorial.is_active){
|
||||||
view_enqueue_command_function(app, view_id, tutorial_deactivate);
|
view_enqueue_command_function(app, view_id, tutorial_deactivate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scratch_Block scratch(app);
|
tutorial.hover_action = TutorialAction_None;
|
||||||
|
if (tutorial.is_active){
|
||||||
String_Const_u8 title = string_u8_litexpr("Handmade Seattle Demo");
|
draw_fancy_block(app, 0, fcolor_zero(), &slide.long_details, title_p);
|
||||||
|
|
||||||
Fancy_Block long_details = {};
|
|
||||||
push_fancy_line(scratch, &long_details, tutorial_face, fcolor_id(Stag_Pop1), title);
|
|
||||||
|
|
||||||
//
|
|
||||||
Fancy_Line *line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
#define M "If there are any features you'd like to know about or try out, "
|
|
||||||
push_fancy_string(scratch, line, string_u8_litexpr(M));
|
|
||||||
#undef M
|
|
||||||
push_fancy_string(scratch, line, fcolor_id(Stag_Keyword), string_u8_litexpr("ask!"));
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Pop1), string_u8_litexpr(""));
|
|
||||||
|
|
||||||
//
|
|
||||||
push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Keyword), string_u8_litexpr("Let's start with a few navigation commands:"));
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Control Comma>");
|
|
||||||
push_fancy_stringf(scratch, line, "change active panel");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<*AnyArrow*>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor one character or line");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Control *AnyArrow*>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor by 'chunks'");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Home>, <End>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor to the first/last character of the line");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<PageUp>, <PageDown>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor by full pages up/down");
|
|
||||||
|
|
||||||
//
|
|
||||||
push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Keyword), string_u8_litexpr("Available in code files:"));
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Alt OpenBracket>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor and mark to surrounding scope");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Alt CloseBracket>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor and mark to previous scope");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Alt SingleQuote>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor and mark to next scope");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Alt Shift CloseBracket>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor and mark to previous top-level scope");
|
|
||||||
|
|
||||||
//
|
|
||||||
line = push_fancy_line(scratch, &long_details, face, fcolor_id(Stag_Default));
|
|
||||||
push_fancy_stringf(scratch, line, fcolor_id(Stag_Pop2),
|
|
||||||
"%40s ", "<Alt Shift SingleQuote>");
|
|
||||||
push_fancy_stringf(scratch, line, "move cursor and mark to next top-level scope");
|
|
||||||
|
|
||||||
|
|
||||||
////
|
|
||||||
Fancy_Line short_details = {};
|
|
||||||
push_fancy_string(scratch, &short_details, tutorial_face, fcolor_id(Stag_Pop1), title);
|
|
||||||
push_fancy_string(scratch, &short_details, face, fcolor_id(Stag_Default), 8.f, 8.f, string_u8_litexpr("Welcome to Handmade Seattle and to this 4coder demo!"));
|
|
||||||
push_fancy_string(scratch, &short_details, face, fcolor_id(Stag_Pop2), string_u8_litexpr("Click here to see more."));
|
|
||||||
|
|
||||||
tutorial_hover_action = TutorialAction_None;
|
|
||||||
|
|
||||||
if (tutorial_is_active){
|
|
||||||
draw_fancy_block(app, 0, fcolor_zero(), &long_details, title_p);
|
|
||||||
|
|
||||||
// NOTE(allen): buttons
|
// NOTE(allen): buttons
|
||||||
Rect_f32_Pair pair = rect_split_top_bottom_neg(region, metrics.line_height*2.f);
|
Rect_f32_Pair footer_pair = rect_split_top_bottom_neg(region, metrics.line_height*2.f);
|
||||||
Rect_f32 footer = pair.max;
|
Rect_f32 footer = footer_pair.max;
|
||||||
footer.x0 += 10.f;
|
footer.x0 += 10.f;
|
||||||
footer.y0 -= 10.f;
|
footer.y0 -= 10.f;
|
||||||
footer.y1 -= 10.f;
|
footer.y1 -= 10.f;
|
||||||
|
|
||||||
f32 b_width = metrics.normal_advance*10.f;
|
f32 b_width = metrics.normal_advance*10.f;
|
||||||
Rect_f32_Pair b1_pair = rect_split_left_right(footer, b_width);
|
|
||||||
footer = b1_pair.max;
|
|
||||||
footer.x0 += 10.f;
|
|
||||||
Rect_f32_Pair b2_pair = rect_split_left_right(footer, b_width);
|
|
||||||
|
|
||||||
Mouse_State mouse = get_mouse_state(app);
|
Mouse_State mouse = get_mouse_state(app);
|
||||||
Vec2_f32 m_p = V2f32(mouse.p);
|
Vec2_f32 m_p = V2f32(mouse.p);
|
||||||
|
|
||||||
if (draw_button(app, b1_pair.min, m_p, face, string_u8_litexpr("prev"))){
|
{
|
||||||
tutorial_hover_action = TutorialAction_Prev;
|
Rect_f32_Pair pair = rect_split_left_right(footer, b_width);
|
||||||
|
footer = pair.max;
|
||||||
|
footer.x0 += 10.f;
|
||||||
|
if (tutorial.slide_index > 0){
|
||||||
|
if (draw_button(app, pair.min, m_p, face, string_u8_litexpr("prev"))){
|
||||||
|
tutorial.hover_action = TutorialAction_Prev;
|
||||||
}
|
}
|
||||||
if (draw_button(app, b2_pair.min, m_p, face, string_u8_litexpr("next"))){
|
|
||||||
tutorial_hover_action = TutorialAction_Next;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Rect_f32_Pair pair = rect_split_left_right(footer, b_width);
|
||||||
|
footer = pair.max;
|
||||||
|
footer.x0 += 10.f;
|
||||||
|
if (tutorial.slide_index < tutorial.slide_count - 1){
|
||||||
|
if (draw_button(app, pair.min, m_p, face, string_u8_litexpr("next"))){
|
||||||
|
tutorial.hover_action = TutorialAction_Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Rect_f32_Pair pair = rect_split_left_right(footer, b_width);
|
||||||
|
footer = pair.max;
|
||||||
|
footer.x0 += 10.f;
|
||||||
|
Rect_f32 exit_box = pair.min;
|
||||||
|
pair = rect_split_left_right(footer, b_width);
|
||||||
|
Rect_f32 restart_box = pair.min;
|
||||||
|
|
||||||
|
if (tutorial.slide_index == tutorial.slide_count - 1){
|
||||||
|
if (draw_button(app, exit_box, m_p, face, string_u8_litexpr("exit"))){
|
||||||
|
tutorial.hover_action = TutorialAction_Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw_button(app, restart_box, m_p, face, string_u8_litexpr("restart"))){
|
||||||
|
tutorial.hover_action = TutorialAction_Restart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
draw_fancy_line(app, 0, fcolor_zero(), &short_details, title_p);
|
draw_fancy_line(app, 0, fcolor_zero(), &slide.short_details, title_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_set_clip(app, prev_clip);
|
draw_set_clip(app, prev_clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
tutorial_default_4coder_run(Application_Links *app)
|
default_4coder_tutorial_run(Application_Links *app)
|
||||||
{
|
{
|
||||||
View_ID view = get_this_ctx_view(app, Access_Always);
|
View_ID view = get_this_ctx_view(app, Access_Always);
|
||||||
View_Context ctx = view_current_context(app, view);
|
View_Context ctx = view_current_context(app, view);
|
||||||
ctx.render_caller = tutorial_default_4coder_render;
|
ctx.render_caller = default_4coder_tutorial_render;
|
||||||
ctx.hides_buffer = true;
|
ctx.hides_buffer = true;
|
||||||
View_Context_Block ctx_block(app, view, &ctx);
|
View_Context_Block ctx_block(app, view, &ctx);
|
||||||
|
|
||||||
in_tutorial = true;
|
tutorial.in_tutorial = true;
|
||||||
tutorial_view = view;
|
tutorial.view = view;
|
||||||
|
|
||||||
for (;;){
|
for (;;){
|
||||||
User_Input in = get_next_input(app, EventPropertyGroup_Any, 0);
|
User_Input in = get_next_input(app, EventPropertyGroup_Any, 0);
|
||||||
|
@ -255,15 +219,15 @@ tutorial_default_4coder_run(Application_Links *app)
|
||||||
case InputEventKind_MouseButton:
|
case InputEventKind_MouseButton:
|
||||||
{
|
{
|
||||||
if (in.event.mouse.code == MouseCode_Left){
|
if (in.event.mouse.code == MouseCode_Left){
|
||||||
tutorial_depressed_action = tutorial_hover_action;
|
tutorial.depressed_action = tutorial.hover_action;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case InputEventKind_MouseButtonRelease:
|
case InputEventKind_MouseButtonRelease:
|
||||||
{
|
{
|
||||||
if (in.event.mouse.code == MouseCode_Left){
|
if (in.event.mouse.code == MouseCode_Left){
|
||||||
if (tutorial_depressed_action == tutorial_hover_action){
|
if (tutorial.depressed_action == tutorial.hover_action){
|
||||||
tutorial_action(app, tutorial_depressed_action);
|
tutorial_action(app, tutorial.depressed_action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
@ -310,7 +274,197 @@ tutorial_default_4coder_run(Application_Links *app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in_tutorial = false;
|
tutorial.in_tutorial = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
global String_Const_u8 hms_title = string_u8_litexpr("Handmade Seattle Demo");
|
||||||
|
|
||||||
|
function void
|
||||||
|
default_4coder_tutorial_short_details(Application_Links *app, Arena *arena, Fancy_Line *short_details){
|
||||||
|
Face_ID face = get_face_id(app, 0);
|
||||||
|
push_fancy_string(arena, short_details, tutorial.face, fcolor_id(Stag_Pop1), hms_title);
|
||||||
|
push_fancy_string(arena, short_details, face, fcolor_id(Stag_Default), 8.f, 8.f, string_u8_litexpr("Welcome to Handmade Seattle and to this 4coder demo!"));
|
||||||
|
push_fancy_string(arena, short_details, face, fcolor_id(Stag_Pop2), string_u8_litexpr("Click here to see more."));
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
default_4coder_tutorial_long_start(Application_Links *app, Arena *arena, Fancy_Block *long_details){
|
||||||
|
Fancy_Line *line = push_fancy_line(arena, long_details, tutorial.face, fcolor_id(Stag_Pop1), hms_title);
|
||||||
|
|
||||||
|
Face_ID face = get_face_id(app, 0);
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
#define M "If there are any features you'd like to know about or try out, "
|
||||||
|
push_fancy_string(arena, line, string_u8_litexpr(M));
|
||||||
|
#undef M
|
||||||
|
push_fancy_string(arena, line, fcolor_id(Stag_Keyword), string_u8_litexpr("ask!"));
|
||||||
|
|
||||||
|
//
|
||||||
|
push_fancy_line(arena, long_details, face, fcolor_id(Stag_Pop1), string_u8_litexpr(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tutorial_Slide
|
||||||
|
default_4coder_tutorial_slide_1(Application_Links *app, Arena *arena){
|
||||||
|
Tutorial_Slide result = {};
|
||||||
|
|
||||||
|
Face_ID face = get_face_id(app, 0);
|
||||||
|
tutorial_init_title_face(app);
|
||||||
|
|
||||||
|
default_4coder_tutorial_short_details(app, arena, &result.short_details);
|
||||||
|
|
||||||
|
Fancy_Block *long_details = &result.long_details;
|
||||||
|
default_4coder_tutorial_long_start(app, arena, long_details);
|
||||||
|
|
||||||
|
Fancy_Line *line = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
push_fancy_line(arena, long_details, face, fcolor_id(Stag_Keyword), string_u8_litexpr("Let's start with a few navigation commands:"));
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control Comma>");
|
||||||
|
push_fancy_stringf(arena, line, "change active panel");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<*AnyArrow*>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor one character or line");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control *AnyArrow*>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor by 'chunks'");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Home>, <End>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor to the first/last character of the line");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<PageUp>, <PageDown>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor by full pages up/down");
|
||||||
|
|
||||||
|
//
|
||||||
|
push_fancy_line(arena, long_details, face, fcolor_id(Stag_Keyword), string_u8_litexpr("Available in code files:"));
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Alt OpenBracket>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor and mark to surrounding scope");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Alt CloseBracket>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor and mark to previous scope");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Alt SingleQuote>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor and mark to next scope");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Alt Shift CloseBracket>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor and mark to previous top-level scope");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Alt Shift SingleQuote>");
|
||||||
|
push_fancy_stringf(arena, line, "move cursor and mark to next top-level scope");
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tutorial_Slide
|
||||||
|
default_4coder_tutorial_slide_2(Application_Links *app, Arena *arena){
|
||||||
|
Tutorial_Slide result = {};
|
||||||
|
|
||||||
|
Face_ID face = get_face_id(app, 0);
|
||||||
|
tutorial_init_title_face(app);
|
||||||
|
|
||||||
|
default_4coder_tutorial_short_details(app, arena, &result.short_details);
|
||||||
|
|
||||||
|
Fancy_Block *long_details = &result.long_details;
|
||||||
|
default_4coder_tutorial_long_start(app, arena, long_details);
|
||||||
|
|
||||||
|
Fancy_Line *line = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
push_fancy_line(arena, long_details, face, fcolor_id(Stag_Keyword), string_u8_litexpr("4coder's default editing paradigm is emacs-like but with some differences:"));
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<TextInsert>");
|
||||||
|
push_fancy_stringf(arena, line, "non-modal text insertion works in any user-writable buffers at the cursor");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Backspace>/<Delete>");
|
||||||
|
push_fancy_stringf(arena, line, "delete the previous/next character from the cursor");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control Space>");
|
||||||
|
push_fancy_stringf(arena, line, "moves the mark to the cursor cursor");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control D>");
|
||||||
|
push_fancy_stringf(arena, line, "delete the cursor to mark range");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control C>");
|
||||||
|
push_fancy_stringf(arena, line, "copy the cursor to mark range to the clipboard");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control X>");
|
||||||
|
push_fancy_stringf(arena, line, "cut the cursor to mark range to the clipboard");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control V>");
|
||||||
|
push_fancy_stringf(arena, line, "paste the clipboard to the buffer");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control Shift V>");
|
||||||
|
push_fancy_stringf(arena, line, "paste the clipboard to the buffer cycling through the clipboard's 'clips'");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control Z>");
|
||||||
|
push_fancy_stringf(arena, line, "undo the last edit");
|
||||||
|
|
||||||
|
//
|
||||||
|
line = push_fancy_line(arena, long_details, face, fcolor_id(Stag_Default));
|
||||||
|
push_fancy_stringf(arena, line, fcolor_id(Stag_Pop2),
|
||||||
|
"%40s ", "<Control Y>");
|
||||||
|
push_fancy_stringf(arena, line, "redo the last undone edit");
|
||||||
|
|
||||||
|
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(default_4coder_tutorial)
|
CUSTOM_COMMAND_SIG(default_4coder_tutorial)
|
||||||
|
@ -322,10 +476,19 @@ CUSTOM_DOC("Tutorial for built in 4coder bindings and features.")
|
||||||
if (panel_split(app, root_panel, Dimension_Y)){
|
if (panel_split(app, root_panel, Dimension_Y)){
|
||||||
panel_swap_children(app, root_panel);
|
panel_swap_children(app, root_panel);
|
||||||
Panel_ID tutorial_panel = panel_get_child(app, root_panel, Side_Min);
|
Panel_ID tutorial_panel = panel_get_child(app, root_panel, Side_Min);
|
||||||
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);
|
view_set_passive(app, tutorial.view, true);
|
||||||
tutorial_activate(app);
|
tutorial_activate(app);
|
||||||
view_enqueue_command_function(app, tutorial_view, tutorial_default_4coder_run);
|
|
||||||
|
local_persist Tutorial_Slide_Function *slides[] = {
|
||||||
|
default_4coder_tutorial_slide_1,
|
||||||
|
default_4coder_tutorial_slide_2,
|
||||||
|
};
|
||||||
|
tutorial.slide_index = 0;
|
||||||
|
tutorial.slide_func_ptrs = slides;
|
||||||
|
tutorial.slide_count = ArrayCount(slides);
|
||||||
|
|
||||||
|
view_enqueue_command_function(app, tutorial.view, default_4coder_tutorial_run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
4coder_tutorial.h - Guided graphical tutorial system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
#if !defined(FCODER_TUTORIAL_H)
|
||||||
|
#define FCODER_TUTORIAL_H
|
||||||
|
|
||||||
|
typedef i32 Tutorial_Action;
|
||||||
|
enum{
|
||||||
|
TutorialAction_None,
|
||||||
|
TutorialAction_Prev,
|
||||||
|
TutorialAction_Next,
|
||||||
|
TutorialAction_Exit,
|
||||||
|
TutorialAction_Restart,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Tutorial_Slide{
|
||||||
|
Fancy_Block long_details;
|
||||||
|
Fancy_Line short_details;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Tutorial_Slide Tutorial_Slide_Function(Application_Links *app, Arena *arena);
|
||||||
|
|
||||||
|
struct Tutorial_State{
|
||||||
|
b32 in_tutorial;
|
||||||
|
View_ID view;
|
||||||
|
Face_ID face;
|
||||||
|
b32 is_active;
|
||||||
|
Tutorial_Action hover_action;
|
||||||
|
Tutorial_Action depressed_action;
|
||||||
|
|
||||||
|
i32 slide_index;
|
||||||
|
Tutorial_Slide_Function **slide_func_ptrs;
|
||||||
|
i32 slide_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BOTTOM
|
|
@ -450,8 +450,8 @@ static Command_Metadata fcoder_metacmd_table[216] = {
|
||||||
{ 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_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(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(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(kill_tutorial, 0), false, "kill_tutorial", 13, "If in the tutorial state - kill it.", 35, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 21 },
|
{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 9 },
|
||||||
{ PROC_LINKS(default_4coder_tutorial, 0), false, "default_4coder_tutorial", 23, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 316 },
|
{ PROC_LINKS(default_4coder_tutorial, 0), false, "default_4coder_tutorial", 23, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 470 },
|
||||||
{ 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_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 },
|
{ 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