mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-14 13:31:25 -07:00
eliminate stateful keybindings data structure - move to on-the-fly cfg tree usage
This commit is contained in:
+179
-130
@@ -1143,6 +1143,48 @@ rd_cfg_is_project_filtered(RD_Cfg *cfg)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal RD_KeyMapNodePtrList
|
||||
rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string)
|
||||
{
|
||||
RD_KeyMapNodePtrList list = {0};
|
||||
{
|
||||
U64 hash = d_hash_from_string(string);
|
||||
U64 slot_idx = hash%rd_state->key_map->name_slots_count;
|
||||
for(RD_KeyMapNode *n = rd_state->key_map->name_slots[slot_idx].first; n != 0; n = n->name_hash_next)
|
||||
{
|
||||
if(str8_match(n->name, string, 0))
|
||||
{
|
||||
RD_KeyMapNodePtr *ptr = push_array(arena, RD_KeyMapNodePtr, 1);
|
||||
ptr->v = n;
|
||||
SLLQueuePush(list.first, list.last, ptr);
|
||||
list.count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
internal RD_KeyMapNodePtrList
|
||||
rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding)
|
||||
{
|
||||
RD_KeyMapNodePtrList list = {0};
|
||||
{
|
||||
U64 hash = d_hash_from_string(str8_struct(&binding));
|
||||
U64 slot_idx = hash%rd_state->key_map->binding_slots_count;
|
||||
for(RD_KeyMapNode *n = rd_state->key_map->binding_slots[slot_idx].first; n != 0; n = n->binding_hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&binding, &n->binding))
|
||||
{
|
||||
RD_KeyMapNodePtr *ptr = push_array(arena, RD_KeyMapNodePtr, 1);
|
||||
ptr->v = n;
|
||||
SLLQueuePush(list.first, list.last, ptr);
|
||||
list.count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity State Functions
|
||||
|
||||
@@ -4231,7 +4273,8 @@ rd_window_frame(void)
|
||||
.display_name__matches = name_matches,
|
||||
.description = cmd_desc,
|
||||
.description__matches = desc_matches,
|
||||
.is_non_code = 1);
|
||||
.is_non_code = 1,
|
||||
.can_have_bindings = 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4391,9 +4434,17 @@ rd_window_frame(void)
|
||||
}
|
||||
|
||||
// rjf: bindings
|
||||
if(0) UI_Column
|
||||
if(item->can_have_bindings)
|
||||
{
|
||||
|
||||
ui_set_next_flags(UI_BoxFlag_Clickable);
|
||||
UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f))
|
||||
{
|
||||
ui_set_next_flags(UI_BoxFlag_Clickable);
|
||||
UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f))
|
||||
{
|
||||
rd_cmd_binding_buttons(item->string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9997,123 +10048,6 @@ rd_push_search_string(Arena *arena)
|
||||
////////////////////////////////
|
||||
//~ rjf: Colors, Fonts, Config
|
||||
|
||||
//- rjf: keybindings
|
||||
|
||||
internal OS_Key
|
||||
rd_os_key_from_cfg_string(String8 string)
|
||||
{
|
||||
OS_Key result = OS_Key_Null;
|
||||
{
|
||||
for(OS_Key key = OS_Key_Null; key < OS_Key_COUNT; key = (OS_Key)(key+1))
|
||||
{
|
||||
if(str8_match(string, os_g_key_cfg_string_table[key], StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
result = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
rd_clear_bindings(void)
|
||||
{
|
||||
arena_clear(rd_state->key_map_arena);
|
||||
rd_state->key_map_table_size = 1024;
|
||||
rd_state->key_map_table = push_array(rd_state->key_map_arena, RD_KeyMapSlot, rd_state->key_map_table_size);
|
||||
rd_state->key_map_total_count = 0;
|
||||
}
|
||||
|
||||
internal RD_BindingList
|
||||
rd_bindings_from_name(Arena *arena, String8 name)
|
||||
{
|
||||
RD_BindingList result = {0};
|
||||
U64 hash = d_hash_from_string(name);
|
||||
U64 slot = hash%rd_state->key_map_table_size;
|
||||
for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first; n != 0; n = n->hash_next)
|
||||
{
|
||||
if(str8_match(n->name, name, 0))
|
||||
{
|
||||
RD_BindingNode *node = push_array(arena, RD_BindingNode, 1);
|
||||
node->binding = n->binding;
|
||||
SLLQueuePush(result.first, result.last, node);
|
||||
result.count += 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
rd_bind_name(String8 name, RD_Binding binding)
|
||||
{
|
||||
if(binding.key != OS_Key_Null)
|
||||
{
|
||||
U64 hash = d_hash_from_string(name);
|
||||
U64 slot = hash%rd_state->key_map_table_size;
|
||||
RD_KeyMapNode *existing_node = 0;
|
||||
for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first; n != 0; n = n->hash_next)
|
||||
{
|
||||
if(str8_match(n->name, name, 0) && n->binding.key == binding.key && n->binding.modifiers == binding.modifiers)
|
||||
{
|
||||
existing_node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(existing_node == 0)
|
||||
{
|
||||
RD_KeyMapNode *n = rd_state->free_key_map_node;
|
||||
if(n == 0)
|
||||
{
|
||||
n = push_array(rd_state->arena, RD_KeyMapNode, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rd_state->free_key_map_node = rd_state->free_key_map_node->hash_next;
|
||||
}
|
||||
n->name = push_str8_copy(rd_state->arena, name);
|
||||
n->binding = binding;
|
||||
DLLPushBack_NP(rd_state->key_map_table[slot].first, rd_state->key_map_table[slot].last, n, hash_next, hash_prev);
|
||||
rd_state->key_map_total_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
rd_unbind_name(String8 name, RD_Binding binding)
|
||||
{
|
||||
U64 hash = d_hash_from_string(name);
|
||||
U64 slot = hash%rd_state->key_map_table_size;
|
||||
for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first, *next = 0; n != 0; n = next)
|
||||
{
|
||||
next = n->hash_next;
|
||||
if(str8_match(n->name, name, 0) && n->binding.key == binding.key && n->binding.modifiers == binding.modifiers)
|
||||
{
|
||||
DLLRemove_NP(rd_state->key_map_table[slot].first, rd_state->key_map_table[slot].last, n, hash_next, hash_prev);
|
||||
n->hash_next = rd_state->free_key_map_node;
|
||||
rd_state->free_key_map_node = n;
|
||||
rd_state->key_map_total_count -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal String8List
|
||||
rd_cmd_name_list_from_binding(Arena *arena, RD_Binding binding)
|
||||
{
|
||||
String8List result = {0};
|
||||
for(U64 idx = 0; idx < rd_state->key_map_table_size; idx += 1)
|
||||
{
|
||||
for(RD_KeyMapNode *n = rd_state->key_map_table[idx].first; n != 0; n = n->hash_next)
|
||||
{
|
||||
if(n->binding.key == binding.key && n->binding.modifiers == binding.modifiers)
|
||||
{
|
||||
str8_list_push(arena, &result, n->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: colors
|
||||
|
||||
internal Vec4F32
|
||||
@@ -11335,7 +11269,7 @@ rd_cmd_kind_info_from_string(String8 string)
|
||||
{
|
||||
RD_CmdKindInfo *info = &rd_nil_cmd_kind_info;
|
||||
{
|
||||
// TODO(rjf): extend this by looking up into dynamically-registered commands by views
|
||||
// TODO(rjf): @dynamic_cmds extend this by looking up into dynamically-registered commands by views
|
||||
RD_CmdKind kind = rd_cmd_kind_from_string(string);
|
||||
if(kind != RD_CmdKind_Null)
|
||||
{
|
||||
@@ -11419,7 +11353,6 @@ rd_init(CmdLine *cmdln)
|
||||
rd_state->entities_base = push_array(rd_state->entities_arena, RD_Entity, 0);
|
||||
rd_state->entities_count = 0;
|
||||
rd_state->entities_root = rd_entity_alloc(&rd_nil_entity, RD_EntityKind_Root);
|
||||
rd_state->key_map_arena = arena_alloc();
|
||||
rd_state->popup_arena = arena_alloc();
|
||||
rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu"));
|
||||
rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu"));
|
||||
@@ -11432,7 +11365,6 @@ rd_init(CmdLine *cmdln)
|
||||
rd_state->drag_drop_arena = arena_alloc();
|
||||
rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1);
|
||||
rd_state->top_regs = &rd_state->base_regs;
|
||||
rd_clear_bindings();
|
||||
|
||||
// rjf: set up top-level config entity trees
|
||||
{
|
||||
@@ -11704,6 +11636,109 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build key map from config
|
||||
//
|
||||
{
|
||||
//- rjf: set up table
|
||||
rd_state->key_map = push_array(rd_frame_arena(), RD_KeyMap, 1);
|
||||
RD_KeyMap *key_map = rd_state->key_map;
|
||||
key_map->name_slots_count = 4096;
|
||||
key_map->name_slots = push_array(rd_frame_arena(), RD_KeyMapSlot, key_map->name_slots_count);
|
||||
key_map->binding_slots_count = 4096;
|
||||
key_map->binding_slots = push_array(rd_frame_arena(), RD_KeyMapSlot, key_map->binding_slots_count);
|
||||
|
||||
//- rjf: gather & parse all explicitly stored keybinding sets
|
||||
RD_CfgList keybindings_cfg_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("keybindings"));
|
||||
for(RD_CfgNode *n = keybindings_cfg_list.first; n != 0; n = n->next)
|
||||
{
|
||||
RD_Cfg *keybindings_root = n->v;
|
||||
for(RD_Cfg *keybinding = keybindings_root->first; keybinding != &rd_nil_cfg; keybinding = keybinding->next)
|
||||
{
|
||||
String8 name = {0};
|
||||
RD_Binding binding = {0};
|
||||
for(RD_Cfg *child = keybinding->first; child != &rd_nil_cfg; child = child->next)
|
||||
{
|
||||
if(0){}
|
||||
else if(str8_match(child->string, str8_lit("ctrl"), 0)) { binding.modifiers |= OS_Modifier_Ctrl; }
|
||||
else if(str8_match(child->string, str8_lit("alt"), 0)) { binding.modifiers |= OS_Modifier_Alt; }
|
||||
else if(str8_match(child->string, str8_lit("shift"), 0)) { binding.modifiers |= OS_Modifier_Shift; }
|
||||
else
|
||||
{
|
||||
OS_Key key = OS_Key_Null;
|
||||
for EachEnumVal(OS_Key, k)
|
||||
{
|
||||
if(str8_match(child->string, os_g_key_cfg_string_table[k], StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
key = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(key != OS_Key_Null)
|
||||
{
|
||||
binding.key = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = child->string;
|
||||
for(U64 idx = 0; idx < ArrayCount(rd_binding_version_remap_old_name_table); idx += 1)
|
||||
{
|
||||
if(str8_match(rd_binding_version_remap_old_name_table[idx], name, StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
name = rd_binding_version_remap_new_name_table[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(name.size != 0)
|
||||
{
|
||||
U64 name_hash = d_hash_from_string(name);
|
||||
U64 binding_hash = d_hash_from_string(str8_struct(&binding));
|
||||
U64 name_slot_idx = name_hash%key_map->name_slots_count;
|
||||
U64 binding_slot_idx = binding_hash%key_map->binding_slots_count;
|
||||
RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1);
|
||||
n->cfg = keybinding;
|
||||
n->name = push_str8_copy(rd_frame_arena(), name);
|
||||
n->binding = binding;
|
||||
SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next);
|
||||
SLLQueuePush_N(key_map->binding_slots[binding_slot_idx].first, key_map->binding_slots[binding_slot_idx].last, n, binding_hash_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: iterate all commands - if they are not found in the map, then use
|
||||
// the default binding.
|
||||
// TODO(rjf): @dynamic_cmds
|
||||
for EachElement(idx, rd_default_binding_table)
|
||||
{
|
||||
String8 name = rd_default_binding_table[idx].string;
|
||||
B32 name_was_mapped = 0;
|
||||
U64 name_hash = d_hash_from_string(name);
|
||||
U64 name_slot_idx = name_hash%key_map->name_slots_count;
|
||||
for(RD_KeyMapNode *n = key_map->name_slots[name_slot_idx].first; n != 0; n = n->name_hash_next)
|
||||
{
|
||||
if(str8_match(n->name, name, 0))
|
||||
{
|
||||
name_was_mapped = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!name_was_mapped)
|
||||
{
|
||||
RD_Binding binding = rd_default_binding_table[idx].binding;
|
||||
U64 binding_hash = d_hash_from_string(str8_struct(&binding));
|
||||
U64 binding_slot_idx = binding_hash%key_map->binding_slots_count;
|
||||
RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1);
|
||||
n->cfg = &rd_nil_cfg;
|
||||
n->name = push_str8_copy(rd_frame_arena(), name);
|
||||
n->binding = binding;
|
||||
SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next);
|
||||
SLLQueuePush_N(key_map->binding_slots[binding_slot_idx].first, key_map->binding_slots[binding_slot_idx].last, n, binding_hash_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: get events from the OS
|
||||
//
|
||||
@@ -11774,7 +11809,7 @@ rd_frame(void)
|
||||
if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Delete))
|
||||
{
|
||||
rd_request_frame();
|
||||
rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding);
|
||||
// TODO(rjf): @cfg rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding);
|
||||
rd_state->bind_change_active = 0;
|
||||
rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]);
|
||||
}
|
||||
@@ -11798,8 +11833,8 @@ rd_frame(void)
|
||||
binding.key = event->key;
|
||||
binding.modifiers = event->modifiers;
|
||||
}
|
||||
rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding);
|
||||
rd_bind_name(rd_state->bind_change_cmd_name, binding);
|
||||
// TODO(rjf): @cfg rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding);
|
||||
// TODO(rjf): @cfg rd_bind_name(rd_state->bind_change_cmd_name, binding);
|
||||
U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key);
|
||||
os_text(&events, event->window, codepoint);
|
||||
os_eat_event(&events, event);
|
||||
@@ -11887,13 +11922,13 @@ rd_frame(void)
|
||||
if(!take && event->kind == OS_EventKind_Press)
|
||||
{
|
||||
RD_Binding binding = {event->key, event->modifiers};
|
||||
String8List spec_candidates = rd_cmd_name_list_from_binding(scratch.arena, binding);
|
||||
if(spec_candidates.first != 0)
|
||||
RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_binding(scratch.arena, binding);
|
||||
if(key_map_nodes.first != 0)
|
||||
{
|
||||
U32 hit_char = os_codepoint_from_modifiers_and_key(event->modifiers, event->key);
|
||||
if(hit_char == 0 || allow_text_hotkeys)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_RunCommand, .cmd_name = spec_candidates.first->string);
|
||||
rd_cmd(RD_CmdKind_RunCommand, .cmd_name = key_map_nodes.first->v->name);
|
||||
if(allow_text_hotkeys)
|
||||
{
|
||||
os_text(&events, event->window, hit_char);
|
||||
@@ -13118,6 +13153,7 @@ rd_frame(void)
|
||||
}
|
||||
|
||||
//- rjf: apply keybindings
|
||||
#if 0 // TODO(rjf): @cfg
|
||||
if(src == RD_CfgSrc_User)
|
||||
{
|
||||
rd_clear_bindings();
|
||||
@@ -13150,7 +13186,15 @@ rd_frame(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_Key k = rd_os_key_from_cfg_string(child->string);
|
||||
OS_Key k = OS_Key_Null;
|
||||
for EachEnumVal(OS_Key, key)
|
||||
{
|
||||
if(str8_match(child->string, os_g_key_cfg_string_table[key], StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
k = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(k != OS_Key_Null)
|
||||
{
|
||||
key = k;
|
||||
@@ -13180,6 +13224,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//- rjf: reset theme to default
|
||||
MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark));
|
||||
@@ -13362,6 +13407,7 @@ rd_frame(void)
|
||||
#endif
|
||||
|
||||
//- rjf: if config bound 0 keys, we need to do some sensible default
|
||||
#if 0 // TODO(rjf): @cfg
|
||||
if(src == RD_CfgSrc_User && rd_state->key_map_total_count == 0)
|
||||
{
|
||||
for(U64 idx = 0; idx < ArrayCount(rd_default_binding_table); idx += 1)
|
||||
@@ -13370,8 +13416,10 @@ rd_frame(void)
|
||||
rd_bind_name(pair->string, pair->binding);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//- rjf: always ensure that the meta controls have bindings
|
||||
#if 0 // TODO(rjf): @cfg
|
||||
if(src == RD_CfgSrc_User)
|
||||
{
|
||||
struct
|
||||
@@ -13395,6 +13443,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
|
||||
//- rjf: writing config changes
|
||||
|
||||
+86
-60
@@ -29,6 +29,38 @@ struct RD_HandleList
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Binding Types
|
||||
|
||||
typedef struct RD_Binding RD_Binding;
|
||||
struct RD_Binding
|
||||
{
|
||||
OS_Key key;
|
||||
OS_Modifiers modifiers;
|
||||
};
|
||||
|
||||
typedef struct RD_BindingNode RD_BindingNode;
|
||||
struct RD_BindingNode
|
||||
{
|
||||
RD_BindingNode *next;
|
||||
RD_Binding binding;
|
||||
};
|
||||
|
||||
typedef struct RD_BindingList RD_BindingList;
|
||||
struct RD_BindingList
|
||||
{
|
||||
RD_BindingNode *first;
|
||||
RD_BindingNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct RD_StringBindingPair RD_StringBindingPair;
|
||||
struct RD_StringBindingPair
|
||||
{
|
||||
String8 string;
|
||||
RD_Binding binding;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Evaluation Spaces
|
||||
|
||||
@@ -84,57 +116,6 @@ enum
|
||||
RD_EntityFlag_MarkedForDeletion = (1<<31),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Binding Types
|
||||
|
||||
typedef struct RD_Binding RD_Binding;
|
||||
struct RD_Binding
|
||||
{
|
||||
OS_Key key;
|
||||
OS_Modifiers modifiers;
|
||||
};
|
||||
|
||||
typedef struct RD_BindingNode RD_BindingNode;
|
||||
struct RD_BindingNode
|
||||
{
|
||||
RD_BindingNode *next;
|
||||
RD_Binding binding;
|
||||
};
|
||||
|
||||
typedef struct RD_BindingList RD_BindingList;
|
||||
struct RD_BindingList
|
||||
{
|
||||
RD_BindingNode *first;
|
||||
RD_BindingNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct RD_StringBindingPair RD_StringBindingPair;
|
||||
struct RD_StringBindingPair
|
||||
{
|
||||
String8 string;
|
||||
RD_Binding binding;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Map Types
|
||||
|
||||
typedef struct RD_KeyMapNode RD_KeyMapNode;
|
||||
struct RD_KeyMapNode
|
||||
{
|
||||
RD_KeyMapNode *hash_next;
|
||||
RD_KeyMapNode *hash_prev;
|
||||
String8 name;
|
||||
RD_Binding binding;
|
||||
};
|
||||
|
||||
typedef struct RD_KeyMapSlot RD_KeyMapSlot;
|
||||
struct RD_KeyMapSlot
|
||||
{
|
||||
RD_KeyMapNode *first;
|
||||
RD_KeyMapNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Setting Types
|
||||
|
||||
@@ -330,6 +311,50 @@ struct RD_CfgRec
|
||||
S32 pop_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Map Types
|
||||
|
||||
typedef struct RD_KeyMapNode RD_KeyMapNode;
|
||||
struct RD_KeyMapNode
|
||||
{
|
||||
RD_KeyMapNode *name_hash_next;
|
||||
RD_KeyMapNode *binding_hash_next;
|
||||
RD_Cfg *cfg;
|
||||
String8 name;
|
||||
RD_Binding binding;
|
||||
};
|
||||
|
||||
typedef struct RD_KeyMapNodePtr RD_KeyMapNodePtr;
|
||||
struct RD_KeyMapNodePtr
|
||||
{
|
||||
RD_KeyMapNodePtr *next;
|
||||
RD_KeyMapNode *v;
|
||||
};
|
||||
|
||||
typedef struct RD_KeyMapNodePtrList RD_KeyMapNodePtrList;
|
||||
struct RD_KeyMapNodePtrList
|
||||
{
|
||||
RD_KeyMapNodePtr *first;
|
||||
RD_KeyMapNodePtr *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct RD_KeyMapSlot RD_KeyMapSlot;
|
||||
struct RD_KeyMapSlot
|
||||
{
|
||||
RD_KeyMapNode *first;
|
||||
RD_KeyMapNode *last;
|
||||
};
|
||||
|
||||
typedef struct RD_KeyMap RD_KeyMap;
|
||||
struct RD_KeyMap
|
||||
{
|
||||
U64 name_slots_count;
|
||||
RD_KeyMapSlot *name_slots;
|
||||
U64 binding_slots_count;
|
||||
RD_KeyMapSlot *binding_slots;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: New Panel Types (Queried From Config)
|
||||
|
||||
@@ -550,6 +575,7 @@ struct RD_ListerItem
|
||||
FuzzyMatchRangeList description__matches;
|
||||
U64 group;
|
||||
B32 is_non_code;
|
||||
B32 can_have_bindings;
|
||||
};
|
||||
|
||||
typedef struct RD_ListerItemChunkNode RD_ListerItemChunkNode;
|
||||
@@ -789,10 +815,13 @@ struct RD_State
|
||||
// rjf: dbgi match store
|
||||
DI_MatchStore *match_store;
|
||||
|
||||
// rjf: ambiguous path table
|
||||
// rjf: ambiguous path table (constructed from-scratch each frame)
|
||||
U64 ambiguous_path_slots_count;
|
||||
RD_AmbiguousPathNode **ambiguous_path_slots;
|
||||
|
||||
// rjf: key map (constructed from-scratch each frame)
|
||||
RD_KeyMap *key_map;
|
||||
|
||||
// rjf: registers stack
|
||||
RD_RegsNode base_regs;
|
||||
RD_RegsNode *top_regs;
|
||||
@@ -890,11 +919,13 @@ struct RD_State
|
||||
RD_EntityListCache kind_caches[RD_EntityKind_COUNT];
|
||||
|
||||
// rjf: key map table
|
||||
#if 0 // TODO(rjf): @cfg
|
||||
Arena *key_map_arena;
|
||||
U64 key_map_table_size;
|
||||
RD_KeyMapSlot *key_map_table;
|
||||
RD_KeyMapNode *free_key_map_node;
|
||||
U64 key_map_total_count;
|
||||
#endif
|
||||
|
||||
// rjf: bind change
|
||||
Arena *bind_change_arena;
|
||||
@@ -1121,6 +1152,9 @@ internal Rng2F32 rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode
|
||||
|
||||
internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg);
|
||||
|
||||
internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string);
|
||||
internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Stateful Functions
|
||||
|
||||
@@ -1303,14 +1337,6 @@ internal String8 rd_push_search_string(Arena *arena);
|
||||
////////////////////////////////
|
||||
//~ rjf: Colors, Fonts, Config
|
||||
|
||||
//- rjf: keybindings
|
||||
internal OS_Key rd_os_key_from_cfg_string(String8 string);
|
||||
internal void rd_clear_bindings(void);
|
||||
internal RD_BindingList rd_bindings_from_name(Arena *arena, String8 name);
|
||||
internal void rd_bind_name(String8 name, RD_Binding binding);
|
||||
internal void rd_unbind_name(String8 name, RD_Binding binding);
|
||||
internal String8List rd_cmd_name_list_from_binding(Arena *arena, RD_Binding binding);
|
||||
|
||||
//- rjf: colors
|
||||
internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color);
|
||||
internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind);
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
// etc., all need to be merged, and optionally contextualized/filtered.
|
||||
// right-clicking a tab should be equivalent to spawning a command lister,
|
||||
// but only with commands that are directly
|
||||
//
|
||||
// [ ] r8 bitmap view rule seems incorrect?
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: post-0.9.12 TODO notes
|
||||
|
||||
+14
-12
@@ -95,26 +95,28 @@ internal void
|
||||
rd_cmd_binding_buttons(String8 name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
RD_BindingList bindings = rd_bindings_from_name(scratch.arena, name);
|
||||
RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_name(scratch.arena, name);
|
||||
|
||||
//- rjf: build buttons for each binding
|
||||
for(RD_BindingNode *n = bindings.first; n != 0; n = n->next)
|
||||
for(RD_KeyMapNodePtr *n = key_map_nodes.first; n != 0; n = n->next)
|
||||
{
|
||||
RD_Binding binding = n->binding;
|
||||
RD_Binding binding = n->v->binding;
|
||||
B32 rebinding_active_for_this_binding = (rd_state->bind_change_active &&
|
||||
str8_match(rd_state->bind_change_cmd_name, name, 0) &&
|
||||
rd_state->bind_change_binding.key == binding.key &&
|
||||
rd_state->bind_change_binding.modifiers == binding.modifiers);
|
||||
|
||||
//- rjf: grab all conflicts
|
||||
String8List specs_with_binding = rd_cmd_name_list_from_binding(scratch.arena, binding);
|
||||
B32 has_conflicts = 0;
|
||||
for(String8Node *n = specs_with_binding.first; n != 0; n = n->next)
|
||||
RD_KeyMapNodePtrList nodes_with_this_binding = rd_key_map_node_ptr_list_from_binding(scratch.arena, binding);
|
||||
{
|
||||
if(!str8_match(n->string, name, 0))
|
||||
for(RD_KeyMapNodePtr *n2 = nodes_with_this_binding.first; n2 != 0; n2 = n2->next)
|
||||
{
|
||||
has_conflicts = 1;
|
||||
break;
|
||||
if(!str8_match(n->v->name, n2->v->name, 0))
|
||||
{
|
||||
has_conflicts = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,11 +198,11 @@ rd_cmd_binding_buttons(String8 name)
|
||||
if(ui_hovering(sig) && has_conflicts) UI_Tooltip
|
||||
{
|
||||
UI_PrefWidth(ui_children_sum(1)) rd_error_label(str8_lit("This binding conflicts with those for:"));
|
||||
for(String8Node *n = specs_with_binding.first; n != 0; n = n->next)
|
||||
for(RD_KeyMapNodePtr *n2 = nodes_with_this_binding.first; n2 != 0; n2 = n2->next)
|
||||
{
|
||||
if(!str8_match(n->string, name, 0))
|
||||
if(!str8_match(n2->v->name, n->v->name, 0))
|
||||
{
|
||||
RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(n->string);
|
||||
RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(n2->v->name);
|
||||
ui_labelf("%S", info->display_name);
|
||||
}
|
||||
}
|
||||
@@ -219,7 +221,7 @@ rd_cmd_binding_buttons(String8 name)
|
||||
UI_Signal sig = rd_icon_button(RD_IconKind_X, 0, str8_lit("###delete_binding"));
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
rd_unbind_name(name, binding);
|
||||
// TODO(rjf): @cfg rd_unbind_name(name, binding);
|
||||
rd_state->bind_change_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user