raddbg_server: checkpoint; raddbg: zoom panels

This commit is contained in:
Ryan Fleury committed 2026-10-14 20:53:32 -07:00
1 parent d5cbced499
commit 933f05949c
14 files changed
+655 -309

No files matched your search

+1 -1
View File
@@ -49,7 +49,7 @@ commands =
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry debug", .linux = "./build.sh raddbg debug meta", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg raddbg_server telemetry debug", .linux = "./build.sh raddbg debug meta", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [raddbg wsl]
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
+7
View File
@@ -10,6 +10,13 @@ target:
enabled: 1
}
target:
{
executable: "build/raddbg_server.exe"
working_directory: build
debug_subprocesses: 1
arguments: "mule_main.exe"
}
target:
{
executable: "build/metagen.exe"
working_directory: build
+1 -1
View File
@@ -82,7 +82,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
#if defined(DBG_INFO_H) && !defined(DI_INIT_MANUAL)
di_init(&cmdline);
#endif
#if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL)
#if defined(DEMON_H) && !defined(DMN_INIT_MANUAL)
dmn_init();
#endif
#if defined(DBG_ENGINE_CORE_H) && !defined(D_INIT_MANUAL)
+52 -39
View File
@@ -7,7 +7,7 @@ cfg_window_from_cfg(CFG_Node *cfg)
CFG_Node *result = &cfg_nil_node;
for(CFG_Node *c = cfg; c != &cfg_nil_node; c = c->parent)
{
if(c->parent->parent == cfg_node_root() && str8_match(c->string, str8_lit("window"), 0))
if(c->parent->parent == cfg_node_root() && str8_match(c->string, s("window"), 0))
{
result = c;
break;
@@ -21,56 +21,69 @@ cfg_panel_tree_from_cfg(Arena *arena, CFG_Node *cfg_root)
{
Temp scratch = scratch_begin(&arena, 1);
CFG_Node *wcfg = cfg_window_from_cfg(cfg_root);
CFG_Node *src_root = cfg_node_child_from_string(wcfg, str8_lit("panels"));
CFG_Node *src_root = cfg_node_child_from_string(wcfg, s("panels"));
CFG_PanelNode *dst_root = &cfg_nil_panel_node;
CFG_PanelNode *dst_focused = &cfg_nil_panel_node;
CFG_PanelNode *dst_zoom_root = &cfg_nil_panel_node;
{
Axis2 active_split_axis = cfg_node_child_from_string(wcfg, str8_lit("split_x")) != &cfg_nil_node ? Axis2_X : Axis2_Y;
Axis2 active_split_axis = cfg_node_child_from_string(wcfg, s("split_x")) != &cfg_nil_node ? Axis2_X : Axis2_Y;
CFG_NodeRec rec = {0};
CFG_PanelNode *dst_active_parent = &cfg_nil_panel_node;
for(CFG_Node *src = src_root; src != &cfg_nil_node; src = rec.next)
{
// rjf: build a panel node
CFG_PanelNode *dst = push_array(arena, CFG_PanelNode, 1);
MemoryCopyStruct(dst, &cfg_nil_panel_node);
dst->parent = dst_active_parent;
if(dst_active_parent != &cfg_nil_panel_node)
{
DLLPushBack_NPZ(&cfg_nil_panel_node, dst_active_parent->first, dst_active_parent->last, dst, next, prev);
dst_active_parent->child_count += 1;
}
if(dst_root == &cfg_nil_panel_node)
{
dst_root = dst;
}
// rjf: unpack this config string
MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src->string);
// rjf: extract cfg info
// rjf: build a panel node if this is a child panel
CFG_PanelNode *dst = &cfg_nil_panel_node;
B32 panel_has_children = 0;
dst->cfg = src;
dst->pct_of_parent = (src == src_root ? 1.f : (F32)f64_from_str8(src->string));
dst->tab_side = (cfg_node_child_from_string(src, str8_lit("tabs_on_bottom")) != &cfg_nil_node ? Side_Max : Side_Min);
dst->split_axis = active_split_axis;
for(CFG_Node *src_child = src->first; src_child != &cfg_nil_node; src_child = src_child->next)
if(src == src_root || (tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric))
{
MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_child->string);
if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric)
// rjf: allocate
dst = push_array(arena, CFG_PanelNode, 1);
MemoryCopyStruct(dst, &cfg_nil_panel_node);
dst->parent = dst_active_parent;
if(dst_active_parent != &cfg_nil_panel_node)
{
panel_has_children = 1;
DLLPushBack_NPZ(&cfg_nil_panel_node, dst_active_parent->first, dst_active_parent->last, dst, next, prev);
dst_active_parent->child_count += 1;
}
else if(str8_match(src_child->string, str8_lit("tabs_on_bottom"), 0))
if(dst_root == &cfg_nil_panel_node)
{
// NOTE(rjf): skip - this is a panel option.
dst_root = dst;
}
else if(str8_match(src_child->string, str8_lit("selected"), 0))
// rjf: extract cfg info
dst->cfg = src;
dst->pct_of_parent = (src == src_root ? 1.f : (F32)f64_from_str8(src->string));
dst->tab_side = (cfg_node_child_from_string(src, s("tabs_on_bottom")) != &cfg_nil_node ? Side_Max : Side_Min);
dst->split_axis = active_split_axis;
for(CFG_Node *src_child = src->first; src_child != &cfg_nil_node; src_child = src_child->next)
{
dst_focused = dst;
}
else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier)
{
cfg_node_ptr_list_push(arena, &dst->tabs, src_child);
if(cfg_node_child_from_string(src_child, str8_lit("selected")) != &cfg_nil_node)
MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_child->string);
if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric)
{
dst->selected_tab = src_child;
panel_has_children = 1;
}
if(str8_match(src_child->string, s("tabs_on_bottom"), 0))
{
// NOTE(rjf): skip - this is a panel option.
}
else if(str8_match(src_child->string, s("selected"), 0))
{
dst_focused = dst;
}
else if(str8_match(src_child->string, s("zoom_root"), 0))
{
dst_zoom_root = dst;
}
else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier)
{
cfg_node_ptr_list_push(arena, &dst->tabs, src_child);
if(cfg_node_child_from_string(src_child, s("selected")) != &cfg_nil_node)
{
dst->selected_tab = src_child;
}
}
}
}
@@ -103,7 +116,7 @@ cfg_panel_tree_from_cfg(Arena *arena, CFG_Node *cfg_root)
}
}
scratch_end(scratch);
CFG_PanelTree tree = {dst_root, dst_focused};
CFG_PanelTree tree = {dst_root, dst_focused, dst_zoom_root};
return tree;
}
@@ -179,7 +192,7 @@ cfg_target_rect_from_panel_node(Rng2F32 root_rect, CFG_PanelNode *root, CFG_Pane
// rjf: count ancestors
U64 ancestor_count = 0;
for(CFG_PanelNode *p = panel->parent; p != &cfg_nil_panel_node; p = p->parent)
for(CFG_PanelNode *p = panel->parent; p != root->parent; p = p->parent)
{
ancestor_count += 1;
}
@@ -188,7 +201,7 @@ cfg_target_rect_from_panel_node(Rng2F32 root_rect, CFG_PanelNode *root, CFG_Pane
CFG_PanelNode **ancestors = push_array(scratch.arena, CFG_PanelNode *, ancestor_count);
{
U64 ancestor_idx = 0;
for(CFG_PanelNode *p = panel->parent; p != &cfg_nil_panel_node; p = p->parent)
for(CFG_PanelNode *p = panel->parent; p != root->parent; p = p->parent)
{
ancestors[ancestor_idx] = p;
ancestor_idx += 1;
@@ -203,7 +216,7 @@ cfg_target_rect_from_panel_node(Rng2F32 root_rect, CFG_PanelNode *root, CFG_Pane
{
CFG_PanelNode *ancestor = ancestors[ancestor_idx];
CFG_PanelNode *parent = ancestor->parent;
if(parent != &cfg_nil_panel_node)
if(parent != root->parent)
{
parent_rect = cfg_target_rect_from_panel_node_child(parent_rect, parent, ancestor);
}
+1
View File
@@ -33,6 +33,7 @@ struct CFG_PanelTree
{
CFG_PanelNode *root;
CFG_PanelNode *focused;
CFG_PanelNode *zoom_root;
};
typedef struct CFG_PanelNodeRec CFG_PanelNodeRec;
+27 -10
View File
@@ -3830,21 +3830,38 @@ d_ctrl_thread__open_remote_server(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
SOCK_Endpoint endpoint = sock_endpoint_from_string(msg->path);
//- rjf: handshake & get state
B32 good_handshake = 1;
{
Temp scratch = scratch_begin(0, 0);
DS_Msg msg = {0};
// rjf: send handshake packet
{
msg.kind = DS_MsgKind_Handshake;
msg.msg_id = 1;
DS_Msg server_msg = {0};
{
server_msg.kind = DS_MsgKind_Handshake;
server_msg.msg_id = 1;
}
String8 send_packet = ds_packet_from_msg(scratch.arena, &server_msg);
sock_send(d_ctrl_state->sock_session, SOCK_Protocol_TCP, endpoint, send_packet, max_U64);
}
String8 msg_raw = ds_packet_from_msg(scratch.arena, &msg);
DS_PacketHeader header =
// rjf: receive state packet(s)
{
.magic = DS_PACKET_MAGIC,
.kind = DS_PacketKind_Msg,
.version = DS_PACKET_VERSION,
.payload_size = msg_raw.size,
};
SOCK_Protocol recv_protocol = SOCK_Protocol_TCP;
SOCK_Endpoint recv_endpoint = {0};
String8 recv_packet = {0};
sock_recv(scratch.arena, d_ctrl_state->sock_session, &recv_protocol, &recv_endpoint, &recv_packet, now_time_us()+10000000);
if(recv_packet.size == 0)
{
good_handshake = 0;
}
}
// rjf: report failure
if(!good_handshake)
{
log_user_errorf("Couldn't successfully connect to server at %S (%S).", sock_string_from_endpoint(scratch.arena, endpoint), msg->path);
}
scratch_end(scratch);
}
+3
View File
@@ -40,6 +40,7 @@ ds_msg_from_packet(Arena *arena, String8 data)
String8 string = {0};
off += str8_deserial_read_struct(payload, off, &string.size);
string = str8_substr(payload, r1u64(off, off+string.size));
off += string.size;
str8_list_push(arena, &msg.command_line, string);
}
}
@@ -49,6 +50,7 @@ ds_msg_from_packet(Arena *arena, String8 data)
String8 string = {0};
off += str8_deserial_read_struct(payload, off, &string.size);
string = str8_substr(payload, r1u64(off, off+string.size));
off += string.size;
msg.path = string;
}
@@ -61,6 +63,7 @@ ds_msg_from_packet(Arena *arena, String8 data)
String8 string = {0};
off += str8_deserial_read_struct(payload, off, &string.size);
string = str8_substr(payload, r1u64(off, off+string.size));
off += string.size;
str8_list_push(arena, &msg.env, string);
}
}
+1 -1
View File
@@ -131,6 +131,6 @@ internal String8 ds_packet_from_msg(Arena *arena, DS_Msg *msg);
internal DS_Response ds_response_from_packet(Arena *arena, String8 data);
internal String8 ds_packet_from_response(Arena *arena, DS_Response *response);
internal DMN_EventList ds_dmn_events_from_packet(Arena *arena, String8 data);
internal String8 ds_serialized_from_dmn_events(Arena *arena, DMN_EventList evts);
internal String8 ds_packet_from_dmn_events(Arena *arena, DMN_EventList evts);
#endif // DBG_SERVER_H
+11 -3
View File
@@ -62,7 +62,7 @@ str8_lit_comp(""),
str8_lit_comp(""),
};
RD_VocabInfo rd_vocab_info_table[375] =
RD_VocabInfo rd_vocab_info_table[379] =
{
{str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars},
{str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline},
@@ -254,11 +254,15 @@ RD_VocabInfo rd_vocab_info_table[375] =
{str8_lit_comp("rotate_panel_columns"), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), str8_lit_comp(""), RD_IconKind_Null},
{str8_lit_comp("next_panel"), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), str8_lit_comp(""), RD_IconKind_RightArrow},
{str8_lit_comp("prev_panel"), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), str8_lit_comp(""), RD_IconKind_LeftArrow},
{str8_lit_comp("parent_panel"), str8_lit_comp(""), str8_lit_comp("Focus Parent Panel"), str8_lit_comp(""), RD_IconKind_Null},
{str8_lit_comp("focus_panel"), str8_lit_comp(""), str8_lit_comp("Focus Panel"), str8_lit_comp(""), RD_IconKind_Null},
{str8_lit_comp("focus_panel_right"), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), str8_lit_comp(""), RD_IconKind_RightArrow},
{str8_lit_comp("focus_panel_left"), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), str8_lit_comp(""), RD_IconKind_LeftArrow},
{str8_lit_comp("focus_panel_up"), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), str8_lit_comp(""), RD_IconKind_UpArrow},
{str8_lit_comp("focus_panel_down"), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), str8_lit_comp(""), RD_IconKind_DownArrow},
{str8_lit_comp("zoom_panel"), str8_lit_comp(""), str8_lit_comp("Zoom Panel"), str8_lit_comp(""), RD_IconKind_Window},
{str8_lit_comp("unzoom_panel"), str8_lit_comp(""), str8_lit_comp("Unzoom Panel"), str8_lit_comp(""), RD_IconKind_Window},
{str8_lit_comp("toggle_zoom_panel"), str8_lit_comp(""), str8_lit_comp("Toggle Panel Zoom"), str8_lit_comp(""), RD_IconKind_Window},
{str8_lit_comp("undo"), str8_lit_comp(""), str8_lit_comp("Undo"), str8_lit_comp(""), RD_IconKind_Undo},
{str8_lit_comp("redo"), str8_lit_comp(""), str8_lit_comp("Redo"), str8_lit_comp(""), RD_IconKind_Redo},
{str8_lit_comp("go_back"), str8_lit_comp(""), str8_lit_comp("Go Back"), str8_lit_comp(""), RD_IconKind_LeftArrow},
@@ -471,7 +475,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[39] =
{str8_lit_comp("color"), 1, str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")},
{str8_lit_comp("geo3d"), 1, str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")},
{str8_lit_comp("getting_started"), 0, str8_lit_comp("@inherit(tab) x:\n{\n}\n")},
{str8_lit_comp("target"), 0, str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': @folder path,\n 'entry_point': expr_string,\n @default(\"output\") 'output_label': code_string,\n 'stdout_path': @can_not_exist @no_relativize path,\n 'stderr_path': @can_not_exist @no_relativize path,\n 'stdin_path': @can_not_exist @no_relativize path,\n 'environment': set,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")},
{str8_lit_comp("target"), 0, str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': @folder path,\n 'entry_point': expr_string,\n @default(\"output\") 'output_label': code_string,\n 'stdout_path': @can_not_exist @no_relativize path,\n 'stderr_path': @can_not_exist @no_relativize path,\n 'stdin_path': @can_not_exist @no_relativize path,\n 'environment': set,\n 'debug_subprocesses': bool,\n @display_name('Remote')\n 'remote': bool,\n @expand_if(\"$.remote\") @display_name('Deploy')\n 'deploy': bool,\n @expand_if(\"$.remote\") @display_name('Address')\n 'address': string,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")},
{str8_lit_comp("breakpoint"), 0, str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @display_name(\"Break Selected Thread Only\") 'break_selected_thread_only': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")},
{str8_lit_comp("watch_pin"), 0, str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n}\n")},
{str8_lit_comp("debug_info"), 0, str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(load_debug_info)\nx:\n{\n 'path': @no_relativize path,\n @no_revert @no_expand @default(1) 'enabled': bool,\n @query 'guid': string,\n}\n")},
@@ -604,7 +608,7 @@ Rng1U64 rd_reg_slot_range_table[56] =
{OffsetOf(RD_Regs, wm_event), OffsetOf(RD_Regs, wm_event) + sizeof(WM_Event *)},
};
RD_CmdKindInfo rd_cmd_kind_info_table[261] =
RD_CmdKindInfo rd_cmd_kind_info_table[265] =
{
{0},
{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets")}},
@@ -682,11 +686,15 @@ RD_CmdKindInfo rd_cmd_kind_info_table[261] =
{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("parent_panel"), str8_lit_comp("Focuses the parent of the currently selected panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("zoom_panel"), str8_lit_comp("Zooms a panel, making it occupy the entire window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("unzoom_panel"), str8_lit_comp("Unzooms the currently zoomed panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("toggle_zoom_panel"), str8_lit_comp("Zooms a panel, making it occupy the entire window, or unzooms it, if already zoomed."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}},
+5 -1
View File
@@ -145,11 +145,15 @@ RD_CmdKind_SplitPanel,
RD_CmdKind_RotatePanelColumns,
RD_CmdKind_NextPanel,
RD_CmdKind_PrevPanel,
RD_CmdKind_ParentPanel,
RD_CmdKind_FocusPanel,
RD_CmdKind_FocusPanelRight,
RD_CmdKind_FocusPanelLeft,
RD_CmdKind_FocusPanelUp,
RD_CmdKind_FocusPanelDown,
RD_CmdKind_ZoomPanel,
RD_CmdKind_UnzoomPanel,
RD_CmdKind_ToggleZoomPanel,
RD_CmdKind_Undo,
RD_CmdKind_Redo,
RD_CmdKind_GoBack,
@@ -634,7 +638,7 @@ Z(getting_started)\
C_LINKAGE_BEGIN
extern String8 rd_tab_fast_path_view_name_table[25];
extern String8 rd_tab_fast_path_query_name_table[25];
extern RD_VocabInfo rd_vocab_info_table[375];
extern RD_VocabInfo rd_vocab_info_table[379];
extern RD_NameSchemaInfo rd_name_schema_info_table[39];
extern String8 rd_reg_slot_code_name_table[56];
extern Rng1U64 rd_reg_slot_range_table[56];
+12
View File
@@ -803,6 +803,12 @@ RD_VocabTable:
'stdin_path': @can_not_exist @no_relativize path,
'environment': set,
'debug_subprocesses': bool,
@display_name('Remote')
'remote': bool,
@expand_if("$.remote") @display_name('Deploy')
'deploy': bool,
@expand_if("$.remote") @display_name('Address')
'address': string,
@no_revert @no_expand @default(0) 'enabled': bool,
}
```,
@@ -1095,12 +1101,18 @@ RD_CmdTable: // | | | |
//- rjf: focused panel changing
{NextPanel 0 1 1 "" Null 0 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" }
{PrevPanel 0 1 1 "" Null 0 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" }
{ParentPanel 0 1 1 "" Null 0 0 0 0 0 0 0 Null "parent_panel" "Focus Parent Panel" "Focuses the parent of the currently selected panel." "" "" }
{FocusPanel 0 0 0 "" Null 0 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" }
{FocusPanelRight 0 1 1 "" Null 0 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" }
{FocusPanelLeft 0 1 1 "" Null 0 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" }
{FocusPanelUp 0 1 1 "" Null 0 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" }
{FocusPanelDown 0 1 1 "" Null 0 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" }
//- rjf: panel zooming
{ZoomPanel 0 1 1 "" Null 0 0 0 0 0 0 0 Window "zoom_panel" "Zoom Panel" "Zooms a panel, making it occupy the entire window." "" "" }
{UnzoomPanel 0 1 1 "" Null 0 0 0 0 0 0 0 Window "unzoom_panel" "Unzoom Panel" "Unzooms the currently zoomed panel." "" "" }
{ToggleZoomPanel 0 1 1 "" Null 0 0 0 0 0 0 0 Window "toggle_zoom_panel" "Toggle Panel Zoom" "Zooms a panel, making it occupy the entire window, or unzooms it, if already zoomed." "" "" }
//- rjf: undo/redo
{Undo 0 0 0 "" Null 0 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" }
{Redo 0 0 0 "" Null 0 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" }
+432 -244
View File
@@ -5724,7 +5724,7 @@ rd_window_frame(void)
//
rd_regs()->panel = panel_tree.focused->cfg->id;
rd_regs()->tab = panel_tree.focused->selected_tab->id;
rd_regs()->view = panel_tree.focused->selected_tab->id;
rd_regs()->view = panel_tree.focused->selected_tab->id;
//////////////////////////////
//- rjf: @window_frame_part compute window's theme
@@ -6054,8 +6054,8 @@ rd_window_frame(void)
ui_push_pref_height(ui_px(floor_f32(ui_top_font_size()*3.f), 1.f));
ui_push_blur_size(10.f);
FNT_RasterFlags text_raster_flags = 0;
if(rd_setting_b32_from_name(str8_lit("smooth_ui_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;}
if(rd_setting_b32_from_name(str8_lit("hint_ui_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;}
if(rd_setting_b32_from_name(s("smooth_ui_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;}
if(rd_setting_b32_from_name(s("hint_ui_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;}
ui_push_text_raster_flags(text_raster_flags);
}
@@ -7538,6 +7538,10 @@ rd_window_frame(void)
rd_cmd_kind_info_table[RD_CmdKind_NextPanel].string,
rd_cmd_kind_info_table[RD_CmdKind_PrevPanel].string,
{0},//-
rd_cmd_kind_info_table[RD_CmdKind_ZoomPanel].string,
rd_cmd_kind_info_table[RD_CmdKind_UnzoomPanel].string,
rd_cmd_kind_info_table[RD_CmdKind_ToggleZoomPanel].string,
{0},//-
rd_cmd_kind_info_table[RD_CmdKind_TabBarTop].string,
rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string,
{0},//-
@@ -7554,6 +7558,10 @@ rd_window_frame(void)
'n',
'p',
0,//-
'z',
'm',
't',
0,//--
0,
0,
0,//-
@@ -8236,53 +8244,150 @@ rd_window_frame(void)
//
B32 is_changing_panel_boundaries = 0;
ProfScope("non-leaf panel UI")
for(CFG_PanelNode *panel = panel_tree.root;
panel != &cfg_nil_panel_node;
panel = cfg_panel_node_rec__depth_first_pre(panel_tree.root, panel).next)
{
//////////////////////////
//- rjf: continue on leaf panels
//
if(panel->first == &cfg_nil_panel_node)
CFG_PanelNode *panel_tree_root = (panel_tree.zoom_root != &cfg_nil_panel_node) ? panel_tree.zoom_root : panel_tree.root;
for(CFG_PanelNode *panel = panel_tree_root;
panel != &cfg_nil_panel_node;
panel = cfg_panel_node_rec__depth_first_pre(panel_tree_root, panel).next)
{
continue;
}
//////////////////////////
//- rjf: grab info
//
Axis2 split_axis = panel->split_axis;
Rng2F32 panel_rect = cfg_target_rect_from_panel_node(content_rect, panel_tree.root, panel);
//////////////////////////
//- rjf: boundary tab-drag/drop sites
//
{
CFG_Node *drag_view = cfg_node_from_id(rd_state->drag_drop_regs->view);
if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && drag_view != &cfg_nil_node)
//////////////////////////
//- rjf: continue on leaf panels
//
if(panel->first == &cfg_nil_panel_node)
{
//- rjf: params
F32 drop_site_major_dim_px = ceil_f32(ui_top_font_size()*7.f);
F32 drop_site_minor_dim_px = ceil_f32(ui_top_font_size()*5.f);
F32 corner_radius = ui_top_font_size()*0.5f;
F32 padding = ceil_f32(ui_top_font_size()*0.5f);
continue;
}
//- rjf: special case - build Y boundary drop sites on root panel
//
// (this does not naturally follow from the below algorithm, since the
// root level panel only splits on X)
if(panel == panel_tree.root) UI_CornerRadius(corner_radius)
//////////////////////////
//- rjf: grab info
//
Axis2 split_axis = panel->split_axis;
Rng2F32 panel_rect = cfg_target_rect_from_panel_node(content_rect, panel_tree_root, panel);
if(panel == panel_tree.zoom_root)
{
panel_rect = content_rect;
}
//////////////////////////
//- rjf: boundary tab-drag/drop sites
//
{
CFG_Node *drag_view = cfg_node_from_id(rd_state->drag_drop_regs->view);
if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && drag_view != &cfg_nil_node)
{
Vec2F32 panel_rect_center = center_2f32(panel_rect);
Axis2 axis = axis2_flip(panel_tree.root->split_axis);
for EachEnumVal(Side, side)
//- rjf: params
F32 drop_site_major_dim_px = ceil_f32(ui_top_font_size()*7.f);
F32 drop_site_minor_dim_px = ceil_f32(ui_top_font_size()*5.f);
F32 corner_radius = ui_top_font_size()*0.5f;
F32 padding = ceil_f32(ui_top_font_size()*0.5f);
//- rjf: special case - build Y boundary drop sites on root panel
//
// (this does not naturally follow from the below algorithm, since the
// root level panel only splits on X)
if(panel == panel_tree_root) UI_CornerRadius(corner_radius)
{
UI_Key key = ui_key_from_stringf(ui_key_zero(), "root_extra_split_%i", side);
Rng2F32 site_rect = panel_rect;
site_rect.p0.v[axis2_flip(axis)] = panel_rect_center.v[axis2_flip(axis)] - drop_site_major_dim_px/2;
site_rect.p1.v[axis2_flip(axis)] = panel_rect_center.v[axis2_flip(axis)] + drop_site_major_dim_px/2;
site_rect.p0.v[axis] = panel_rect.v[side].v[axis] - drop_site_minor_dim_px/2;
site_rect.p1.v[axis] = panel_rect.v[side].v[axis] + drop_site_minor_dim_px/2;
Vec2F32 panel_rect_center = center_2f32(panel_rect);
Axis2 axis = axis2_flip(panel_tree_root->split_axis);
for EachEnumVal(Side, side)
{
UI_Key key = ui_key_from_stringf(ui_key_zero(), "root_extra_split_%i", side);
Rng2F32 site_rect = panel_rect;
site_rect.p0.v[axis2_flip(axis)] = panel_rect_center.v[axis2_flip(axis)] - drop_site_major_dim_px/2;
site_rect.p1.v[axis2_flip(axis)] = panel_rect_center.v[axis2_flip(axis)] + drop_site_major_dim_px/2;
site_rect.p0.v[axis] = panel_rect.v[side].v[axis] - drop_site_minor_dim_px/2;
site_rect.p1.v[axis] = panel_rect.v[side].v[axis] + drop_site_minor_dim_px/2;
// rjf: build
UI_Box *site_box = &ui_nil_box;
{
F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f, .rate = rd_state->menu_animation_rate);
UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t)
{
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key);
ui_signal_from_box(site_box);
}
UI_Box *site_box_viz = &ui_nil_box;
UI_Parent(site_box) UI_WidthFill UI_HeightFill
UI_Padding(ui_px(padding, 1.f))
UI_Column
UI_Padding(ui_px(padding, 1.f))
UI_GroupKey(key)
{
ui_set_next_child_layout_axis(axis2_flip(axis));
site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_DrawDropShadow|
UI_BoxFlag_DrawBackgroundBlur|
UI_BoxFlag_DrawHotEffects, ui_key_zero());
}
UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f))
{
ui_set_next_child_layout_axis(axis);
UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f))
{
ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero());
ui_spacer(ui_px(padding, 1.f));
ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero());
}
}
}
// rjf: viz
if(ui_key_match(site_box->key, ui_drop_hot_key()))
{
Rng2F32 future_split_rect_target = site_rect;
future_split_rect_target.p0.v[axis] -= drop_site_major_dim_px;
future_split_rect_target.p1.v[axis] += drop_site_major_dim_px;
future_split_rect_target.p0.v[axis2_flip(axis)] = panel_rect.p0.v[axis2_flip(axis)];
future_split_rect_target.p1.v[axis2_flip(axis)] = panel_rect.p1.v[axis2_flip(axis)];
future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f);
Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target);
Rng2F32 future_split_rect =
{
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate),
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate),
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate),
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate),
};
UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f)
{
ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero());
}
}
// rjf: drop
if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop())
{
Dir2 dir = (axis == Axis2_Y ? (side == Side_Min ? Dir2_Up : Dir2_Down) :
axis == Axis2_X ? (side == Side_Min ? Dir2_Left : Dir2_Right) :
Dir2_Invalid);
if(dir != Dir2_Invalid)
{
CFG_PanelNode *split_panel = panel;
rd_cmd(RD_CmdKind_SplitPanel,
.dst_panel = split_panel->cfg->id,
.panel = rd_state->drag_drop_regs->panel,
.view = rd_state->drag_drop_regs->view,
.dir2 = dir);
}
}
}
}
//- rjf: iterate all children, build boundary drop sites
Axis2 split_axis = panel->split_axis;
UI_CornerRadius(corner_radius) for(CFG_PanelNode *child = panel->first;; child = child->next)
{
// rjf: form rect
Rng2F32 child_rect = cfg_target_rect_from_panel_node_child(panel_rect, panel, child);
Vec2F32 child_rect_center = center_2f32(child_rect);
UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel->cfg, child->cfg);
Rng2F32 site_rect = r2f32(child_rect_center, child_rect_center);
site_rect.p0.v[split_axis] = child_rect.p0.v[split_axis] - drop_site_minor_dim_px/2;
site_rect.p1.v[split_axis] = child_rect.p0.v[split_axis] + drop_site_minor_dim_px/2;
site_rect.p0.v[axis2_flip(split_axis)] -= drop_site_major_dim_px/2;
site_rect.p1.v[axis2_flip(split_axis)] += drop_site_major_dim_px/2;
// rjf: build
UI_Box *site_box = &ui_nil_box;
@@ -8300,7 +8405,7 @@ rd_window_frame(void)
UI_Padding(ui_px(padding, 1.f))
UI_GroupKey(key)
{
ui_set_next_child_layout_axis(axis2_flip(axis));
ui_set_next_child_layout_axis(axis2_flip(split_axis));
site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_DrawDropShadow|
@@ -8309,7 +8414,7 @@ rd_window_frame(void)
}
UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f))
{
ui_set_next_child_layout_axis(axis);
ui_set_next_child_layout_axis(split_axis);
UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f))
{
ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero());
@@ -8323,10 +8428,10 @@ rd_window_frame(void)
if(ui_key_match(site_box->key, ui_drop_hot_key()))
{
Rng2F32 future_split_rect_target = site_rect;
future_split_rect_target.p0.v[axis] -= drop_site_major_dim_px;
future_split_rect_target.p1.v[axis] += drop_site_major_dim_px;
future_split_rect_target.p0.v[axis2_flip(axis)] = panel_rect.p0.v[axis2_flip(axis)];
future_split_rect_target.p1.v[axis2_flip(axis)] = panel_rect.p1.v[axis2_flip(axis)];
future_split_rect_target.p0.v[split_axis] -= drop_site_major_dim_px;
future_split_rect_target.p1.v[split_axis] += drop_site_major_dim_px;
future_split_rect_target.p0.v[axis2_flip(split_axis)] = child_rect.p0.v[axis2_flip(split_axis)];
future_split_rect_target.p1.v[axis2_flip(split_axis)] = child_rect.p1.v[axis2_flip(split_axis)];
future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f);
Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target);
Rng2F32 future_split_rect =
@@ -8345,187 +8450,97 @@ rd_window_frame(void)
// rjf: drop
if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop())
{
Dir2 dir = (axis == Axis2_Y ? (side == Side_Min ? Dir2_Up : Dir2_Down) :
axis == Axis2_X ? (side == Side_Min ? Dir2_Left : Dir2_Right) :
Dir2_Invalid);
if(dir != Dir2_Invalid)
Dir2 dir = (panel->split_axis == Axis2_X ? Dir2_Left : Dir2_Up);
CFG_PanelNode *split_panel = child;
if(split_panel == &cfg_nil_panel_node)
{
CFG_PanelNode *split_panel = panel;
rd_cmd(RD_CmdKind_SplitPanel,
.dst_panel = split_panel->cfg->id,
.panel = rd_state->drag_drop_regs->panel,
.view = rd_state->drag_drop_regs->view,
.dir2 = dir);
split_panel = panel->last;
dir = (panel->split_axis == Axis2_X ? Dir2_Right : Dir2_Down);
}
rd_cmd(RD_CmdKind_SplitPanel,
.dst_panel = split_panel->cfg->id,
.panel = rd_state->drag_drop_regs->panel,
.view = rd_state->drag_drop_regs->view,
.dir2 = dir);
}
}
}
//- rjf: iterate all children, build boundary drop sites
Axis2 split_axis = panel->split_axis;
UI_CornerRadius(corner_radius) for(CFG_PanelNode *child = panel->first;; child = child->next)
{
// rjf: form rect
Rng2F32 child_rect = cfg_target_rect_from_panel_node_child(panel_rect, panel, child);
Vec2F32 child_rect_center = center_2f32(child_rect);
UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel->cfg, child->cfg);
Rng2F32 site_rect = r2f32(child_rect_center, child_rect_center);
site_rect.p0.v[split_axis] = child_rect.p0.v[split_axis] - drop_site_minor_dim_px/2;
site_rect.p1.v[split_axis] = child_rect.p0.v[split_axis] + drop_site_minor_dim_px/2;
site_rect.p0.v[axis2_flip(split_axis)] -= drop_site_major_dim_px/2;
site_rect.p1.v[axis2_flip(split_axis)] += drop_site_major_dim_px/2;
// rjf: build
UI_Box *site_box = &ui_nil_box;
{
F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f, .rate = rd_state->menu_animation_rate);
UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t)
// rjf: exit on opl child
if(child == &cfg_nil_panel_node)
{
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key);
ui_signal_from_box(site_box);
break;
}
UI_Box *site_box_viz = &ui_nil_box;
UI_Parent(site_box) UI_WidthFill UI_HeightFill
UI_Padding(ui_px(padding, 1.f))
UI_Column
UI_Padding(ui_px(padding, 1.f))
UI_GroupKey(key)
{
ui_set_next_child_layout_axis(axis2_flip(split_axis));
site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_DrawDropShadow|
UI_BoxFlag_DrawBackgroundBlur|
UI_BoxFlag_DrawHotEffects, ui_key_zero());
}
UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f))
{
ui_set_next_child_layout_axis(split_axis);
UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f))
{
ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero());
ui_spacer(ui_px(padding, 1.f));
ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero());
}
}
}
// rjf: viz
if(ui_key_match(site_box->key, ui_drop_hot_key()))
{
Rng2F32 future_split_rect_target = site_rect;
future_split_rect_target.p0.v[split_axis] -= drop_site_major_dim_px;
future_split_rect_target.p1.v[split_axis] += drop_site_major_dim_px;
future_split_rect_target.p0.v[axis2_flip(split_axis)] = child_rect.p0.v[axis2_flip(split_axis)];
future_split_rect_target.p1.v[axis2_flip(split_axis)] = child_rect.p1.v[axis2_flip(split_axis)];
future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f);
Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target);
Rng2F32 future_split_rect =
{
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate),
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate),
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate),
ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate),
};
UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f)
{
ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero());
}
}
// rjf: drop
if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop())
{
Dir2 dir = (panel->split_axis == Axis2_X ? Dir2_Left : Dir2_Up);
CFG_PanelNode *split_panel = child;
if(split_panel == &cfg_nil_panel_node)
{
split_panel = panel->last;
dir = (panel->split_axis == Axis2_X ? Dir2_Right : Dir2_Down);
}
rd_cmd(RD_CmdKind_SplitPanel,
.dst_panel = split_panel->cfg->id,
.panel = rd_state->drag_drop_regs->panel,
.view = rd_state->drag_drop_regs->view,
.dir2 = dir);
}
// rjf: exit on opl child
if(child == &cfg_nil_panel_node)
{
break;
}
}
}
}
//////////////////////////
//- rjf: do UI for drag boundaries between all children
//
for(CFG_PanelNode *child = panel->first;
child != &cfg_nil_panel_node && child->next != &cfg_nil_panel_node;
child = child->next)
{
CFG_PanelNode *min_child = child;
CFG_PanelNode *max_child = min_child->next;
Rng2F32 min_child_rect = cfg_target_rect_from_panel_node_child(panel_rect, panel, min_child);
Rng2F32 max_child_rect = cfg_target_rect_from_panel_node_child(panel_rect, panel, max_child);
Rng2F32 boundary_rect = {0};
//////////////////////////
//- rjf: do UI for drag boundaries between all children
//
for(CFG_PanelNode *child = panel->first;
child != &cfg_nil_panel_node && child->next != &cfg_nil_panel_node;
child = child->next)
{
boundary_rect.p0.v[split_axis] = min_child_rect.p1.v[split_axis] - ui_top_font_size()/3;
boundary_rect.p1.v[split_axis] = max_child_rect.p0.v[split_axis] + ui_top_font_size()/3;
boundary_rect.p0.v[axis2_flip(split_axis)] = panel_rect.p0.v[axis2_flip(split_axis)];
boundary_rect.p1.v[axis2_flip(split_axis)] = panel_rect.p1.v[axis2_flip(split_axis)];
}
CFG_PanelNode *min_child = child;
CFG_PanelNode *max_child = min_child->next;
Rng2F32 min_child_rect = cfg_target_rect_from_panel_node_child(panel_rect, panel, min_child);
Rng2F32 max_child_rect = cfg_target_rect_from_panel_node_child(panel_rect, panel, max_child);
Rng2F32 boundary_rect = {0};
{
boundary_rect.p0.v[split_axis] = min_child_rect.p1.v[split_axis] - ui_top_font_size()/3;
boundary_rect.p1.v[split_axis] = max_child_rect.p0.v[split_axis] + ui_top_font_size()/3;
boundary_rect.p0.v[axis2_flip(split_axis)] = panel_rect.p0.v[axis2_flip(split_axis)];
boundary_rect.p1.v[axis2_flip(split_axis)] = panel_rect.p1.v[axis2_flip(split_axis)];
}
UI_Rect(boundary_rect)
{
ui_set_next_hover_cursor(split_axis == Axis2_X ? WM_Cursor_LeftRight : WM_Cursor_UpDown);
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%p_%p", min_child->cfg, max_child->cfg);
UI_Signal sig = ui_signal_from_box(box);
if(ui_double_clicked(sig))
UI_Rect(boundary_rect)
{
ui_kill_action();
F32 sum_pct = min_child->pct_of_parent + max_child->pct_of_parent;
min_child->pct_of_parent = 0.5f * sum_pct;
max_child->pct_of_parent = 0.5f * sum_pct;
cfg_node_equip_stringf(rd_state->cfg, min_child->cfg, "%f", min_child->pct_of_parent);
cfg_node_equip_stringf(rd_state->cfg, max_child->cfg, "%f", max_child->pct_of_parent);
}
else if(ui_pressed(sig))
{
Vec2F32 v = {min_child->pct_of_parent, max_child->pct_of_parent};
ui_store_drag_struct(&v);
}
else if(ui_dragging(sig))
{
Vec2F32 v = *ui_get_drag_struct(Vec2F32);
Vec2F32 mouse_delta = ui_drag_delta();
F32 total_size = dim_2f32(panel_rect).v[split_axis];
F32 min_pct__before = v.v[0];
F32 min_pixels__before = min_pct__before * total_size;
F32 min_pixels__after = min_pixels__before + mouse_delta.v[split_axis];
if(min_pixels__after < 50.f)
ui_set_next_hover_cursor(split_axis == Axis2_X ? WM_Cursor_LeftRight : WM_Cursor_UpDown);
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%p_%p", min_child->cfg, max_child->cfg);
UI_Signal sig = ui_signal_from_box(box);
if(ui_double_clicked(sig))
{
min_pixels__after = 50.f;
ui_kill_action();
F32 sum_pct = min_child->pct_of_parent + max_child->pct_of_parent;
min_child->pct_of_parent = 0.5f * sum_pct;
max_child->pct_of_parent = 0.5f * sum_pct;
cfg_node_equip_stringf(rd_state->cfg, min_child->cfg, "%f", min_child->pct_of_parent);
cfg_node_equip_stringf(rd_state->cfg, max_child->cfg, "%f", max_child->pct_of_parent);
}
F32 min_pct__after = min_pixels__after / total_size;
F32 pct_delta = min_pct__after - min_pct__before;
F32 max_pct__before = v.v[1];
F32 max_pct__after = max_pct__before - pct_delta;
F32 max_pixels__after = max_pct__after * total_size;
if(max_pixels__after < 50.f)
else if(ui_pressed(sig))
{
max_pixels__after = 50.f;
max_pct__after = max_pixels__after / total_size;
pct_delta = -(max_pct__after - max_pct__before);
min_pct__after = min_pct__before + pct_delta;
Vec2F32 v = {min_child->pct_of_parent, max_child->pct_of_parent};
ui_store_drag_struct(&v);
}
else if(ui_dragging(sig))
{
Vec2F32 v = *ui_get_drag_struct(Vec2F32);
Vec2F32 mouse_delta = ui_drag_delta();
F32 total_size = dim_2f32(panel_rect).v[split_axis];
F32 min_pct__before = v.v[0];
F32 min_pixels__before = min_pct__before * total_size;
F32 min_pixels__after = min_pixels__before + mouse_delta.v[split_axis];
if(min_pixels__after < 50.f)
{
min_pixels__after = 50.f;
}
F32 min_pct__after = min_pixels__after / total_size;
F32 pct_delta = min_pct__after - min_pct__before;
F32 max_pct__before = v.v[1];
F32 max_pct__after = max_pct__before - pct_delta;
F32 max_pixels__after = max_pct__after * total_size;
if(max_pixels__after < 50.f)
{
max_pixels__after = 50.f;
max_pct__after = max_pixels__after / total_size;
pct_delta = -(max_pct__after - max_pct__before);
min_pct__after = min_pct__before + pct_delta;
}
min_child->pct_of_parent = min_pct__after;
max_child->pct_of_parent = max_pct__after;
cfg_node_equip_stringf(rd_state->cfg, min_child->cfg, "%f", min_pct__after);
cfg_node_equip_stringf(rd_state->cfg, max_child->cfg, "%f", max_pct__after);
is_changing_panel_boundaries = 1;
}
min_child->pct_of_parent = min_pct__after;
max_child->pct_of_parent = max_pct__after;
cfg_node_equip_stringf(rd_state->cfg, min_child->cfg, "%f", min_pct__after);
cfg_node_equip_stringf(rd_state->cfg, max_child->cfg, "%f", max_pct__after);
is_changing_panel_boundaries = 1;
}
}
}
@@ -8544,7 +8559,20 @@ rd_window_frame(void)
panel != &cfg_nil_panel_node;
panel = cfg_panel_node_rec__depth_first_pre(panel_tree.root, panel).next)
{
Rng2F32 target_rect_px = cfg_target_rect_from_panel_node(content_rect, panel_tree.root, panel);
B32 is_in_zoom = 0;
for(CFG_PanelNode *p = panel; p != &cfg_nil_panel_node; p = p->parent)
{
if(p == panel_tree.zoom_root)
{
is_in_zoom = 1;
break;
}
}
Rng2F32 target_rect_px = cfg_target_rect_from_panel_node(content_rect, is_in_zoom ? panel_tree.zoom_root : panel_tree.root, panel);
if(panel == panel_tree.zoom_root)
{
target_rect_px = content_rect;
}
Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0/content_rect_dim.x,
target_rect_px.y0/content_rect_dim.y,
target_rect_px.x1/content_rect_dim.x,
@@ -8565,12 +8593,23 @@ rd_window_frame(void)
if(content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0)
{
B32 any_disasm_open = 0;
ProfScope("leaf panel UI")
for(CFG_PanelNode *panel = panel_tree.root;
panel != &cfg_nil_panel_node;
panel = cfg_panel_node_rec__depth_first_pre(panel_tree.root, panel).next)
if(ws->panel_hoist_cfg_id != panel_tree.zoom_root->cfg->id && panel_tree.zoom_root->cfg->id != 0)
{
if(panel->first != &cfg_nil_panel_node) {continue;}
ws->panel_hoist_cfg_id = panel_tree.zoom_root->cfg->id;
}
CFG_PanelNode *front_panel = cfg_panel_node_from_tree_cfg(panel_tree.root, cfg_node_from_id(ws->panel_hoist_cfg_id));
CFG_PanelNode *panel_trees[] = {front_panel, panel_tree.root};
F32 panel_zoom_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_zoom_t"), (F32)(panel_tree.zoom_root != &cfg_nil_panel_node), .initial = (F32)(panel_tree.zoom_root != &cfg_nil_panel_node));
ProfScope("leaf panel UI")
for EachElement(panel_tree_idx, panel_trees)
for(CFG_PanelNode *panel = panel_trees[panel_tree_idx];
panel != &cfg_nil_panel_node;
panel = cfg_panel_node_rec__depth_first_pre(panel_trees[panel_tree_idx], panel).next)
{
if(panel_trees[panel_tree_idx] != front_panel && panel == front_panel)
{
continue;
}
B32 panel_is_focused = (window_is_focused &&
!rd_state->popup_active &&
!ws->menu_bar_focused &&
@@ -8586,12 +8625,26 @@ rd_window_frame(void)
}
ProfScope("leaf panel UI work - %.*s: %.*s", str8_varg(selected_tab->string), str8_varg(rd_expr_from_cfg(selected_tab)))
UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off)
UI_Transparency(panel_trees[panel_tree_idx] != front_panel ? panel_zoom_t : 0)
{
//////////////////////////
//- rjf: calculate UI rectangles
//
Vec2F32 content_rect_dim = dim_2f32(content_rect);
Rng2F32 target_rect_px = cfg_target_rect_from_panel_node(content_rect, panel_tree.root, panel);
B32 is_in_zoom = 0;
for(CFG_PanelNode *p = panel; p != &cfg_nil_panel_node; p = p->parent)
{
if(p == panel_tree.zoom_root)
{
is_in_zoom = 1;
break;
}
}
Rng2F32 target_rect_px = cfg_target_rect_from_panel_node(content_rect, is_in_zoom ? panel_tree.zoom_root : panel_tree.root, panel);
if(panel == panel_tree.zoom_root)
{
target_rect_px = content_rect;
}
Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0 / content_rect_dim.x,
target_rect_px.y0 / content_rect_dim.y,
target_rect_px.x1 / content_rect_dim.x,
@@ -8623,9 +8676,17 @@ rd_window_frame(void)
content_rect = intersect_2f32(content_rect, panel_rect);
//////////////////////////
//- rjf: decide to skip this panel (e.g. if it is too small
//- rjf: for non-leaf panels with focus (subtree selection) -> draw border for all children
//
B32 build_panel = (content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0);
if(panel->first != &cfg_nil_panel_node && panel == panel_tree.focused) UI_Rect(pad_2f32(panel_rect, ui_top_font_size()*0.2f)) UI_Focus(UI_FocusKind_On)
{
ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_DisableFocusOverlay, "###");
}
//////////////////////////
//- rjf: decide to skip this panel (e.g. if it non-leaf, or is too small)
//
B32 build_panel = ((panel->first == &cfg_nil_panel_node) && content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0 && ui_top_transparency() < 0.99f);
//////////////////////////
//- rjf: build combined split+movetab drag/drop sites
@@ -8822,6 +8883,16 @@ rd_window_frame(void)
ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero());
}
//////////////////////////
//- rjf: determine how much this panel is occluding others
//
B32 is_occluding = 0;
if(panel_trees[panel_tree_idx] == front_panel)
{
is_occluding = (abs_f32(panel_rect.x0 - target_rect_px.x0) > 2 ||
abs_f32(panel_rect.y0 - target_rect_px.y0) > 2);
}
//////////////////////////
//- rjf: build panel container box
//
@@ -8833,6 +8904,7 @@ rd_window_frame(void)
UI_BoxFlag_Clip|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_DisableFocusOverlay|
(is_occluding*UI_BoxFlag_DrawBackground)|
((panel_tree.focused != panel)*UI_BoxFlag_DisableFocusBorder),
panel_key);
}
@@ -8971,6 +9043,70 @@ rd_window_frame(void)
}
}
//////////////////////////
//- rjf: build zoom button
//
if(panel_is_focused)
{
UI_TextAlignment(UI_TextAlign_Center)
UI_TagF(".")
{
ui_set_next_child_layout_axis(Axis2_Y);
UI_Box *container = &ui_nil_box;
UI_Rect(r2f32p(tab_bar_rect.x1 - tab_bar_vheight, tab_bar_rect.y0, tab_bar_rect.x1, tab_bar_rect.y1))
{
container = ui_build_box_from_stringf(0, "###zoom_panel");
}
UI_Parent(container)
{
if(panel->tab_side == Side_Max)
{
ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f));
}
else
{
ui_spacer(ui_px(1.f, 1.f));
}
{
UI_Box *zoom_box = &ui_nil_box;
RD_Font(RD_FontSlot_Icons)
UI_CornerRadius((tab_bar_vheight - tab_bar_vheight/4.f) / 3.f)
UI_VisualMargin(tab_bar_vheight/5.f)
UI_TagF("implicit")
UI_TagF("weak")
UI_FontSize(ui_top_font_size()*0.65f)
{
zoom_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_DrawBackground|
UI_BoxFlag_DrawHotEffects|
UI_BoxFlag_DrawActiveEffects|
UI_BoxFlag_Clickable|
UI_BoxFlag_DisableTextTrunc,
"%S##zoom_panel_button_%p",
rd_icon_kind_text_table[panel_tree.zoom_root == panel ? RD_IconKind_WindowRestore : RD_IconKind_Window],
panel->cfg);
}
UI_Signal sig = ui_signal_from_box(zoom_box);
if(ui_pressed(sig))
{
rd_cmd(RD_CmdKind_ToggleZoomPanel, .panel = panel->cfg->id);
}
if(ui_hovering(sig)) UI_Tooltip
{
ui_state->tooltip_anchor_key = zoom_box->key;
ui_set_next_pref_width(ui_children_sum(1));
UI_Row
{
ui_labelf("Toggle Zoom Panel");
rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_ToggleZoomPanel].string, s(""), 1, RD_CmdBindingButtonFlag_NoEdit);
}
}
}
}
}
}
//////////////////////////
//- rjf: compute tab build tasks
//
@@ -8987,7 +9123,7 @@ rd_window_frame(void)
U64 tab_task_count = 0;
F32 tab_close_width_px = ui_top_font_size()*2.5f;
F32 max_tab_width_px = ui_top_font_size()*20.f;
if(build_panel) UI_TagF("tab")
UI_TagF("tab")
{
B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries);
for(CFG_NodePtrNode *n = panel->tabs.first; n != 0; n = n->next)
@@ -8999,19 +9135,24 @@ rd_window_frame(void)
}
UI_TagF(tab != panel->selected_tab ? "inactive" : "")
{
TabTask *t = push_array(scratch.arena, TabTask, 1);
t->tab = tab;
t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, 0);
F32 tab_width_target = dr_dim_from_fstrs(ui_top_tab_size(), &t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f;
DR_FStrList tab_title_fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, 0);
F32 tab_width_target = dr_dim_from_fstrs(ui_top_tab_size(), &tab_title_fstrs).x + tab_close_width_px + ui_top_font_size()*1.f;
B32 tab_is_selected = (tab == panel->selected_tab);
if(tab_is_selected && panel_tree.focused == panel)
{
tab_width_target += tab_close_width_px;
}
tab_width_target = Min(max_tab_width_px, tab_width_target);
t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0, .rate = rd_state->menu_animation_rate));
SLLQueuePush(first_tab_task, last_tab_task, t);
tab_task_count += 1;
F32 tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0, .rate = rd_state->menu_animation_rate));
if(build_panel)
{
TabTask *t = push_array(scratch.arena, TabTask, 1);
t->tab = tab;
t->fstrs = tab_title_fstrs;
t->tab_width = tab_width;
SLLQueuePush(first_tab_task, last_tab_task, t);
tab_task_count += 1;
}
}
}
}
@@ -9361,6 +9502,7 @@ rd_window_frame(void)
//////////////////////////
//- rjf: accept file drops
//
if(build_panel)
{
for(UI_Event *evt = 0; ui_next_event(&evt);)
{
@@ -11459,9 +11601,9 @@ rd_init(CmdLine *cmdln)
for(U64 idx = 1; idx < cmdln->argc; idx += 1)
{
String8 arg = str8_cstring(cmdln->argv[idx]);
B32 is_flag = (str8_match(str8_prefix(arg, 1), str8_lit("-"), 0) ||
str8_match(str8_prefix(arg, 1), str8_lit("--"), 0) ||
str8_match(str8_prefix(arg, 1), str8_lit("/"), 0));
B32 is_flag = (str8_match(str8_prefix(arg, 1), s("-"), 0) ||
str8_match(str8_prefix(arg, 1), s("--"), 0) ||
str8_match(str8_prefix(arg, 1), s("/"), 0));
B32 is_cfg = 0;
B32 is_dmp = 0;
if(!is_flag && !after_first_non_flag)
@@ -11479,12 +11621,12 @@ rd_init(CmdLine *cmdln)
String8 header_suffix = {0};
header_suffix.str = header_suffix_buffer;
header_suffix.size = file_read(file, r1u64(10, 10+256), header_suffix_buffer);
String8 header_type_suffix = str8_skip(header_suffix, str8_find_needle(header_suffix, 0, str8_lit(" "), 0)+1);
if(str8_match(header_type_suffix, str8_lit("user"), StringMatchFlag_RightSideSloppy))
String8 header_type_suffix = str8_skip(header_suffix, str8_find_needle(header_suffix, 0, s(" "), 0)+1);
if(str8_match(header_type_suffix, s("user"), StringMatchFlag_RightSideSloppy))
{
implicit_user_arg = path_absolute_dst_from_relative_dst_src(scratch.arena, arg, get_process_info()->initial_path);
}
else if(str8_match(header_type_suffix, str8_lit("project"), StringMatchFlag_RightSideSloppy))
else if(str8_match(header_type_suffix, s("project"), StringMatchFlag_RightSideSloppy))
{
implicit_project_arg = path_absolute_dst_from_relative_dst_src(scratch.arena, arg, get_process_info()->initial_path);
}
@@ -14545,6 +14687,11 @@ rd_frame(void)
CFG_Node *split_panel_prev = panel->prev->cfg;
CFG_Node *new_parent = cfg_node_alloc(rd_state->cfg);
CFG_Node *new_sibling = cfg_node_alloc(rd_state->cfg);
if(panel == panel_tree.zoom_root)
{
CFG_Node *zoom_panel = cfg_node_child_from_string_or_alloc(rd_state->cfg, split_panel, s("zoom_root"));
cfg_node_insert_child(rd_state->cfg, new_parent, &cfg_nil_node, zoom_panel);
}
cfg_node_equip_string(rd_state->cfg, new_parent, split_panel->string);
cfg_node_equip_string(rd_state->cfg, split_panel, str8_lit("0.5"));
cfg_node_equip_string(rd_state->cfg, new_sibling, str8_lit("0.5"));
@@ -14726,6 +14873,17 @@ rd_frame(void)
}
rd_cmd(RD_CmdKind_FocusPanel, .panel = next_focused->cfg->id);
}break;
case RD_CmdKind_ParentPanel:
{
CFG_Node *panel = cfg_node_from_id(rd_regs()->panel);
CFG_PanelTree panel_tree = cfg_panel_tree_from_cfg(scratch.arena, cfg_node_from_id(rd_regs()->window));
CFG_PanelNode *panel_node = cfg_panel_node_from_tree_cfg(panel_tree.root, panel);
CFG_PanelNode *parent_node = panel_node->parent;
if(parent_node != &cfg_nil_panel_node)
{
rd_cmd(RD_CmdKind_FocusPanel, .panel = parent_node->cfg->id);
}
}break;
case RD_CmdKind_FocusPanel:
{
CFG_Node *panel = cfg_node_from_id(rd_regs()->panel);
@@ -14804,6 +14962,35 @@ rd_frame(void)
}
}break;
//- rjf: panel zooming
case RD_CmdKind_ToggleZoomPanel:
case RD_CmdKind_ZoomPanel:
case RD_CmdKind_UnzoomPanel:
{
CFG_Node *window = cfg_node_from_id(rd_regs()->window);
CFG_Node *panel = cfg_node_from_id(rd_regs()->panel);
CFG_PanelTree panel_tree = cfg_panel_tree_from_cfg(scratch.arena, window);
RD_WindowState *ws = rd_window_state_from_cfg(window);
ws->panel_hoist_cfg_id = rd_regs()->panel;
// rjf: remove existing zoom
B32 already_zoomed = 0;
{
CFG_PanelNode *zoom_root = panel_tree.zoom_root;
if(zoom_root->cfg != &cfg_nil_node)
{
already_zoomed = 1;
cfg_node_release(rd_state->cfg, cfg_node_child_from_string(zoom_root->cfg, s("zoom_root")));
}
}
// rjf: not already zoomed? -> zoom
if(!already_zoomed || kind == RD_CmdKind_ZoomPanel)
{
cfg_node_child_from_string_or_alloc(rd_state->cfg, panel, s("zoom_root"));
}
}break;
//- rjf: undo/redo
case RD_CmdKind_Undo:{}break;
case RD_CmdKind_Redo:{}break;
@@ -18595,13 +18782,14 @@ rd_frame(void)
F32 scrolling_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("scrolling_animations"));
F32 tooltip_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("tooltip_animations"));
F32 menu_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("menu_animations"));
rd_state->catchall_animation_rate = 1 - master_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt));
rd_state->menu_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-70.f * rd_state->frame_dt));
rd_state->menu_animation_rate__slow = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-50.f * rd_state->frame_dt));
rd_state->entity_alive_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-30.f * rd_state->frame_dt));
rd_state->rich_hover_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-50.f * rd_state->frame_dt));
rd_state->scrolling_animation_rate = 1 - master_animations_f*scrolling_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt));
rd_state->tooltip_animation_rate = 1 - master_animations_f*tooltip_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt));
rd_state->catchall_animation_rate = 1 - master_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt));
rd_state->menu_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-70.f * rd_state->frame_dt));
rd_state->menu_animation_rate__slow = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-50.f * rd_state->frame_dt));
rd_state->menu_animation_rate__very_slow = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-20.f * rd_state->frame_dt));
rd_state->entity_alive_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-30.f * rd_state->frame_dt));
rd_state->rich_hover_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-50.f * rd_state->frame_dt));
rd_state->scrolling_animation_rate = 1 - master_animations_f*scrolling_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt));
rd_state->tooltip_animation_rate = 1 - master_animations_f*tooltip_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt));
}
//////////////////////////////
+4
View File
@@ -324,6 +324,9 @@ struct RD_WindowState
CFG_ID query_last_bottom_view_id;
RD_QueryView *query_top;
// rjf: panel 'hoisting' state - bring-to-front
CFG_ID panel_hoist_cfg_id;
// rjf: hover eval state
B32 hover_eval_focused;
Arena *hover_eval_arena;
@@ -457,6 +460,7 @@ struct RD_State
F32 catchall_animation_rate;
F32 menu_animation_rate;
F32 menu_animation_rate__slow;
F32 menu_animation_rate__very_slow;
F32 entity_alive_animation_rate;
F32 rich_hover_animation_rate;
F32 scrolling_animation_rate;
+98 -9
View File
@@ -48,7 +48,7 @@ struct RDS_Msg
{
RDS_Msg *next;
SOCK_Endpoint endpoint;
String8 msg_raw;
String8 packet;
};
typedef struct RDS_Client RDS_Client;
@@ -87,9 +87,6 @@ struct RDS_State
Arena *c2d_arena;
RDS_Msg *c2d_msg_first;
RDS_Msg *c2d_msg_last;
//- rjf: demon run state
B32 demon_is_running;
};
global RDS_State *rds_state = 0;
@@ -120,7 +117,7 @@ dmn_thread__entry_point(void *p)
RDS_Msg *dst = push_array(scratch.arena, RDS_Msg, 1);
SLLQueuePush(msg_first, msg_last, dst);
dst->endpoint = src->endpoint;
dst->msg_raw = str8_copy(scratch.arena, src->msg_raw);
dst->packet = str8_copy(scratch.arena, src->packet);
}
arena_clear(rds_state->c2d_arena);
rds_state->c2d_msg_first = rds_state->c2d_msg_last = 0;
@@ -135,7 +132,7 @@ dmn_thread__entry_point(void *p)
for(RDS_Msg *msg_n = msg_first; msg_n != 0; msg_n = msg_n->next)
{
//- rjf: unpack message
DS_Msg msg = ds_msg_from_packet(scratch.arena, msg_n->msg_raw);
DS_Msg msg = ds_msg_from_packet(scratch.arena, msg_n->packet);
//- rjf: do action, get response
DS_Response response = {0};
@@ -197,6 +194,7 @@ dmn_thread__entry_point(void *p)
}
//- rjf: pack response & send back to the originating endpoint of the message
if(msg_n->endpoint.port != 0)
{
String8 data = ds_packet_from_response(scratch.arena, &response);
sock_send(rds_state->sock_session, SOCK_Protocol_TCP, msg_n->endpoint, data, max_U64);
@@ -205,7 +203,7 @@ dmn_thread__entry_point(void *p)
//- rjf: pack events & send to all connected client
if(events.count != 0)
{
String8 data = ds_serialized_from_dmn_events(scratch.arena, events);
String8 data = ds_packet_from_dmn_events(scratch.arena, events);
for(RDS_Client *c = rds_state->first_client; c != 0; c = c->order_next)
{
sock_send(rds_state->sock_session, SOCK_Protocol_TCP, c->endpoint, data, max_U64);
@@ -223,6 +221,8 @@ dmn_thread__entry_point(void *p)
internal void
entry_point(CmdLine *cmd_line)
{
Temp scratch = scratch_begin(0, 0);
//- rjf: get port argument
U64 port = 7273;
{
@@ -234,6 +234,42 @@ entry_point(CmdLine *cmd_line)
}
}
//- rjf: get launch targets from command line
typedef struct Target Target;
struct Target
{
Target *next;
String8List cmd_line;
};
Target *first_target = 0;
Target *last_target = 0;
{
B32 past_first_non_flag = 0;
for(U64 idx = 1; idx < cmd_line->argc; idx += 1)
{
String8 arg = str8_cstring(cmd_line->argv[idx]);
B32 is_flag = (str8_match(str8_prefix(arg, 1), s("-"), 0) ||
str8_match(str8_prefix(arg, 1), s("--"), 0) ||
str8_match(str8_prefix(arg, 1), s("/"), 0));
past_first_non_flag = (past_first_non_flag || !is_flag);
if(past_first_non_flag)
{
// rjf: create new target after ;s, or if we don't have one
if(str8_match(arg, s(";"), 0) || first_target == 0)
{
Target *t = push_array(scratch.arena, Target, 1);
SLLQueuePush(first_target, last_target, t);
}
// rjf: push this string to the most recently added target
if(last_target != 0)
{
str8_list_push(scratch.arena, &last_target->cmd_line, arg);
}
}
}
}
//- rjf: set up shared state
Arena *arena = arena_alloc();
rds_state = push_array(arena, RDS_State, 1);
@@ -242,10 +278,41 @@ entry_point(CmdLine *cmd_line)
rds_state->c2d_rw_mutex = rw_mutex_alloc();
rds_state->c2d_cv = cond_var_alloc();
rds_state->c2d_arena = arena_alloc();
rds_state->client_slots_count = 64;
rds_state->client_slots = push_array(arena, RDS_ClientSlot, rds_state->client_slots_count);
//- rjf: launch demon thread
thread_launch(dmn_thread__entry_point, 0);
//- rjf: do initial launch of all command-line-specified targets
{
String8 current_path = get_current_path(scratch.arena);
for EachNode(t, Target, first_target)
{
fprintf(stderr, "[launching command line target]\n");
fprintf(stderr, " ");
for EachNode(n, String8Node, t->cmd_line.first)
{
fprintf(stderr, " %.*s", str8_varg(n->string));
}
fprintf(stderr, "\n");
DS_Msg msg =
{
.kind = DS_MsgKind_Launch,
.command_line = t->cmd_line,
.path = current_path,
};
String8 packet = ds_packet_from_msg(scratch.arena, &msg);
RWMutexScope(rds_state->c2d_rw_mutex, 1)
{
RDS_Msg *msg = push_array(rds_state->c2d_arena, RDS_Msg, 1);
msg->packet = str8_copy(rds_state->c2d_arena, packet);
SLLQueuePush(rds_state->c2d_msg_first, rds_state->c2d_msg_last, msg);
}
cond_var_broadcast(rds_state->c2d_cv);
}
}
//- rjf: loop: wait for messages, issue commands to demon
for(;;)
{
@@ -318,15 +385,35 @@ entry_point(CmdLine *cmd_line)
if(peek_kind < DS_MsgKind_Launch || DS_MsgKind_SingleStep < peek_kind)
{
DS_Msg msg = ds_msg_from_packet(scratch.arena, data);
// rjf: form base response info
DS_Response response = {0};
response.msg_id = msg.msg_id;
response.good = 1;
// rjf: do message specifics
switch(msg.kind)
{
default:{}break;
//- rjf: response
case DS_MsgKind_Handshake:
{
// TODO(rjf): send initial state
}break;
//- rjf: halting
case DS_MsgKind_Halt:
{
dmn_halt(0, 0);
}break;
}
// rjf: send response
{
String8 packet = ds_packet_from_response(scratch.arena, &response);
sock_send(rds_state->sock_session, protocol, endpoint, packet, now_time_us()+10000000);
}
}
}
@@ -335,14 +422,16 @@ entry_point(CmdLine *cmd_line)
{
RWMutexScope(rds_state->c2d_rw_mutex, 1)
{
String8 msg_raw = str8_skip(data, sizeof(header));
RDS_Msg *msg = push_array(rds_state->c2d_arena, RDS_Msg, 1);
msg->endpoint = endpoint;
msg->msg_raw = str8_copy(rds_state->c2d_arena, msg_raw);
msg->packet = str8_copy(rds_state->c2d_arena, data);
SLLQueuePush(rds_state->c2d_msg_first, rds_state->c2d_msg_last, msg);
}
cond_var_broadcast(rds_state->c2d_cv);
}
scratch_end(scratch);
}
scratch_end(scratch);
}