mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-21 11:14:59 -07:00
Merge remote-tracking branch 'EpicGames/master' into odin
# Conflicts: # src/df/core/df_core.mdesk # src/df/core/generated/df_core.meta.c
This commit is contained in:
@@ -234,4 +234,14 @@
|
||||
# define LANG_C 0
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unsupported Errors
|
||||
|
||||
#if ARCH_X86
|
||||
# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported.
|
||||
#endif
|
||||
#if !ARCH_X64
|
||||
# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported.
|
||||
#endif
|
||||
|
||||
#endif // BASE_CONTEXT_CRACKING_H
|
||||
|
||||
+10
-7
@@ -37,17 +37,17 @@ log_select(Log *log)
|
||||
//~ rjf: Log Building/Clearing
|
||||
|
||||
internal void
|
||||
log_msg(String8 string)
|
||||
log_msg(LogMsgKind kind, String8 string)
|
||||
{
|
||||
if(log_active != 0 && log_active->top_scope != 0)
|
||||
{
|
||||
String8 string_copy = push_str8_copy(log_active->arena, string);
|
||||
str8_list_push(log_active->arena, &log_active->top_scope->strings, string_copy);
|
||||
str8_list_push(log_active->arena, &log_active->top_scope->strings[kind], string_copy);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
log_msgf(char *fmt, ...)
|
||||
log_msgf(LogMsgKind kind, char *fmt, ...)
|
||||
{
|
||||
if(log_active != 0)
|
||||
{
|
||||
@@ -55,7 +55,7 @@ log_msgf(char *fmt, ...)
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
||||
log_msg(string);
|
||||
log_msg(kind, string);
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@@ -76,10 +76,10 @@ log_scope_begin(void)
|
||||
}
|
||||
}
|
||||
|
||||
internal String8
|
||||
internal LogScopeResult
|
||||
log_scope_end(Arena *arena)
|
||||
{
|
||||
String8 result = {0};
|
||||
LogScopeResult result = {0};
|
||||
if(log_active != 0)
|
||||
{
|
||||
LogScope *scope = log_active->top_scope;
|
||||
@@ -88,7 +88,10 @@ log_scope_end(Arena *arena)
|
||||
SLLStackPop(log_active->top_scope);
|
||||
if(arena != 0)
|
||||
{
|
||||
result = str8_list_join(arena, &scope->strings, 0);
|
||||
for(EachEnumVal(LogMsgKind, kind))
|
||||
{
|
||||
result.strings[kind] = str8_list_join(arena, &scope->strings[kind], 0);
|
||||
}
|
||||
}
|
||||
arena_pop_to(log_active->arena, scope->pos);
|
||||
}
|
||||
|
||||
+22
-4
@@ -7,12 +7,26 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Types
|
||||
|
||||
typedef enum LogMsgKind
|
||||
{
|
||||
LogMsgKind_Info,
|
||||
LogMsgKind_UserError,
|
||||
LogMsgKind_COUNT
|
||||
}
|
||||
LogMsgKind;
|
||||
|
||||
typedef struct LogScope LogScope;
|
||||
struct LogScope
|
||||
{
|
||||
LogScope *next;
|
||||
U64 pos;
|
||||
String8List strings;
|
||||
String8List strings[LogMsgKind_COUNT];
|
||||
};
|
||||
|
||||
typedef struct LogScopeResult LogScopeResult;
|
||||
struct LogScopeResult
|
||||
{
|
||||
String8 strings[LogMsgKind_COUNT];
|
||||
};
|
||||
|
||||
typedef struct Log Log;
|
||||
@@ -32,13 +46,17 @@ internal void log_select(Log *log);
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Building
|
||||
|
||||
internal void log_msg(String8 string);
|
||||
internal void log_msgf(char *fmt, ...);
|
||||
internal void log_msg(LogMsgKind kind, String8 string);
|
||||
internal void log_msgf(LogMsgKind kind, char *fmt, ...);
|
||||
#define log_info(s) log_msg(LogMsgKind_Info, (s))
|
||||
#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__)
|
||||
#define log_user_error(s) log_msg(LogMsgKind_UserError, (s))
|
||||
#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Scopes
|
||||
|
||||
internal void log_scope_begin(void);
|
||||
internal String8 log_scope_end(Arena *arena);
|
||||
internal LogScopeResult log_scope_end(Arena *arena);
|
||||
|
||||
#endif // BASE_LOG_H
|
||||
|
||||
+39
-28
@@ -743,6 +743,8 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list)
|
||||
CTRL_Event *event = &n->v;
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
|
||||
//- rjf: processes
|
||||
case CTRL_EventKind_NewProc:
|
||||
{
|
||||
@@ -1794,8 +1796,17 @@ ctrl_thread__entry_point(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
String8 log = log_scope_end(scratch.arena);
|
||||
ctrl_thread__flush_log(log);
|
||||
//- rjf: gather & output logs
|
||||
LogScopeResult log = log_scope_end(scratch.arena);
|
||||
ctrl_thread__flush_info_log(log.strings[LogMsgKind_Info]);
|
||||
if(log.strings[LogMsgKind_UserError].size != 0)
|
||||
{
|
||||
CTRL_EventList evts = {0};
|
||||
CTRL_Event *evt = ctrl_event_list_push(scratch.arena, &evts);
|
||||
evt->kind = CTRL_EventKind_Error;
|
||||
evt->string = log.strings[LogMsgKind_UserError];
|
||||
ctrl_c2u_push_events(&evts);
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
@@ -1942,16 +1953,16 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
if(next_event_node != 0) CTRL_CtrlThreadLogScope
|
||||
{
|
||||
DMN_Event *ev = &next_event_node->v;
|
||||
log_msgf("--- event ---\n");
|
||||
log_msgf("kind: %S\n", dmn_event_kind_string_table[ev->kind]);
|
||||
log_msgf("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]);
|
||||
log_msgf("process: [%I64u]\n", ev->process.u64[0]);
|
||||
log_msgf("thread: [%I64u]\n", ev->thread.u64[0]);
|
||||
log_msgf("module: [%I64u]\n", ev->module.u64[0]);
|
||||
log_msgf("arch: %S\n", string_from_architecture(ev->arch));
|
||||
log_msgf("address: 0x%I64x\n", ev->address);
|
||||
log_msgf("string: \"%S\"\n", ev->string);
|
||||
log_msgf("ip_vaddr: 0x%I64x\n", ev->instruction_pointer);
|
||||
log_infof("--- event ---\n");
|
||||
log_infof("kind: %S\n", dmn_event_kind_string_table[ev->kind]);
|
||||
log_infof("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]);
|
||||
log_infof("process: [%I64u]\n", ev->process.u64[0]);
|
||||
log_infof("thread: [%I64u]\n", ev->thread.u64[0]);
|
||||
log_infof("module: [%I64u]\n", ev->module.u64[0]);
|
||||
log_infof("arch: %S\n", string_from_architecture(ev->arch));
|
||||
log_infof("address: 0x%I64x\n", ev->address);
|
||||
log_infof("string: \"%S\"\n", ev->string);
|
||||
log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer);
|
||||
}
|
||||
|
||||
// rjf: determine if we should filter
|
||||
@@ -2104,9 +2115,9 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
// rjf: run for new events
|
||||
ProfScope("run for new events")
|
||||
{
|
||||
CTRL_CtrlThreadLogScope log_msgf("{dmn_ctrl_run ...");
|
||||
CTRL_CtrlThreadLogScope log_infof("{dmn_ctrl_run ...");
|
||||
DMN_EventList events = dmn_ctrl_run(scratch.arena, ctrl_ctx, run_ctrls);
|
||||
CTRL_CtrlThreadLogScope log_msgf("}\n");
|
||||
CTRL_CtrlThreadLogScope log_infof("}\n");
|
||||
for(DMN_EventNode *src_n = events.first; src_n != 0; src_n = src_n->next)
|
||||
{
|
||||
DMN_EventNode *dst_n = ctrl_state->free_dmn_event_node;
|
||||
@@ -2296,17 +2307,17 @@ ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size)
|
||||
//- rjf: log flusher
|
||||
|
||||
internal void
|
||||
ctrl_thread__flush_log(String8 string)
|
||||
ctrl_thread__flush_info_log(String8 string)
|
||||
{
|
||||
os_append_data_to_file_path(ctrl_state->ctrl_thread_log_path, string);
|
||||
}
|
||||
|
||||
internal void
|
||||
ctrl_thread__end_and_flush_log(void)
|
||||
ctrl_thread__end_and_flush_info_log(void)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 log = log_scope_end(scratch.arena);
|
||||
ctrl_thread__flush_log(log);
|
||||
LogScopeResult log = log_scope_end(scratch.arena);
|
||||
ctrl_thread__flush_info_log(log.strings[LogMsgKind_Info]);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -2752,25 +2763,25 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
case DMN_EventKind_Trap:
|
||||
{
|
||||
hard_stop = 1;
|
||||
log_msgf(">>> stepping >>> hard stop\n");
|
||||
log_infof(">>> stepping >>> hard stop\n");
|
||||
}break;
|
||||
case DMN_EventKind_Exception:
|
||||
case DMN_EventKind_Breakpoint:
|
||||
{
|
||||
use_stepping_logic = 1;
|
||||
log_msgf(">>> stepping >>> exception or breakpoint - begin stepping logic\n");
|
||||
log_infof(">>> stepping >>> exception or breakpoint - begin stepping logic\n");
|
||||
}break;
|
||||
case DMN_EventKind_CreateProcess:
|
||||
{
|
||||
DMN_TrapChunkList new_traps = {0};
|
||||
ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, CTRL_MachineID_Local, event->process, &msg->user_bps, &new_traps);
|
||||
log_msgf(">>> stepping >>> create process -> resolve new BPs\n");
|
||||
log_infof(">>> stepping >>> create process -> resolve new BPs\n");
|
||||
for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next)
|
||||
{
|
||||
for(U64 idx = 0; idx < n->count; idx += 1)
|
||||
{
|
||||
DMN_Trap *trap = &n->v[idx];
|
||||
log_msgf(" trap: {process:%I64d, vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr);
|
||||
log_infof(" trap: {process:%I64d, vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr);
|
||||
}
|
||||
}
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps);
|
||||
@@ -2782,7 +2793,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, CTRL_MachineID_Local, event->process, event->module, &msg->user_bps, &new_traps);
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps);
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps);
|
||||
log_msgf(">>> stepping >>> load module -> resolve new BPs\n");
|
||||
log_infof(">>> stepping >>> load module -> resolve new BPs\n");
|
||||
}break;
|
||||
}
|
||||
|
||||
@@ -3156,13 +3167,13 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
{
|
||||
hit_user_bp = 0;
|
||||
hit_conditional_bp_but_filtered = 1;
|
||||
log_msgf(">>> stepping >>> conditional breakpoint hit, but condition eval'd to 0, and so filtered\n");
|
||||
log_infof(">>> stepping >>> conditional breakpoint hit, but condition eval'd to 0, and so filtered\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
hit_user_bp = 1;
|
||||
hit_conditional_bp_but_filtered = 0;
|
||||
log_msgf(">>> stepping >>> conditional breakpoint hit\n");
|
||||
log_infof(">>> stepping >>> conditional breakpoint hit\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3183,8 +3194,8 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
}
|
||||
}
|
||||
|
||||
log_msgf(">>> stepping >>> stepping logic - BP event -> hit_user_bp: %i\n", hit_user_bp);
|
||||
log_msgf(">>> stepping >>> stepping logic - BP event -> hit_entry: %i\n", hit_entry);
|
||||
log_infof(">>> stepping >>> stepping logic - BP event -> hit_user_bp: %i\n", hit_user_bp);
|
||||
log_infof(">>> stepping >>> stepping logic - BP event -> hit_entry: %i\n", hit_entry);
|
||||
temp_end(temp);
|
||||
}
|
||||
}
|
||||
@@ -3418,7 +3429,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
{
|
||||
stage_stop_cause = CTRL_EventCause_Finished;
|
||||
}
|
||||
log_msgf(">>> stepping >>> stage stop cause -> %i\n", stage_stop_cause);
|
||||
log_infof(">>> stepping >>> stage stop cause -> %i\n", stage_stop_cause);
|
||||
if(stage_stop_cause != CTRL_EventCause_Null)
|
||||
{
|
||||
stop_event = event;
|
||||
|
||||
@@ -556,7 +556,7 @@ read_only global CTRL_Entity ctrl_entity_nil =
|
||||
////////////////////////////////
|
||||
//~ rjf: Logging Markup
|
||||
|
||||
#define CTRL_CtrlThreadLogScope DeferLoop(log_scope_begin(), ctrl_thread__end_and_flush_log())
|
||||
#define CTRL_CtrlThreadLogScope DeferLoop(log_scope_begin(), ctrl_thread__end_and_flush_info_log())
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Type Functions
|
||||
@@ -716,8 +716,8 @@ internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_
|
||||
internal B32 ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size);
|
||||
|
||||
//- rjf: log flusher
|
||||
internal void ctrl_thread__flush_log(String8 string);
|
||||
internal void ctrl_thread__end_and_flush_log(void);
|
||||
internal void ctrl_thread__flush_info_log(String8 string);
|
||||
internal void ctrl_thread__end_and_flush_info_log(void);
|
||||
|
||||
//- rjf: msg kind implementations
|
||||
internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
|
||||
|
||||
@@ -440,7 +440,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
U64 jump_dst_vaddr = rel_voff;
|
||||
|
||||
// rjf: push strings derived from voff -> line info
|
||||
if(params.style_flags & DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines)
|
||||
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines))
|
||||
{
|
||||
if(dbgi != &dbgi_parse_nil)
|
||||
{
|
||||
|
||||
@@ -1205,7 +1205,7 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_LaunchOptions *options)
|
||||
IsWow64Process(process_info.hProcess, &is_wow);
|
||||
if(is_wow)
|
||||
{
|
||||
MessageBox(0, "Sorry, The RAD Debugger only debugs 64-bit applications currently.", "Process error", MB_OK|MB_ICONSTOP);
|
||||
log_user_errorf("Only 64-bit applications can be debugged currently.");
|
||||
DebugActiveProcessStop(process_info.dwProcessId);
|
||||
TerminateProcess(process_info.hProcess,0xffffffff);
|
||||
}
|
||||
@@ -1242,6 +1242,23 @@ dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid)
|
||||
{
|
||||
result = 1;
|
||||
dmn_w32_shared->new_process_pending = 1;
|
||||
|
||||
#if 0
|
||||
// TODO(rjf): JIT debugging info
|
||||
{
|
||||
typedef struct JIT_DEBUG_INFO JIT_DEBUG_INFO;
|
||||
struct JIT_DEBUG_INFO
|
||||
{
|
||||
DWORD dwSize;
|
||||
DWORD dwProcessorArchitecture;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwReserved0;
|
||||
ULONG64 lpExceptionAddress;
|
||||
ULONG64 lpExceptionRecord;
|
||||
ULONG64 lpContextRecord;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1732,6 +1749,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
{
|
||||
switch(child->kind)
|
||||
{
|
||||
default:{}break;
|
||||
case DMN_W32_EntityKind_Thread:
|
||||
{
|
||||
DMN_Event *e = dmn_event_list_push(arena, &events);
|
||||
|
||||
+48
-17
@@ -1799,7 +1799,7 @@ df_entity_alloc(DF_StateDeltaHistory *hist, DF_Entity *parent, DF_EntityKind kin
|
||||
df_entity_notify_mutation(entity);
|
||||
|
||||
// rjf: log
|
||||
log_msgf("new entity: %S $%I64d\n", df_g_entity_kind_display_string_table[kind], entity->id);
|
||||
log_infof("new entity: %S $%I64d\n", df_g_entity_kind_display_string_table[kind], entity->id);
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -1844,7 +1844,7 @@ df_entity_release(DF_StateDeltaHistory *hist, DF_Entity *entity)
|
||||
t->e = child;
|
||||
SLLQueuePush(first_task, last_task, t);
|
||||
}
|
||||
log_msgf("end entity: %S $%I64d\n", df_g_entity_kind_display_string_table[task->e->kind], task->e->id);
|
||||
log_infof("end entity: %S $%I64d\n", df_g_entity_kind_display_string_table[task->e->kind], task->e->id);
|
||||
df_state_delta_history_push_struct_delta(hist, &task->e->first);
|
||||
df_state_delta_history_push_struct_delta(hist, &task->e->last);
|
||||
df_state_delta_history_push_struct_delta(hist, &task->e->next);
|
||||
@@ -6457,8 +6457,8 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_Entity *entity = df_entity_from_handle(params->entity);
|
||||
log_msgf("debug frontend command pushed: \"%S\"\n", spec->info.string);
|
||||
#define HandleParamPrint(mem_name) if(!df_handle_match(df_handle_zero(), params->mem_name)) { log_msgf("| %s: [0x%I64x, 0x%I64x]\n", #mem_name, params->mem_name.u64[0], params->mem_name.u64[1]); }
|
||||
log_infof("debug frontend command pushed: \"%S\"\n", spec->info.string);
|
||||
#define HandleParamPrint(mem_name) if(!df_handle_match(df_handle_zero(), params->mem_name)) { log_infof("| %s: [0x%I64x, 0x%I64x]\n", #mem_name, params->mem_name.u64[0], params->mem_name.u64[1]); }
|
||||
HandleParamPrint(window);
|
||||
HandleParamPrint(panel);
|
||||
HandleParamPrint(dest_panel);
|
||||
@@ -6467,7 +6467,7 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
if(!df_entity_is_nil(entity))
|
||||
{
|
||||
String8 entity_name = df_display_string_from_entity(scratch.arena, entity);
|
||||
log_msgf("| entity: \"%S\"\n", entity_name);
|
||||
log_infof("| entity: \"%S\"\n", entity_name);
|
||||
}
|
||||
U64 idx = 0;
|
||||
for(DF_HandleNode *n = params->entity_list.first; n != 0; n = n->next, idx += 1)
|
||||
@@ -6476,22 +6476,40 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
if(!df_entity_is_nil(entity))
|
||||
{
|
||||
String8 entity_name = df_display_string_from_entity(scratch.arena, entity);
|
||||
log_msgf("| entity_list[%I64u]: \"%S\"\n", idx, entity_name);
|
||||
log_infof("| entity_list[%I64u]: \"%S\"\n", idx, entity_name);
|
||||
}
|
||||
}
|
||||
if(!df_cmd_spec_is_nil(params->cmd_spec))
|
||||
{
|
||||
log_msgf("| cmd_spec: \"%S\"\n", params->cmd_spec->info.string);
|
||||
log_infof("| cmd_spec: \"%S\"\n", params->cmd_spec->info.string);
|
||||
}
|
||||
if(params->string.size != 0) { log_infof("| string: \"%S\"\n", params->string); }
|
||||
if(params->file_path.size != 0) { log_infof("| file_path: \"%S\"\n", params->file_path); }
|
||||
if(params->text_point.line != 0){ log_infof("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); }
|
||||
if(params->vaddr != 0) { log_infof("| vaddr: 0x%I64x\n", params->vaddr); }
|
||||
if(params->voff != 0) { log_infof("| voff: 0x%I64x\n", params->voff); }
|
||||
if(params->index != 0) { log_infof("| index: 0x%I64x\n", params->index); }
|
||||
if(params->id != 0) { log_infof("| id: 0x%I64x\n", params->id); }
|
||||
if(params->os_event != 0)
|
||||
{
|
||||
String8 kind_string = str8_lit("<unknown>");
|
||||
switch(params->os_event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
case OS_EventKind_Press: {kind_string = str8_lit("press");}break;
|
||||
case OS_EventKind_Release: {kind_string = str8_lit("release");}break;
|
||||
case OS_EventKind_MouseMove: {kind_string = str8_lit("mousemove");}break;
|
||||
case OS_EventKind_Text: {kind_string = str8_lit("text");}break;
|
||||
case OS_EventKind_Scroll: {kind_string = str8_lit("scroll");}break;
|
||||
case OS_EventKind_WindowLoseFocus:{kind_string = str8_lit("losefocus");}break;
|
||||
case OS_EventKind_WindowClose: {kind_string = str8_lit("closewindow");}break;
|
||||
case OS_EventKind_FileDrop: {kind_string = str8_lit("filedrop");}break;
|
||||
case OS_EventKind_Wakeup: {kind_string = str8_lit("wakeup");}break;
|
||||
}
|
||||
log_infof("| os_event->kind: %S\n", kind_string);
|
||||
}
|
||||
if(params->string.size != 0) { log_msgf("| string: \"%S\"\n", params->string); }
|
||||
if(params->file_path.size != 0) { log_msgf("| file_path: \"%S\"\n", params->file_path); }
|
||||
if(params->text_point.line != 0){ log_msgf("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); }
|
||||
if(params->vaddr != 0) { log_msgf("| vaddr: 0x%I64x\n", params->vaddr); }
|
||||
if(params->voff != 0) { log_msgf("| voff: 0x%I64x\n", params->voff); }
|
||||
if(params->index != 0) { log_msgf("| index: 0x%I64x\n", params->index); }
|
||||
if(params->id != 0) { log_msgf("| id: 0x%I64x\n", params->id); }
|
||||
#undef HandleParamPrint
|
||||
log_msgf("--------------------------------\n");
|
||||
log_infof("--------------------------------\n");
|
||||
scratch_end(scratch);
|
||||
}
|
||||
df_cmd_list_push(df_state->root_cmd_arena, &df_state->root_cmds, params, spec);
|
||||
@@ -6685,6 +6703,13 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
{
|
||||
default:{}break;
|
||||
|
||||
//- rjf: errors
|
||||
|
||||
case CTRL_EventKind_Error:
|
||||
{
|
||||
log_user_error(event->string);
|
||||
}break;
|
||||
|
||||
//- rjf: starts/stops
|
||||
|
||||
case CTRL_EventKind_Started:
|
||||
@@ -7204,6 +7229,10 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
String8 args = df_entity_child_from_kind(target, DF_EntityKind_Arguments)->name;
|
||||
String8 path = df_entity_child_from_kind(target, DF_EntityKind_ExecutionPath)->name;
|
||||
String8 entry= df_entity_child_from_kind(target, DF_EntityKind_EntryPointName)->name;
|
||||
name = str8_skip_chop_whitespace(name);
|
||||
args = str8_skip_chop_whitespace(args);
|
||||
path = str8_skip_chop_whitespace(path);
|
||||
entry = str8_skip_chop_whitespace(entry);
|
||||
if(path.size == 0)
|
||||
{
|
||||
String8List current_path_strs = {0};
|
||||
@@ -8691,9 +8720,11 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
case DF_CoreCmdKind_RegisterAsJITDebugger:
|
||||
{
|
||||
#if OS_WINDOWS
|
||||
String8 path_to_debugger_binary = os_string_from_system_path(scratch.arena, OS_SystemPath_Binary);
|
||||
char filename_cstr[MAX_PATH] = {0};
|
||||
GetModuleFileName(0, filename_cstr, sizeof(filename_cstr));
|
||||
String8 debugger_binary_path = str8_cstring(filename_cstr);
|
||||
String8 name8 = str8_lit("Debugger");
|
||||
String8 data8 = push_str8f(scratch.arena, "%S --jit_pid:%%ld --jit_code:%%ld --jit_addr:0x%%p", path_to_debugger_binary);
|
||||
String8 data8 = push_str8f(scratch.arena, "%S --jit_pid:%%ld --jit_code:%%ld --jit_addr:0x%%p", debugger_binary_path);
|
||||
String16 name16 = str16_from_8(scratch.arena, name8);
|
||||
String16 data16 = str16_from_8(scratch.arena, data8);
|
||||
B32 likely_not_in_admin_mode = 0;
|
||||
|
||||
@@ -354,6 +354,7 @@ struct DF_CoreViewRuleSpecInfo
|
||||
{
|
||||
String8 string;
|
||||
String8 display_string;
|
||||
String8 schema;
|
||||
String8 description;
|
||||
DF_CoreViewRuleSpecInfoFlags flags;
|
||||
DF_CoreViewRuleEvalResolutionHookFunctionType *eval_resolution;
|
||||
|
||||
+32
-21
@@ -89,6 +89,7 @@ DF_CmdParamSlotTable:
|
||||
{CmdSpec cmd_spec `struct DF_CmdSpec *`}
|
||||
{ViewSpec view_spec `struct DF_ViewSpec *`}
|
||||
{CfgNode cfg_node `struct DF_CfgNode *`}
|
||||
{OSEvent os_event `struct OS_Event *`}
|
||||
{VirtualAddr vaddr `U64`}
|
||||
{VirtualOff voff `U64`}
|
||||
{Index index `U64`}
|
||||
@@ -114,6 +115,9 @@ DF_CoreCmdTable:// | | |
|
||||
//- rjf: notifications
|
||||
{Error 1 Null Nil 0 0 0 0 0 0 Null "error" "Error" "Notifies of an error." "" }
|
||||
|
||||
//- rjf: os event passthrough
|
||||
{OSEvent 1 Null Nil 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" }
|
||||
|
||||
//- rjf: low-level target control operations
|
||||
{LaunchAndRun 0 EntityList Target 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" }
|
||||
{LaunchAndInit 0 EntityList Target 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" }
|
||||
@@ -247,6 +251,11 @@ DF_CoreCmdTable:// | | |
|
||||
{WriteUserData 1 Null Nil 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" }
|
||||
{WriteProfileData 1 Null Nil 0 0 0 0 0 0 Null "write_profile_data" "Write Profile Data" "Writes profile data to the active profile file." "" }
|
||||
|
||||
//- rjf: meta controls
|
||||
{Edit 0 Null Nil 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" }
|
||||
{Accept 0 Null Nil 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" }
|
||||
{Cancel 0 Null Nil 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" }
|
||||
|
||||
//- rjf: directional movement & text controls
|
||||
{MoveLeft 0 Null Nil 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" }
|
||||
{MoveRight 0 Null Nil 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" }
|
||||
@@ -272,6 +281,8 @@ DF_CoreCmdTable:// | | |
|
||||
{MoveDownPageSelect 0 Null Nil 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" }
|
||||
{MoveUpWholeSelect 0 Null Nil 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" }
|
||||
{MoveDownWholeSelect 0 Null Nil 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" }
|
||||
{MoveUpReorder 0 Null Nil 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" }
|
||||
{MoveDownReorder 0 Null Nil 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" }
|
||||
{MoveHome 0 Null Nil 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" }
|
||||
{MoveEnd 0 Null Nil 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" }
|
||||
{MoveHomeSelect 0 Null Nil 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" }
|
||||
@@ -493,28 +504,28 @@ DF_CoreCmdTable:// | | |
|
||||
// For any view rules in this layer which also have graphical features, they
|
||||
// are specified in both tables under the same name.
|
||||
|
||||
@table(name name_lower string ih ex er vb display_name docs description)
|
||||
@table(name name_lower string ih ex er vb display_name docs schema description)
|
||||
DF_CoreViewRuleTable:
|
||||
{
|
||||
{Null null "" - - - - "" - "" }
|
||||
{Array array "array" - - x - "Array" x "Specifies that a pointer points to N elements, rather than only 1." }
|
||||
{Slice slice "slice" - - x - "Slice" x "Specifies that a struct to be rendered as a slice." }
|
||||
{List list "list" - - - x "List" x "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." }
|
||||
{ByteSwap bswap "bswap" x - x - "Byte Swap" x "Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed." }
|
||||
{BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "Specifies that all integral evaluations should appear in base-10 form." }
|
||||
{BaseBin base_bin "bin" x - - - "Binary Base (Base 2)" x "Specifies that all integral evaluations should appear in base-2 form." }
|
||||
{BaseOct base_oct "oct" x - - - "Octal Base (Base 8)" x "Specifies that all integral evaluations should appear in base-8 form." }
|
||||
{BaseHex base_hex "hex" x - - - "Hexadecimal Base (Base 16)" x "Specifies that all integral evaluations should appear in base-16 form." }
|
||||
{Only only "only" x - - x "Only Specified Members" x "Specifies that only the specified members should appear in struct, union, or class evaluations." }
|
||||
{Omit omit "omit" x - - x "Omit Specified Members" x "Omits a list of member names from appearing in struct, union, or class evaluations." }
|
||||
{NoAddr no_addr "no_addr" x - - - "Disable Address Values" x "Displays only what pointers point to, if possible, without the pointer's address value." }
|
||||
{RGBA rgba "rgba" - x - x "Color (RGBA)" x "Displays as a color, interpreting the data as encoding R, G, B, and A values." }
|
||||
{Text text "text" - x - x "Text" x "Displays as text." }
|
||||
{Disasm disasm "disasm" - x - x "Disassembly" x "Displays as disassembled instructions, interpreting the data as raw machine code." }
|
||||
{Graph graph "graph" - x - x "Graph" x "Displays as a pointer graph, visualizing nodes and edges formed by pointers directly." }
|
||||
{Bitmap bitmap "bitmap" - x - x "Bitmap" x "Displays as a bitmap, interpreting the data as raw pixel data." }
|
||||
{Geo geo "geo" - x - x "Geometry" x "Displays as geometry, interpreting the data as vertex data." }
|
||||
{OdinMap odin_map "odin_map" - x - x "Odin map" x "Specifies that a struct to be rendered as an Odin map type." }
|
||||
{Null null "" - - - - "" - "" "" }
|
||||
{Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." }
|
||||
{Slice slice "slice" - - x - "Slice" x "" "Specifies a struct of {data, len} should be rendered as a slice." }
|
||||
{List list "list" - - - x "List" x "x:{member}" "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." }
|
||||
{ByteSwap bswap "bswap" x - x - "Byte Swap" x "" "Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed." }
|
||||
{BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "" "Specifies that all integral evaluations should appear in base-10 form." }
|
||||
{BaseBin base_bin "bin" x - - - "Binary Base (Base 2)" x "" "Specifies that all integral evaluations should appear in base-2 form." }
|
||||
{BaseOct base_oct "oct" x - - - "Octal Base (Base 8)" x "" "Specifies that all integral evaluations should appear in base-8 form." }
|
||||
{BaseHex base_hex "hex" x - - - "Hexadecimal Base (Base 16)" x "" "Specifies that all integral evaluations should appear in base-16 form." }
|
||||
{Only only "only" x - - x "Only Specified Members" x "x:{member}" "Specifies that only the specified members should appear in struct, union, or class evaluations." }
|
||||
{Omit omit "omit" x - - x "Omit Specified Members" x "x:{member}" "Omits a list of member names from appearing in struct, union, or class evaluations." }
|
||||
{NoAddr no_addr "no_addr" x - - - "Disable Address Values" x "" "Displays only what pointers point to, if possible, without the pointer's address value." }
|
||||
{RGBA rgba "rgba" - x - x "Color (RGBA)" x "" "Displays as a color, interpreting the data as encoding R, G, B, and A values." }
|
||||
{Text text "text" - x - x "Text" x "x:{'lang':lang, 'size':expr}" "Displays as text." }
|
||||
{Disasm disasm "disasm" - x - x "Disassembly" x "x:{'arch':arch, 'size':expr}" "Displays as disassembled instructions, interpreting the data as raw machine code." }
|
||||
{Graph graph "graph" - x - x "Graph" x "" "Displays as a pointer graph, visualizing nodes and edges formed by pointers directly." }
|
||||
{Bitmap bitmap "bitmap" - x - x "Bitmap" x "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" "Displays as a bitmap, interpreting the data as raw pixel data." }
|
||||
{Geo geo "geo" - x - x "Geometry" x "x:{'count':expr, 'vertices_base':expr, 'vertices_size':expr}" "Displays as geometry, interpreting the data as vertex data." }
|
||||
{OdinMap odin_map "odin_map" - x - x "Odin map" x "" "Specifies that a struct should be rendered as an Odin map type." }
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -1823,7 +1834,7 @@ DF_DevToggleTable:
|
||||
@data(DF_CoreViewRuleSpecInfo) @c_file df_g_core_view_rule_spec_info_table:
|
||||
{
|
||||
@expand(DF_CoreViewRuleTable a)
|
||||
```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.description)"), (DF_CoreViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(DF_CoreViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*$(a.er == "x"))|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), $(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.er != "x" -> 0), $(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vb != "x" -> 0), }```;
|
||||
```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.description)"), (DF_CoreViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(DF_CoreViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*$(a.er == "x"))|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), $(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.er != "x" -> 0), $(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vb != "x" -> 0), }```;
|
||||
}
|
||||
|
||||
//- rjf: icon kinds
|
||||
|
||||
@@ -53,6 +53,7 @@ DF_CoreCmdKind_Null,
|
||||
DF_CoreCmdKind_Exit,
|
||||
DF_CoreCmdKind_RunCommand,
|
||||
DF_CoreCmdKind_Error,
|
||||
DF_CoreCmdKind_OSEvent,
|
||||
DF_CoreCmdKind_LaunchAndRun,
|
||||
DF_CoreCmdKind_LaunchAndInit,
|
||||
DF_CoreCmdKind_Kill,
|
||||
@@ -146,6 +147,9 @@ DF_CoreCmdKind_ApplyUserData,
|
||||
DF_CoreCmdKind_ApplyProfileData,
|
||||
DF_CoreCmdKind_WriteUserData,
|
||||
DF_CoreCmdKind_WriteProfileData,
|
||||
DF_CoreCmdKind_Edit,
|
||||
DF_CoreCmdKind_Accept,
|
||||
DF_CoreCmdKind_Cancel,
|
||||
DF_CoreCmdKind_MoveLeft,
|
||||
DF_CoreCmdKind_MoveRight,
|
||||
DF_CoreCmdKind_MoveUp,
|
||||
@@ -170,6 +174,8 @@ DF_CoreCmdKind_MoveUpPageSelect,
|
||||
DF_CoreCmdKind_MoveDownPageSelect,
|
||||
DF_CoreCmdKind_MoveUpWholeSelect,
|
||||
DF_CoreCmdKind_MoveDownWholeSelect,
|
||||
DF_CoreCmdKind_MoveUpReorder,
|
||||
DF_CoreCmdKind_MoveDownReorder,
|
||||
DF_CoreCmdKind_MoveHome,
|
||||
DF_CoreCmdKind_MoveEnd,
|
||||
DF_CoreCmdKind_MoveHomeSelect,
|
||||
@@ -380,6 +386,7 @@ DF_CmdParamSlot_TextPoint,
|
||||
DF_CmdParamSlot_CmdSpec,
|
||||
DF_CmdParamSlot_ViewSpec,
|
||||
DF_CmdParamSlot_CfgNode,
|
||||
DF_CmdParamSlot_OSEvent,
|
||||
DF_CmdParamSlot_VirtualAddr,
|
||||
DF_CmdParamSlot_VirtualOff,
|
||||
DF_CmdParamSlot_Index,
|
||||
@@ -407,6 +414,7 @@ TxtPt text_point;
|
||||
struct DF_CmdSpec * cmd_spec;
|
||||
struct DF_ViewSpec * view_spec;
|
||||
struct DF_CfgNode * cfg_node;
|
||||
struct OS_Event * os_event;
|
||||
U64 vaddr;
|
||||
U64 voff;
|
||||
U64 index;
|
||||
@@ -1526,7 +1534,7 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
|
||||
{&DEV_updating_indicator, str8_lit_comp("updating_indicator")},
|
||||
};
|
||||
C_LINKAGE_BEGIN
|
||||
extern Rng1U64 df_g_cmd_param_slot_range_table[21];
|
||||
extern Rng1U64 df_g_cmd_param_slot_range_table[22];
|
||||
extern DF_IconKind df_g_entity_kind_icon_kind_table[27];
|
||||
extern String8 df_g_entity_kind_display_string_table[27];
|
||||
extern String8 df_g_entity_kind_name_label_table[27];
|
||||
|
||||
+810
-180
File diff suppressed because it is too large
Load Diff
+33
-7
@@ -108,13 +108,21 @@ enum
|
||||
DF_ViewSpecFlag_TypingAutomaticallyFilters = (1<<6),
|
||||
};
|
||||
|
||||
typedef enum DF_NameKind
|
||||
{
|
||||
DF_NameKind_Null,
|
||||
DF_NameKind_EntityName,
|
||||
DF_NameKind_COUNT
|
||||
}
|
||||
DF_NameKind;
|
||||
|
||||
typedef struct DF_ViewSpecInfo DF_ViewSpecInfo;
|
||||
struct DF_ViewSpecInfo
|
||||
{
|
||||
DF_ViewSpecFlags flags;
|
||||
String8 name;
|
||||
String8 display_string;
|
||||
enum DF_NameKind name_kind;
|
||||
DF_NameKind name_kind;
|
||||
DF_IconKind icon_kind;
|
||||
DF_ViewSetupFunctionType *setup_hook;
|
||||
DF_ViewStringFromStateFunctionType *string_from_state_hook;
|
||||
@@ -408,6 +416,7 @@ struct DF_CodeSliceParams
|
||||
F32 line_num_width_px;
|
||||
F32 line_text_max_width_px;
|
||||
DF_EntityList flash_ranges;
|
||||
F32 margin_float_off_px;
|
||||
};
|
||||
|
||||
typedef struct DF_CodeSliceSignal DF_CodeSliceSignal;
|
||||
@@ -434,9 +443,14 @@ struct DF_CodeSliceSignal
|
||||
typedef U32 DF_AutoCompListerFlags;
|
||||
enum
|
||||
{
|
||||
DF_AutoCompListerFlag_Locals = (1<<0),
|
||||
DF_AutoCompListerFlag_Registers = (1<<1),
|
||||
DF_AutoCompListerFlag_ViewRules = (1<<2),
|
||||
DF_AutoCompListerFlag_Locals = (1<<0),
|
||||
DF_AutoCompListerFlag_Registers = (1<<1),
|
||||
DF_AutoCompListerFlag_ViewRules = (1<<2),
|
||||
DF_AutoCompListerFlag_ViewRuleParams= (1<<3),
|
||||
DF_AutoCompListerFlag_Members = (1<<4),
|
||||
DF_AutoCompListerFlag_Languages = (1<<5),
|
||||
DF_AutoCompListerFlag_Architectures = (1<<6),
|
||||
DF_AutoCompListerFlag_Tex2DFormats = (1<<7),
|
||||
};
|
||||
|
||||
typedef struct DF_AutoCompListerItem DF_AutoCompListerItem;
|
||||
@@ -472,6 +486,13 @@ struct DF_AutoCompListerItemArray
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DF_AutoCompListerParams DF_AutoCompListerParams;
|
||||
struct DF_AutoCompListerParams
|
||||
{
|
||||
DF_AutoCompListerFlags flags;
|
||||
String8List strings;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Per-Window State
|
||||
|
||||
@@ -517,9 +538,12 @@ struct DF_Window
|
||||
// rjf: autocomplete lister state
|
||||
U64 autocomp_last_frame_idx;
|
||||
B32 autocomp_force_closed;
|
||||
B32 autocomp_query_dirty;
|
||||
UI_Key autocomp_root_key;
|
||||
DF_CtrlCtx autocomp_ctrl_ctx;
|
||||
DF_AutoCompListerFlags autocomp_lister_flags;
|
||||
Arena *autocomp_lister_params_arena;
|
||||
DF_AutoCompListerParams autocomp_lister_params;
|
||||
U64 autocomp_cursor_off;
|
||||
U8 autocomp_lister_query_buffer[1024];
|
||||
U64 autocomp_lister_query_size;
|
||||
F32 autocomp_open_t;
|
||||
@@ -899,7 +923,7 @@ internal DF_Window *df_window_open(Vec2F32 size, OS_Handle preferred_monitor, DF
|
||||
|
||||
internal DF_Window *df_window_from_os_handle(OS_Handle os);
|
||||
|
||||
internal void df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, DF_CmdList *cmds);
|
||||
internal void df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Eval Viz
|
||||
@@ -921,7 +945,9 @@ internal DF_AutoCompListerItemArray df_autocomp_lister_item_array_from_chunk_lis
|
||||
internal int df_autocomp_lister_item_qsort_compare(DF_AutoCompListerItem *a, DF_AutoCompListerItem *b);
|
||||
internal void df_autocomp_lister_item_array_sort__in_place(DF_AutoCompListerItemArray *array);
|
||||
|
||||
internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerFlags flags, String8 query);
|
||||
internal String8 df_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off);
|
||||
internal DF_AutoCompListerParams df_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off);
|
||||
internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_CtrlCtx ctrl_ctx, DF_AutoCompListerParams *params, String8 input, U64 cursor_off);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Search Strings
|
||||
|
||||
+9
-13
@@ -90,6 +90,11 @@ DF_DefaultBindingTable:
|
||||
{ "load_user" O ctrl shift alt }
|
||||
{ "load_profile" O ctrl 0 alt }
|
||||
|
||||
//- rjf: meta controls
|
||||
{ "edit" F2 0 0 0 }
|
||||
{ "accept" Return 0 0 0 }
|
||||
{ "cancel" Esc 0 0 0 }
|
||||
|
||||
//- rjf: directional movement & text controls
|
||||
{ "move_left" Left 0 0 0 }
|
||||
{ "move_right" Right 0 0 0 }
|
||||
@@ -115,6 +120,8 @@ DF_DefaultBindingTable:
|
||||
{ "move_down_page_select" PageDown 0 shift 0 }
|
||||
{ "move_up_whole_select" Home ctrl shift 0 }
|
||||
{ "move_down_whole_select" End ctrl shift 0 }
|
||||
{ "move_up_reorder" Up 0 0 alt }
|
||||
{ "move_down_reorder" Down 0 0 alt }
|
||||
{ "move_home" Home 0 0 0 }
|
||||
{ "move_end" End 0 0 0 }
|
||||
{ "move_home_select" Home 0 shift 0 }
|
||||
@@ -125,8 +132,10 @@ DF_DefaultBindingTable:
|
||||
{ "backspace_single" Backspace 0 0 0 }
|
||||
{ "backspace_chunk" Backspace ctrl 0 0 }
|
||||
{ "copy" C ctrl 0 0 }
|
||||
{ "copy" Insert ctrl 0 0 }
|
||||
{ "cut" X ctrl 0 0 }
|
||||
{ "paste" V ctrl 0 0 }
|
||||
{ "paste" Insert 0 shift 0 }
|
||||
{ "insert_text" Null 0 0 0 }
|
||||
|
||||
//- rjf: code navigation
|
||||
@@ -178,13 +187,6 @@ DF_BindingVersionRemapTable:
|
||||
////////////////////////////////
|
||||
//~ rjf: Gfx Layer View Kinds
|
||||
|
||||
@table(name)
|
||||
DF_NameKindTable:
|
||||
{
|
||||
{Null}
|
||||
{EntityName}
|
||||
}
|
||||
|
||||
@table(name, name_lower, display_string, name_kind, icon, parameterized_by_entity, can_serialize, can_serialize_entity_path, can_filter, filter_is_code, typing_automatically_filters, inc_in_docs, docs_desc)
|
||||
DF_GfxViewTable:
|
||||
{
|
||||
@@ -414,12 +416,6 @@ DF_ThemePresetColorTable:
|
||||
|
||||
//- rjf: enums
|
||||
|
||||
@enum DF_NameKind:
|
||||
{
|
||||
@expand(DF_NameKindTable, a) `$(a.name)`,
|
||||
COUNT,
|
||||
}
|
||||
|
||||
@enum DF_GfxViewKind:
|
||||
{
|
||||
@expand(DF_GfxViewTable a) `$(a.name)`,
|
||||
|
||||
+956
-455
File diff suppressed because it is too large
Load Diff
+66
-40
@@ -281,55 +281,70 @@ struct DF_EvalRoot
|
||||
U8 *expr_buffer;
|
||||
};
|
||||
|
||||
typedef enum DF_EvalWatchViewColumnKind
|
||||
typedef enum DF_WatchViewColumnKind
|
||||
{
|
||||
DF_EvalWatchViewColumnKind_Expr,
|
||||
DF_EvalWatchViewColumnKind_Value,
|
||||
DF_EvalWatchViewColumnKind_Type,
|
||||
DF_EvalWatchViewColumnKind_ViewRule,
|
||||
DF_EvalWatchViewColumnKind_COUNT
|
||||
DF_WatchViewColumnKind_Expr,
|
||||
DF_WatchViewColumnKind_Value,
|
||||
DF_WatchViewColumnKind_Type,
|
||||
DF_WatchViewColumnKind_ViewRule,
|
||||
DF_WatchViewColumnKind_COUNT
|
||||
}
|
||||
DF_EvalWatchViewColumnKind;
|
||||
DF_WatchViewColumnKind;
|
||||
|
||||
typedef enum DF_EvalWatchViewFillKind
|
||||
typedef enum DF_WatchViewFillKind
|
||||
{
|
||||
DF_EvalWatchViewFillKind_Mutable,
|
||||
DF_EvalWatchViewFillKind_Registers,
|
||||
DF_EvalWatchViewFillKind_Locals,
|
||||
DF_EvalWatchViewFillKind_Globals,
|
||||
DF_EvalWatchViewFillKind_ThreadLocals,
|
||||
DF_EvalWatchViewFillKind_Types,
|
||||
DF_EvalWatchViewFillKind_Procedures,
|
||||
DF_EvalWatchViewFillKind_COUNT
|
||||
DF_WatchViewFillKind_Mutable,
|
||||
DF_WatchViewFillKind_Registers,
|
||||
DF_WatchViewFillKind_Locals,
|
||||
DF_WatchViewFillKind_Globals,
|
||||
DF_WatchViewFillKind_ThreadLocals,
|
||||
DF_WatchViewFillKind_Types,
|
||||
DF_WatchViewFillKind_Procedures,
|
||||
DF_WatchViewFillKind_COUNT
|
||||
}
|
||||
DF_EvalWatchViewFillKind;
|
||||
DF_WatchViewFillKind;
|
||||
|
||||
typedef struct DF_EvalWatchViewPoint DF_EvalWatchViewPoint;
|
||||
struct DF_EvalWatchViewPoint
|
||||
typedef struct DF_WatchViewPoint DF_WatchViewPoint;
|
||||
struct DF_WatchViewPoint
|
||||
{
|
||||
DF_EvalWatchViewColumnKind column_kind;
|
||||
DF_WatchViewColumnKind column_kind;
|
||||
DF_ExpandKey parent_key;
|
||||
DF_ExpandKey key;
|
||||
};
|
||||
|
||||
typedef struct DF_EvalWatchViewState DF_EvalWatchViewState;
|
||||
struct DF_EvalWatchViewState
|
||||
typedef struct DF_WatchViewTextEditState DF_WatchViewTextEditState;
|
||||
struct DF_WatchViewTextEditState
|
||||
{
|
||||
DF_WatchViewTextEditState *pt_hash_next;
|
||||
DF_WatchViewPoint pt;
|
||||
TxtPt cursor;
|
||||
TxtPt mark;
|
||||
U8 input_buffer[1024];
|
||||
U64 input_size;
|
||||
U8 initial_buffer[1024];
|
||||
U64 initial_size;
|
||||
};
|
||||
|
||||
typedef struct DF_WatchViewState DF_WatchViewState;
|
||||
struct DF_WatchViewState
|
||||
{
|
||||
B32 initialized;
|
||||
|
||||
// rjf: fill kind (way that the contents of the watch view are computed)
|
||||
DF_EvalWatchViewFillKind fill_kind;
|
||||
DF_WatchViewFillKind fill_kind;
|
||||
|
||||
// rjf; table cursor state
|
||||
DF_EvalWatchViewPoint cursor;
|
||||
DF_EvalWatchViewPoint mark;
|
||||
DF_WatchViewPoint cursor;
|
||||
DF_WatchViewPoint mark;
|
||||
DF_WatchViewPoint next_cursor;
|
||||
DF_WatchViewPoint next_mark;
|
||||
|
||||
// rjf: text input state
|
||||
TxtPt input_cursor;
|
||||
TxtPt input_mark;
|
||||
U8 input_buffer[1024];
|
||||
U64 input_size;
|
||||
B32 input_editing;
|
||||
Arena *text_edit_arena;
|
||||
U64 text_edit_state_slots_count;
|
||||
DF_WatchViewTextEditState dummy_text_edit_state;
|
||||
DF_WatchViewTextEditState **text_edit_state_slots;
|
||||
B32 text_editing;
|
||||
|
||||
// rjf: table column width state
|
||||
F32 expr_column_pct;
|
||||
@@ -454,27 +469,38 @@ internal DF_EntityListerItemArray df_entity_lister_item_array_from_list(Arena *a
|
||||
internal void df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray array);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Eval/Watch Views
|
||||
//~ rjf: Watch Views
|
||||
|
||||
//- rjf: eval watch view instance -> eval view key
|
||||
internal DF_EvalViewKey df_eval_view_key_from_eval_watch_view(DF_EvalWatchViewState *ewv);
|
||||
internal DF_EvalViewKey df_eval_view_key_from_eval_watch_view(DF_WatchViewState *ewv);
|
||||
|
||||
//- rjf: root allocation/deallocation/mutation
|
||||
internal DF_EvalRoot * df_eval_root_alloc(DF_View *view, DF_EvalWatchViewState *ews);
|
||||
internal void df_eval_root_release(DF_EvalWatchViewState *ews, DF_EvalRoot *root);
|
||||
internal DF_EvalRoot * df_eval_root_alloc(DF_View *view, DF_WatchViewState *ews);
|
||||
internal void df_eval_root_release(DF_WatchViewState *ews, DF_EvalRoot *root);
|
||||
internal void df_eval_root_equip_string(DF_EvalRoot *root, String8 string);
|
||||
internal DF_EvalRoot * df_eval_root_from_string(DF_EvalWatchViewState *ews, String8 string);
|
||||
internal DF_EvalRoot * df_eval_root_from_expand_key(DF_EvalWatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key);
|
||||
internal DF_EvalRoot * df_eval_root_from_string(DF_WatchViewState *ews, String8 string);
|
||||
internal DF_EvalRoot * df_eval_root_from_expand_key(DF_WatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key);
|
||||
internal String8 df_string_from_eval_root(DF_EvalRoot *root);
|
||||
internal DF_ExpandKey df_parent_expand_key_from_eval_root(DF_EvalRoot *root);
|
||||
internal DF_ExpandKey df_expand_key_from_eval_root(DF_EvalRoot *root);
|
||||
|
||||
//- rjf: watch view points <-> table coordinates
|
||||
internal B32 df_watch_view_point_match(DF_WatchViewPoint a, DF_WatchViewPoint b);
|
||||
internal DF_WatchViewPoint df_watch_view_point_from_tbl(DF_EvalVizBlockList *blocks, Vec2S64 tbl);
|
||||
internal Vec2S64 df_tbl_from_watch_view_point(DF_EvalVizBlockList *blocks, DF_WatchViewPoint pt);
|
||||
|
||||
//- rjf: table coordinates -> strings
|
||||
internal String8 df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalView *ev, TG_Graph *graph, RDI_Parsed *rdi, DF_EvalVizRow *row, DF_WatchViewColumnKind col_kind, B32 editable);
|
||||
|
||||
//- rjf: table coordinates -> text edit state
|
||||
internal DF_WatchViewTextEditState *df_watch_view_text_edit_state_from_pt(DF_WatchViewState *wv, DF_WatchViewPoint pt);
|
||||
|
||||
//- rjf: windowed watch tree visualization
|
||||
internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_EvalWatchViewState *ews);
|
||||
internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews);
|
||||
|
||||
//- rjf: eval/watch views main hooks
|
||||
internal void df_eval_watch_view_init(DF_EvalWatchViewState *ewv, DF_View *view, DF_EvalWatchViewFillKind fill_kind);
|
||||
internal void df_eval_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, DF_CmdList *cmds);
|
||||
internal void df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect);
|
||||
internal void df_watch_view_init(DF_WatchViewState *ewv, DF_View *view, DF_WatchViewFillKind fill_kind);
|
||||
internal void df_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, DF_CmdList *cmds);
|
||||
internal void df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect);
|
||||
|
||||
#endif // DEBUG_FRONTEND_VIEWS_H
|
||||
|
||||
@@ -598,7 +598,7 @@ str8_lit_comp("goto_name"),
|
||||
str8_lit_comp("function_breakpoint"),
|
||||
};
|
||||
|
||||
DF_StringBindingPair df_g_default_binding_table[97] =
|
||||
DF_StringBindingPair df_g_default_binding_table[104] =
|
||||
{
|
||||
{str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}},
|
||||
@@ -644,6 +644,9 @@ DF_StringBindingPair df_g_default_binding_table[97] =
|
||||
{str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("load_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("load_profile"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("edit"), {OS_Key_F2, 0 }},
|
||||
{str8_lit_comp("accept"), {OS_Key_Return, 0 }},
|
||||
{str8_lit_comp("cancel"), {OS_Key_Esc, 0 }},
|
||||
{str8_lit_comp("move_left"), {OS_Key_Left, 0 }},
|
||||
{str8_lit_comp("move_right"), {OS_Key_Right, 0 }},
|
||||
{str8_lit_comp("move_up"), {OS_Key_Up, 0 }},
|
||||
@@ -668,6 +671,8 @@ DF_StringBindingPair df_g_default_binding_table[97] =
|
||||
{str8_lit_comp("move_down_page_select"), {OS_Key_PageDown, 0 |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("move_up_whole_select"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("move_down_whole_select"), {OS_Key_End, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("move_up_reorder"), {OS_Key_Up, 0 |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("move_down_reorder"), {OS_Key_Down, 0 |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("move_home"), {OS_Key_Home, 0 }},
|
||||
{str8_lit_comp("move_end"), {OS_Key_End, 0 }},
|
||||
{str8_lit_comp("move_home_select"), {OS_Key_Home, 0 |OS_EventFlag_Shift }},
|
||||
@@ -678,8 +683,10 @@ DF_StringBindingPair df_g_default_binding_table[97] =
|
||||
{str8_lit_comp("backspace_single"), {OS_Key_Backspace, 0 }},
|
||||
{str8_lit_comp("backspace_chunk"), {OS_Key_Backspace, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("copy"), {OS_Key_C, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("copy"), {OS_Key_Insert, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("cut"), {OS_Key_X, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("paste"), {OS_Key_V, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("paste"), {OS_Key_Insert, 0 |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("insert_text"), {OS_Key_Null, 0 }},
|
||||
{str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_EventFlag_Alt}},
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
#ifndef DF_GFX_META_H
|
||||
#define DF_GFX_META_H
|
||||
|
||||
typedef enum DF_NameKind
|
||||
{
|
||||
DF_NameKind_Null,
|
||||
DF_NameKind_EntityName,
|
||||
DF_NameKind_COUNT,
|
||||
} DF_NameKind;
|
||||
|
||||
typedef enum DF_GfxViewKind
|
||||
{
|
||||
DF_GfxViewKind_Null,
|
||||
@@ -303,7 +296,7 @@ extern Vec4F32* df_g_theme_preset_colors_table[9];
|
||||
extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7];
|
||||
extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7];
|
||||
extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7];
|
||||
extern DF_StringBindingPair df_g_default_binding_table[97];
|
||||
extern DF_StringBindingPair df_g_default_binding_table[104];
|
||||
extern String8 df_g_binding_version_remap_old_name_table[3];
|
||||
extern String8 df_g_binding_version_remap_new_name_table[3];
|
||||
extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RDI_MARKUP_H
|
||||
#define RDI_MARKUP_H
|
||||
#ifndef RADDBG_MARKUP_H
|
||||
#define RADDBG_MARKUP_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ Usage Macros
|
||||
@@ -75,4 +75,4 @@ raddbg_log__impl(char *fmt, ...)
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#endif // RDI_MARKUP_H
|
||||
#endif // RADDBG_MARKUP_H
|
||||
|
||||
@@ -141,4 +141,14 @@
|
||||
# error Endianness of this architecture not understood by context cracker
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unsupported Errors
|
||||
|
||||
#if ARCH_X86
|
||||
# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported.
|
||||
#endif
|
||||
#if !ARCH_X64
|
||||
# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported.
|
||||
#endif
|
||||
|
||||
#endif // BASE_CONTEXT_CRACKING_H
|
||||
|
||||
+122
-81
@@ -11,7 +11,9 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: begin logging
|
||||
//
|
||||
if(main_thread_log == 0)
|
||||
{
|
||||
main_thread_log = log_alloc();
|
||||
@@ -24,13 +26,17 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
log_select(main_thread_log);
|
||||
log_scope_begin();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: tick cache layers
|
||||
//
|
||||
txt_user_clock_tick();
|
||||
dasm_user_clock_tick();
|
||||
geo_user_clock_tick();
|
||||
tex_user_clock_tick();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: pick target hz
|
||||
//
|
||||
// TODO(rjf): maximize target, given all windows and their monitors
|
||||
F32 target_hz = os_default_refresh_rate();
|
||||
if(frame_time_us_history_idx > 32)
|
||||
@@ -66,29 +72,41 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
target_hz = best_target_hz;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: target Hz -> delta time
|
||||
//
|
||||
F32 dt = 1.f/target_hz;
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: last frame before sleep -> disable txti change detection
|
||||
//
|
||||
if(df_gfx_state->num_frames_requested == 0)
|
||||
{
|
||||
txti_set_external_change_detection_enabled(0);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: get events from the OS
|
||||
//
|
||||
OS_EventList events = {0};
|
||||
if(os_handle_match(repaint_window_handle, os_handle_zero()))
|
||||
{
|
||||
events = os_get_events(scratch.arena, df_gfx_state->num_frames_requested == 0);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: enable txti change detection
|
||||
//
|
||||
txti_set_external_change_detection_enabled(1);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: begin measuring actual per-frame work
|
||||
//
|
||||
U64 begin_time_us = os_now_microseconds();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: bind change
|
||||
//
|
||||
if(!df_gfx_state->confirm_active && df_gfx_state->bind_change_active)
|
||||
{
|
||||
if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Esc))
|
||||
@@ -113,6 +131,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
event->key != OS_Key_Delete &&
|
||||
event->key != OS_Key_LeftMouseButton &&
|
||||
event->key != OS_Key_RightMouseButton &&
|
||||
event->key != OS_Key_MiddleMouseButton &&
|
||||
event->key != OS_Key_Ctrl &&
|
||||
event->key != OS_Key_Alt &&
|
||||
event->key != OS_Key_Shift)
|
||||
@@ -136,7 +155,10 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: take hotkeys
|
||||
//////////////////////////////
|
||||
//- rjf: consume events
|
||||
//
|
||||
B32 queue_drag_drop = 0;
|
||||
{
|
||||
for(OS_Event *event = events.first, *next = 0;
|
||||
event != 0;
|
||||
@@ -145,7 +167,63 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
next = event->next;
|
||||
DF_Window *window = df_window_from_os_handle(event->window);
|
||||
DF_CmdParams params = window ? df_cmd_params_from_window(window) : df_cmd_params_from_gfx();
|
||||
if(event->kind == OS_EventKind_Press)
|
||||
B32 take = 0;
|
||||
B32 skip = 0;
|
||||
|
||||
//- rjf: try drag-drop
|
||||
if(df_drag_is_active() && event->kind == OS_EventKind_Release && event->key == OS_Key_LeftMouseButton)
|
||||
{
|
||||
skip = 1;
|
||||
queue_drag_drop = 1;
|
||||
}
|
||||
|
||||
//- rjf: try window close
|
||||
if(!take && event->kind == OS_EventKind_WindowClose && window != 0)
|
||||
{
|
||||
take = 1;
|
||||
DF_CmdParams params = df_cmd_params_from_window(window);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CloseWindow));
|
||||
}
|
||||
|
||||
//- rjf: try menu bar operations
|
||||
{
|
||||
if(!take && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
window->menu_bar_focused_on_press = window->menu_bar_focused;
|
||||
window->menu_bar_key_held = 1;
|
||||
window->menu_bar_focus_press_started = 1;
|
||||
}
|
||||
if(!take && event->kind == OS_EventKind_Release && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
window->menu_bar_key_held = 0;
|
||||
}
|
||||
if(window->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
window->menu_bar_focused = 0;
|
||||
}
|
||||
else if(window->menu_bar_focus_press_started && !window->menu_bar_focused && event->kind == OS_EventKind_Release && event->flags == 0 && event->key == OS_Key_Alt && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
window->menu_bar_focused = !window->menu_bar_focused_on_press;
|
||||
window->menu_bar_focus_press_started = 0;
|
||||
}
|
||||
else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && window->menu_bar_focused && !ui_any_ctx_menu_is_open())
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
window->menu_bar_focused = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: try hotkey presses
|
||||
if(!take && event->kind == OS_EventKind_Press)
|
||||
{
|
||||
DF_Binding binding = {event->key, event->flags};
|
||||
DF_CmdSpecList spec_candidates = df_cmd_spec_list_from_binding(scratch.arena, binding);
|
||||
@@ -159,7 +237,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_CmdSpec);
|
||||
}
|
||||
U32 hit_char = os_codepoint_from_event_flags_and_key(event->flags, event->key);
|
||||
os_eat_event(&events, event);
|
||||
take = 1;
|
||||
df_push_cmd__root(¶ms, run_spec);
|
||||
if(event->flags & OS_EventFlag_Alt)
|
||||
{
|
||||
@@ -172,7 +250,9 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
}
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
else if(event->kind == OS_EventKind_Text)
|
||||
|
||||
//- rjf: try text events
|
||||
if(!take && event->kind == OS_EventKind_Text)
|
||||
{
|
||||
String32 insertion32 = str32(&event->character, 1);
|
||||
String8 insertion8 = str8_from_32(scratch.arena, insertion32);
|
||||
@@ -181,87 +261,51 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, spec);
|
||||
df_gfx_request_frame();
|
||||
os_eat_event(&events, event);
|
||||
take = 1;
|
||||
if(event->flags & OS_EventFlag_Alt)
|
||||
{
|
||||
window->menu_bar_focus_press_started = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: menu bar focus
|
||||
{
|
||||
for(OS_Event *event = events.first, *next = 0; event != 0; event = next)
|
||||
{
|
||||
next = event->next;
|
||||
DF_Window *ws = df_window_from_os_handle(event->window);
|
||||
if(ws == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
B32 take = 0;
|
||||
if(event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0)
|
||||
|
||||
//- rjf: do fall-through
|
||||
if(!take)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
ws->menu_bar_focused_on_press = ws->menu_bar_focused;
|
||||
ws->menu_bar_key_held = 1;
|
||||
ws->menu_bar_focus_press_started = 1;
|
||||
params.os_event = event;
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_OSEvent));
|
||||
}
|
||||
if(event->kind == OS_EventKind_Release && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
ws->menu_bar_key_held = 0;
|
||||
}
|
||||
if(ws->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->flags == 0 && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
ws->menu_bar_focused = 0;
|
||||
}
|
||||
else if(ws->menu_bar_focus_press_started && !ws->menu_bar_focused && event->kind == OS_EventKind_Release && event->flags == 0 && event->key == OS_Key_Alt && event->is_repeat == 0)
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
ws->menu_bar_focused = !ws->menu_bar_focused_on_press;
|
||||
ws->menu_bar_focus_press_started = 0;
|
||||
}
|
||||
else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && ws->menu_bar_focused && !ui_any_ctx_menu_is_open())
|
||||
{
|
||||
take = 1;
|
||||
df_gfx_request_frame();
|
||||
ws->menu_bar_focused = 0;
|
||||
}
|
||||
if(take)
|
||||
|
||||
//- rjf: take
|
||||
if(take && !skip)
|
||||
{
|
||||
os_eat_event(&events, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: gather root-level commands
|
||||
//
|
||||
DF_CmdList cmds = df_core_gather_root_cmds(scratch.arena);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: begin frame
|
||||
//
|
||||
df_core_begin_frame(scratch.arena, &cmds, dt);
|
||||
df_gfx_begin_frame(scratch.arena, &cmds);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: queue drop for drag/drop
|
||||
if(df_drag_is_active())
|
||||
//
|
||||
if(queue_drag_drop)
|
||||
{
|
||||
for(OS_Event *event = events.first; event != 0; event = event->next)
|
||||
{
|
||||
if(event->kind == OS_EventKind_Release && event->key == OS_Key_LeftMouseButton)
|
||||
{
|
||||
df_queue_drag_drop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
df_queue_drag_drop();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: auto-focus moused-over windows while dragging
|
||||
//
|
||||
if(df_drag_is_active())
|
||||
{
|
||||
B32 over_focused_window = 0;
|
||||
@@ -292,20 +336,26 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: update & render
|
||||
//
|
||||
{
|
||||
d_begin_frame();
|
||||
for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next)
|
||||
{
|
||||
df_window_update_and_render(scratch.arena, &events, w, &cmds);
|
||||
df_window_update_and_render(scratch.arena, w, &cmds);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: end frontend frame, send signals, etc.
|
||||
//
|
||||
df_gfx_end_frame();
|
||||
df_core_end_frame();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: submit rendering to all windows
|
||||
//
|
||||
{
|
||||
r_begin_frame();
|
||||
for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next)
|
||||
@@ -317,35 +367,26 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
r_end_frame();
|
||||
}
|
||||
|
||||
//- rjf: take window closing events
|
||||
for(OS_Event *e = events.first, *next = 0; e; e = next)
|
||||
{
|
||||
next = e->next;
|
||||
if(e->kind == OS_EventKind_WindowClose)
|
||||
{
|
||||
for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next)
|
||||
{
|
||||
if(os_handle_match(w->os, e->window))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(w);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CloseWindow));
|
||||
break;
|
||||
}
|
||||
}
|
||||
os_eat_event(&events, e);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: determine frame time, record into history
|
||||
//
|
||||
U64 end_time_us = os_now_microseconds();
|
||||
U64 frame_time_us = end_time_us-begin_time_us;
|
||||
frame_time_us_history[frame_time_us_history_idx%ArrayCount(frame_time_us_history)] = frame_time_us;
|
||||
frame_time_us_history_idx += 1;
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: end logging
|
||||
//
|
||||
{
|
||||
String8 log = log_scope_end(scratch.arena);
|
||||
os_append_data_to_file_path(main_thread_log_path, log);
|
||||
LogScopeResult log = log_scope_end(scratch.arena);
|
||||
os_append_data_to_file_path(main_thread_log_path, log.strings[LogMsgKind_Info]);
|
||||
if(log.strings[LogMsgKind_UserError].size != 0)
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_gfx();
|
||||
p.string = log.strings[LogMsgKind_UserError];
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
|
||||
+47
-46
@@ -4,19 +4,13 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Frontend/UI Pass Tasks
|
||||
//
|
||||
// [ ] editing multiple bindings for commands
|
||||
// [ ] n-row table selection, in watch window & other UIs, multi-selection
|
||||
// ctrl+C
|
||||
// [ ] UI_NavActions, OS_Event -> UI_Event (single event stream)
|
||||
//
|
||||
// [ ] better discoverability for view rules - have better help hover tooltip,
|
||||
// info on arguments, and better autocomplete lister
|
||||
//
|
||||
// [ ] source view -> floating margin/line-nums
|
||||
// [ ] theme colors -> more explicit about e.g. opaque backgrounds vs. floating
|
||||
// & scrollbars etc.
|
||||
// [ ] target/breakpoint/watch-pin reordering
|
||||
// [ ] watch window reordering
|
||||
// [ ] standard way to filter
|
||||
// [ ] visualize remapped files (via path map)
|
||||
// [ ] theme lister -> fonts & font sizes
|
||||
// [ ] font lister
|
||||
@@ -32,9 +26,6 @@
|
||||
// that you use to tag them. Just some way that would make it easier to
|
||||
// focus on your own threads.
|
||||
//
|
||||
// [ ] autocomplete lister should respect position in edited expression,
|
||||
// tabbing through should autocomplete but not exit, etc.
|
||||
//
|
||||
// [ ] it would be nice to have "show in explorer" for right click on source
|
||||
// file tab (opens explorer & selects the file)
|
||||
//
|
||||
@@ -42,8 +33,6 @@
|
||||
// different color? can I turn it off? And why sometimes digits in number
|
||||
// start with brighter color, but sometimes with darker - shouldn't it
|
||||
// always have the same color ordering?
|
||||
//
|
||||
// [ ] pipe failure-to-launch errors back to frontend
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Hot, High Priority Tasks (Complete Unusability, Crashes, Fire-Worthy)
|
||||
@@ -73,6 +62,17 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup)
|
||||
//
|
||||
// [ ] Jeff Notes
|
||||
// [ ] highlighted text & ctrl+f -> auto-fill search query
|
||||
// [ ] double-click any part of frame in callstack view -> snap to function
|
||||
// [ ] sort locals by appearance in source code (or maybe just debug info)
|
||||
// [ ] sum view rule
|
||||
// [ ] plot view rule
|
||||
// [ ] histogram view rule
|
||||
// [ ] max view rule
|
||||
// [ ] min view rule
|
||||
// [ ] double click on procedure in procedures tab to jump to source
|
||||
//
|
||||
// [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not
|
||||
// support it?
|
||||
//
|
||||
@@ -129,24 +129,11 @@
|
||||
// have alternating bright/dim letters to show sections of a number. Is
|
||||
// this in the theme colors somewhere?
|
||||
//
|
||||
// [ ] ** I couldn't figure out how to really view threads in the debugger.
|
||||
// The only place I found a thread list was in "The Scheduler", but it
|
||||
// only lists threads by ID, which is hard to use. I can hover over them
|
||||
// to get the stack, which helps, but it would be much nicer if the top
|
||||
// function was displayed in the window by default next to the thread.
|
||||
// [ ] ** It would be nice if thread listings displayed the name of the
|
||||
// thread, instead of just the ID.
|
||||
//
|
||||
// [ ] ** Scrollbars are barely visible for me, for some reason. I could not
|
||||
// find anything in the theme that would fill them with a solid, bright
|
||||
// color. Instead they are just a thin outline and the same color as the
|
||||
// scroll bar background.
|
||||
//
|
||||
// [ ] Dragging a window tab (like Locals or Registers or whatnot) and
|
||||
// canceling with ESC should revert the window tab to where it was.
|
||||
// Currently, it leaves the window tab reordered if you dragged over its
|
||||
// window and shuffled its position.
|
||||
//
|
||||
// [ ] Many of the UI elements, like the menus, would like better if they had
|
||||
// a little bit of margin. Having the text right next to the edges, and
|
||||
// with no line spacing, makes it harder to read things quickly.
|
||||
@@ -205,11 +192,6 @@
|
||||
// be fine with them, but they would have to be much more light (like
|
||||
// alpha 0.1 or something)
|
||||
//
|
||||
// [ ] It's confusing that ENTER is the way you expand and collapse things in
|
||||
// the watch window, but then also how you edit them if they are not
|
||||
// expandable? It seems like this should be consistent (one way to edit,
|
||||
// one way to expand/collapse, that are distinct)
|
||||
//
|
||||
// [ ] The hex format for color values in the config file was a real
|
||||
// mindbender. It's prefixed with "0x", so I was assuming it was either
|
||||
// Windows Big Endian (0xAARRGGBB) or Mac Little Endian (0xAABBGGRR). To
|
||||
@@ -234,16 +216,10 @@
|
||||
// [ ] can it ignore stepping into _RTC_CheckStackVars generated functions?
|
||||
// [ ] mouse back button should make view to go back after I double clicked
|
||||
// on function to open it
|
||||
// [ ] pressing random keyboard keys in source code advances text cursor like
|
||||
// you were inputting text, very strange.
|
||||
// [ ] Alt+8 to switch to disassembly would be nice (regardless on which
|
||||
// panel was previous, don't want to use ctrl+, multiple times)
|
||||
// Alt+8 for disasm and Alt+6 for memory view are shortcuts I often use
|
||||
// in VS
|
||||
// [ ] in watch window when I enter some new expression and then click mouse
|
||||
// away from cell, then it should behave the same as if I pressed enter.
|
||||
// Currently it does the same as if I have pressed esc and I have lost my
|
||||
// expression
|
||||
// [ ] default font size is too small for me - not only source code, but
|
||||
// menus/tab/watch names (which don't resize). Maybe you could query
|
||||
// Windows for initial font size?
|
||||
@@ -319,7 +295,6 @@
|
||||
// variables?
|
||||
//
|
||||
// [ ] @feature disasm view improvement features
|
||||
// [ ] interleaved src/dasm view
|
||||
// [ ] visualize jump destinations in disasm
|
||||
//
|
||||
// [ ] @feature eval ui improvement features
|
||||
@@ -355,14 +330,6 @@
|
||||
// [ ] fancy string runs can include "weakness" information for text truncation
|
||||
// ... can prioritize certain parts of strings to be truncated before
|
||||
// others. would be good for e.g. the middle of a path
|
||||
// [ ] ui code maintenance, simplification, design, & robustness pass
|
||||
// [ ] page-up & page-down correct handling in keyboard nav
|
||||
// [ ] collapse context menus & command lister into same codepaths. filter by
|
||||
// context. parameterize by context.
|
||||
// [ ] collapse text cells & command lister & etc. into same codepath (?)
|
||||
// [ ] nested context menus
|
||||
// [ ] unified top-level cursor/typing/lister helper
|
||||
// [ ] font selection lister
|
||||
// [ ] font cache eviction (both for font tags, closing fp handles, and
|
||||
// rasterizations)
|
||||
// [ ] frontend speedup opportunities
|
||||
@@ -377,7 +344,41 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Recently Completed Task Log
|
||||
//
|
||||
//
|
||||
// [x] UI_NavActions, OS_Event -> UI_Event (single event stream)
|
||||
// [x] better discoverability for view rules - have better help hover tooltip,
|
||||
// info on arguments, and better autocomplete lister
|
||||
// [x] source view -> floating margin/line-nums
|
||||
// [x] watch window reordering
|
||||
// [x] standard way to filter
|
||||
// [x] autocomplete lister should respect position in edited expression,
|
||||
// tabbing through should autocomplete but not exit, etc.
|
||||
// [x] pipe failure-to-launch errors back to frontend
|
||||
// [x] bit more padding on the tabs
|
||||
// [x] unified top-level cursor/typing/lister helper
|
||||
// [x] collapse text cells & command lister & etc. into same codepath (?)
|
||||
// [x] page-up & page-down correct handling in keyboard nav
|
||||
// [x] interleaved src/dasm view
|
||||
// [x] in watch window when I enter some new expression and then click mouse
|
||||
// away from cell, then it should behave the same as if I pressed enter.
|
||||
// Currently it does the same as if I have pressed esc and I have lost my
|
||||
// expression
|
||||
// [x] pressing random keyboard keys in source code advances text cursor like
|
||||
// you were inputting text, very strange.
|
||||
// [x] It's confusing that ENTER is the way you expand and collapse things in
|
||||
// the watch window, but then also how you edit them if they are not
|
||||
// expandable? It seems like this should be consistent (one way to edit,
|
||||
// one way to expand/collapse, that are distinct)
|
||||
// [x] Dragging a window tab (like Locals or Registers or whatnot) and
|
||||
// canceling with ESC should revert the window tab to where it was.
|
||||
// Currently, it leaves the window tab reordered if you dragged over its
|
||||
// window and shuffled its position.
|
||||
// [x] ** I couldn't figure out how to really view threads in the debugger.
|
||||
// The only place I found a thread list was in "The Scheduler", but it
|
||||
// only lists threads by ID, which is hard to use. I can hover over them
|
||||
// to get the stack, which helps, but it would be much nicer if the top
|
||||
// function was displayed in the window by default next to the thread.
|
||||
// [x] ** It would be nice if thread listings displayed the name of the
|
||||
// thread, instead of just the ID.
|
||||
|
||||
#ifndef RADDBG_H
|
||||
#define RADDBG_H
|
||||
|
||||
@@ -2057,7 +2057,7 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point)
|
||||
// rjf: unpack proc's container type
|
||||
RDIM_Type *container_type = 0;
|
||||
U64 container_name_opl = p2r_end_of_cplusplus_container_name(name);
|
||||
if(container_name_opl > 2)
|
||||
if(container_name_opl > 2 && in->tpi_hash != 0 && in->tpi_leaf != 0)
|
||||
{
|
||||
String8 container_name = str8(name.str, container_name_opl - 2);
|
||||
CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0);
|
||||
|
||||
+33
-23
@@ -193,32 +193,32 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size,
|
||||
if(is_focus_active)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
UI_NavActionList *nav_actions = ui_nav_actions();
|
||||
for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next)
|
||||
UI_EventList *events = ui_events();
|
||||
for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next)
|
||||
{
|
||||
String8 edit_string = str8(edit_buffer, edit_string_size_out[0]);
|
||||
next = n->next;
|
||||
|
||||
// rjf: do not consume anything that doesn't fit a single-line's operations
|
||||
if(n->v.delta.y != 0)
|
||||
if((n->v.kind != UI_EventKind_Edit && n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Text) || n->v.delta_2s32.y != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// rjf: map this action to an op
|
||||
UI_NavTxtOp op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, edit_string, *cursor, *mark);
|
||||
UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, edit_string, *cursor, *mark);
|
||||
|
||||
// rjf: perform replace range
|
||||
if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0)
|
||||
{
|
||||
String8 new_string = ui_nav_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace);
|
||||
String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace);
|
||||
new_string.size = Min(edit_buffer_size, new_string.size);
|
||||
MemoryCopy(edit_buffer, new_string.str, new_string.size);
|
||||
edit_string_size_out[0] = new_string.size;
|
||||
}
|
||||
|
||||
// rjf: perform copy
|
||||
if(op.flags & UI_NavTxtOpFlag_Copy)
|
||||
if(op.flags & UI_TxtOpFlag_Copy)
|
||||
{
|
||||
os_set_clipboard_text(op.copy);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size,
|
||||
|
||||
// rjf: consume event
|
||||
{
|
||||
ui_nav_eat_action_node(nav_actions, n);
|
||||
ui_eat_event(events, n);
|
||||
changes_made = 1;
|
||||
}
|
||||
}
|
||||
@@ -1335,7 +1335,7 @@ thread_static Vec2F32 ui_scroll_list_dim_px = {0};
|
||||
thread_static Rng1S64 ui_scroll_list_scroll_idx_rng = {0};
|
||||
|
||||
internal void
|
||||
ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S64 *cursor_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out)
|
||||
ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S64 *cursor_out, Vec2S64 *mark_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out)
|
||||
{
|
||||
//- rjf: unpack arguments
|
||||
Rng1S64 scroll_row_idx_range = r1s64(params->item_range.min, ClampBot(params->item_range.min, params->item_range.max-1));
|
||||
@@ -1345,27 +1345,28 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6
|
||||
B32 moved = 0;
|
||||
if(params->flags & UI_ScrollListFlag_Nav && cursor_out != 0 && ui_is_focus_active())
|
||||
{
|
||||
UI_NavActionList *nav_actions = ui_nav_actions();
|
||||
UI_EventList *events = ui_events();
|
||||
Vec2S64 cursor = *cursor_out;
|
||||
for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next)
|
||||
Vec2S64 mark = mark_out ? *mark_out : cursor;
|
||||
for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next)
|
||||
{
|
||||
next = n->next;
|
||||
UI_NavAction *action = &n->v;
|
||||
if((action->delta.x == 0 && action->delta.y == 0) ||
|
||||
action->flags & (UI_NavActionFlag_KeepMark|UI_NavActionFlag_Delete))
|
||||
UI_Event *evt = &n->v;
|
||||
if((evt->delta_2s32.x == 0 && evt->delta_2s32.y == 0) ||
|
||||
evt->flags & UI_EventFlag_Delete)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ui_nav_eat_action_node(nav_actions, n);
|
||||
ui_eat_event(events, n);
|
||||
moved = 1;
|
||||
switch(action->delta_unit)
|
||||
switch(evt->delta_unit)
|
||||
{
|
||||
default:{moved = 0;}break;
|
||||
case UI_NavDeltaUnit_Element:
|
||||
case UI_EventDeltaUnit_Char:
|
||||
{
|
||||
for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis+1))
|
||||
{
|
||||
cursor.v[axis] += action->delta.v[axis];
|
||||
cursor.v[axis] += evt->delta_2s32.v[axis];
|
||||
if(cursor.v[axis] < params->cursor_range.min.v[axis])
|
||||
{
|
||||
cursor.v[axis] = params->cursor_range.max.v[axis];
|
||||
@@ -1377,25 +1378,34 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6
|
||||
cursor.v[axis] = clamp_1s64(r1s64(params->cursor_range.min.v[axis], params->cursor_range.max.v[axis]), cursor.v[axis]);
|
||||
}
|
||||
}break;
|
||||
case UI_NavDeltaUnit_Chunk:
|
||||
case UI_NavDeltaUnit_Whole:
|
||||
case UI_EventDeltaUnit_Word:
|
||||
case UI_EventDeltaUnit_Line:
|
||||
case UI_EventDeltaUnit_Page:
|
||||
{
|
||||
cursor.x = (action->delta.x>0 ? params->cursor_range.max.x : action->delta.x<0 ? params->cursor_range.min.x + !!params->cursor_min_is_empty_selection[Axis2_X] : cursor.x);
|
||||
cursor.y += ((action->delta.y>0 ? +(num_possible_visible_rows-3) : action->delta.y<0 ? -(num_possible_visible_rows-3) : 0));
|
||||
cursor.x = (evt->delta_2s32.x>0 ? params->cursor_range.max.x : evt->delta_2s32.x<0 ? params->cursor_range.min.x + !!params->cursor_min_is_empty_selection[Axis2_X] : cursor.x);
|
||||
cursor.y += ((evt->delta_2s32.y>0 ? +(num_possible_visible_rows-3) : evt->delta_2s32.y<0 ? -(num_possible_visible_rows-3) : 0));
|
||||
cursor.y = clamp_1s64(r1s64(params->cursor_range.min.y + !!params->cursor_min_is_empty_selection[Axis2_Y], params->cursor_range.max.y), cursor.y);
|
||||
}break;
|
||||
case UI_NavDeltaUnit_EndPoint:
|
||||
case UI_EventDeltaUnit_Whole:
|
||||
{
|
||||
for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis+1))
|
||||
{
|
||||
cursor.v[axis] = (action->delta.v[axis]>0 ? params->cursor_range.max.v[axis] : action->delta.v[axis]<0 ? params->cursor_range.min.v[axis] + !!params->cursor_min_is_empty_selection[axis] : cursor.v[axis]);
|
||||
cursor.v[axis] = (evt->delta_2s32.v[axis]>0 ? params->cursor_range.max.v[axis] : evt->delta_2s32.v[axis]<0 ? params->cursor_range.min.v[axis] + !!params->cursor_min_is_empty_selection[axis] : cursor.v[axis]);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
if(!(evt->flags & UI_EventFlag_KeepMark))
|
||||
{
|
||||
mark = cursor;
|
||||
}
|
||||
}
|
||||
if(moved)
|
||||
{
|
||||
*cursor_out = cursor;
|
||||
if(mark_out)
|
||||
{
|
||||
*mark_out = mark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ internal U64 ui_scroll_list_row_from_item(UI_ScrollListRowBlockArray *blocks, U6
|
||||
internal U64 ui_scroll_list_item_from_row(UI_ScrollListRowBlockArray *blocks, U64 row);
|
||||
|
||||
internal UI_ScrollPt ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_range, S64 view_num_indices);
|
||||
internal void ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt_out, Vec2S64 *cursor_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out);
|
||||
internal void ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt_out, Vec2S64 *cursor_out, Vec2S64 *mark_out, Rng1S64 *visible_row_range_out, UI_ScrollListSignal *signal_out);
|
||||
internal void ui_scroll_list_end(void);
|
||||
|
||||
////////////////////////////////
|
||||
@@ -180,6 +180,6 @@ internal void ui_scroll_list_end(void);
|
||||
#define UI_TableCell DeferLoop(ui_table_cell_begin(), ui_table_cell_end())
|
||||
#define UI_TableCellSized(size) DeferLoop(ui_table_cell_sized_begin(size), ui_table_cell_end())
|
||||
|
||||
#define UI_ScrollList(params, scroll_pt_out, cursor_out, visible_row_range_out, signal_out) DeferLoop(ui_scroll_list_begin((params), (scroll_pt_out), (cursor_out), (visible_row_range_out), (signal_out)), ui_scroll_list_end())
|
||||
#define UI_ScrollList(params, scroll_pt_out, cursor_out, mark_out, visible_row_range_out, signal_out) DeferLoop(ui_scroll_list_begin((params), (scroll_pt_out), (cursor_out), (mark_out), (visible_row_range_out), (signal_out)), ui_scroll_list_end())
|
||||
|
||||
#endif // UI_BASIC_WIDGETS_H
|
||||
|
||||
+235
-191
@@ -95,34 +95,37 @@ ui_key_match(UI_Key a, UI_Key b)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Navigation Action List Building & Consumption Functions
|
||||
//~ rjf: Event Type Functions
|
||||
|
||||
internal void
|
||||
ui_nav_action_list_push(Arena *arena, UI_NavActionList *list, UI_NavAction action)
|
||||
internal UI_EventNode *
|
||||
ui_event_list_push(Arena *arena, UI_EventList *list, UI_Event *v)
|
||||
{
|
||||
UI_NavActionNode *node = push_array(arena, UI_NavActionNode, 1);
|
||||
DLLPushBack(list->first, list->last, node);
|
||||
MemoryCopyStruct(&node->v, &action);
|
||||
UI_EventNode *n = push_array(arena, UI_EventNode, 1);
|
||||
MemoryCopyStruct(&n->v, v);
|
||||
n->v.string = push_str8_copy(arena, n->v.string);
|
||||
DLLPushBack(list->first, list->last, n);
|
||||
list->count += 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
internal void
|
||||
ui_nav_eat_action_node(UI_NavActionList *list, UI_NavActionNode *node)
|
||||
ui_eat_event(UI_EventList *list, UI_EventNode *node)
|
||||
{
|
||||
DLLRemove(list->first, list->last, node);
|
||||
list->count -= 1;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: High Level Navigation Action => Text Operations
|
||||
//~ rjf: Text Operation Functions
|
||||
|
||||
internal B32
|
||||
ui_nav_char_is_code_symbol(U8 c)
|
||||
ui_char_is_scan_boundary(U8 c)
|
||||
{
|
||||
return (char_is_alpha(c) || char_is_digit(c, 10) || c == '_');
|
||||
}
|
||||
|
||||
internal S64
|
||||
ui_nav_scanned_column_from_column(String8 string, S64 start_column, Side side)
|
||||
ui_scanned_column_from_column(String8 string, S64 start_column, Side side)
|
||||
{
|
||||
S64 new_column = start_column;
|
||||
S64 delta = (!!side)*2 - 1;
|
||||
@@ -133,86 +136,90 @@ ui_nav_scanned_column_from_column(String8 string, S64 start_column, Side side)
|
||||
{
|
||||
U8 byte = (col <= string.size) ? string.str[col-1] : 0;
|
||||
B32 is_non_space = !char_is_space(byte);
|
||||
B32 is_name = ui_nav_char_is_code_symbol(byte);
|
||||
|
||||
if (((side == Side_Min) && (col == 1)) ||
|
||||
((side == Side_Max) && (col == string.size+1)) ||
|
||||
(found_non_space && !is_non_space) ||
|
||||
(found_text && !is_name))
|
||||
B32 is_name = ui_char_is_scan_boundary(byte);
|
||||
if(((side == Side_Min) && (col == 1)) ||
|
||||
((side == Side_Max) && (col == string.size+1)) ||
|
||||
(found_non_space && !is_non_space) ||
|
||||
(found_text && !is_name))
|
||||
{
|
||||
new_column = col + (!side && col != 1);
|
||||
break;
|
||||
} else if (!found_text && is_name) {
|
||||
}
|
||||
else if (!found_text && is_name)
|
||||
{
|
||||
found_text = 1;
|
||||
} else if (!found_non_space && is_non_space ) {
|
||||
}
|
||||
else if (!found_non_space && is_non_space)
|
||||
{
|
||||
found_non_space = 1;
|
||||
}
|
||||
}
|
||||
return new_column;
|
||||
}
|
||||
|
||||
internal UI_NavTxtOp
|
||||
ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8 line, TxtPt cursor, TxtPt mark)
|
||||
internal UI_TxtOp
|
||||
ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark)
|
||||
{
|
||||
TxtPt next_cursor = cursor;
|
||||
TxtPt next_mark = mark;
|
||||
TxtRng range = {0};
|
||||
String8 replace = {0};
|
||||
String8 copy = {0};
|
||||
UI_NavTxtOpFlags flags = 0;
|
||||
Vec2S32 delta = action.delta;
|
||||
UI_TxtOpFlags flags = 0;
|
||||
Vec2S32 delta = event->delta_2s32;
|
||||
Vec2S32 original_delta = delta;
|
||||
|
||||
//- rjf: resolve high-level delta into byte delta, based on unit
|
||||
switch(action.delta_unit)
|
||||
switch(event->delta_unit)
|
||||
{
|
||||
default:{}break;
|
||||
case UI_NavDeltaUnit_Element:
|
||||
case UI_EventDeltaUnit_Char:
|
||||
{
|
||||
// TODO(rjf): this should account for multi-byte characters in UTF-8... for now, just assume ASCII and
|
||||
// no-op
|
||||
}break;
|
||||
case UI_NavDeltaUnit_Chunk:
|
||||
case UI_EventDeltaUnit_Word:
|
||||
{
|
||||
delta.x = (S32)ui_nav_scanned_column_from_column(line, cursor.column, delta.x > 0 ? Side_Max : Side_Min) - cursor.column;
|
||||
delta.x = (S32)ui_scanned_column_from_column(string, cursor.column, delta.x > 0 ? Side_Max : Side_Min) - cursor.column;
|
||||
}break;
|
||||
case UI_NavDeltaUnit_Whole:
|
||||
case UI_NavDeltaUnit_EndPoint:
|
||||
case UI_EventDeltaUnit_Line:
|
||||
case UI_EventDeltaUnit_Whole:
|
||||
case UI_EventDeltaUnit_Page:
|
||||
{
|
||||
S64 first_nonwhitespace_column = 1;
|
||||
for(U64 idx = 0; idx < line.size; idx += 1)
|
||||
for(U64 idx = 0; idx < string.size; idx += 1)
|
||||
{
|
||||
if(!char_is_space(line.str[idx]))
|
||||
if(!char_is_space(string.str[idx]))
|
||||
{
|
||||
first_nonwhitespace_column = (S64)idx + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
S64 home_dest_column = (cursor.column == first_nonwhitespace_column) ? 1 : first_nonwhitespace_column;
|
||||
delta.x = (delta.x > 0) ? ((S64)line.size+1 - cursor.column) : (home_dest_column - cursor.column);
|
||||
delta.x = (delta.x > 0) ? ((S64)string.size+1 - cursor.column) : (home_dest_column - cursor.column);
|
||||
}break;
|
||||
}
|
||||
|
||||
//- rjf: zero delta
|
||||
if(!txt_pt_match(cursor, mark) && action.flags & UI_NavActionFlag_ZeroDeltaOnSelect)
|
||||
if(!txt_pt_match(cursor, mark) && event->flags & UI_EventFlag_ZeroDeltaOnSelect)
|
||||
{
|
||||
delta = v2s32(0, 0);
|
||||
}
|
||||
|
||||
//- rjf: form next cursor
|
||||
if(txt_pt_match(cursor, mark) || !(action.flags & UI_NavActionFlag_ZeroDeltaOnSelect))
|
||||
if(txt_pt_match(cursor, mark) || !(event->flags & UI_EventFlag_ZeroDeltaOnSelect))
|
||||
{
|
||||
next_cursor.column += delta.x;
|
||||
}
|
||||
|
||||
//- rjf: cap at line
|
||||
if(action.flags & UI_NavActionFlag_CapAtLine)
|
||||
if(event->flags & UI_EventFlag_CapAtLine)
|
||||
{
|
||||
next_cursor.column = Clamp(1, next_cursor.column, (S64)(line.size+1));
|
||||
next_cursor.column = Clamp(1, next_cursor.column, (S64)(string.size+1));
|
||||
}
|
||||
|
||||
//- rjf: in some cases, we want to pick a selection side based on the delta
|
||||
if(!txt_pt_match(cursor, mark) && action.flags & UI_NavActionFlag_PickSelectSide)
|
||||
if(!txt_pt_match(cursor, mark) && event->flags & UI_EventFlag_PickSelectSide)
|
||||
{
|
||||
if(original_delta.x < 0 || original_delta.y < 0)
|
||||
{
|
||||
@@ -225,21 +232,21 @@ ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8
|
||||
}
|
||||
|
||||
//- rjf: copying
|
||||
if(action.flags & UI_NavActionFlag_Copy)
|
||||
if(event->flags & UI_EventFlag_Copy)
|
||||
{
|
||||
if(cursor.line == mark.line)
|
||||
{
|
||||
copy = str8_substr(line, r1u64(cursor.column-1, mark.column-1));
|
||||
flags |= UI_NavTxtOpFlag_Copy;
|
||||
copy = str8_substr(string, r1u64(cursor.column-1, mark.column-1));
|
||||
flags |= UI_TxtOpFlag_Copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= UI_NavTxtOpFlag_Invalid;
|
||||
flags |= UI_TxtOpFlag_Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: pasting
|
||||
if(action.flags & UI_NavActionFlag_Paste)
|
||||
if(event->flags & UI_EventFlag_Paste)
|
||||
{
|
||||
range = txt_rng(cursor, mark);
|
||||
replace = os_get_clipboard_text(arena);
|
||||
@@ -247,7 +254,7 @@ ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8
|
||||
}
|
||||
|
||||
//- rjf: deletion
|
||||
if(action.flags & UI_NavActionFlag_Delete)
|
||||
if(event->flags & UI_EventFlag_Delete)
|
||||
{
|
||||
TxtPt new_pos = txt_pt_min(next_cursor, next_mark);
|
||||
range = txt_rng(next_cursor, next_mark);
|
||||
@@ -256,37 +263,39 @@ ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8
|
||||
}
|
||||
|
||||
//- rjf: stick mark to cursor, when we don't want to keep it in the same spot
|
||||
if(!(action.flags & UI_NavActionFlag_KeepMark))
|
||||
if(!(event->flags & UI_EventFlag_KeepMark))
|
||||
{
|
||||
next_mark = next_cursor;
|
||||
}
|
||||
|
||||
//- rjf: insertion
|
||||
if(action.insertion.size != 0)
|
||||
if(event->string.size != 0)
|
||||
{
|
||||
range = txt_rng(cursor, mark);
|
||||
replace = push_str8_copy(arena, action.insertion);
|
||||
next_cursor = next_mark = txt_pt(range.min.line, range.min.column + action.insertion.size);
|
||||
replace = push_str8_copy(arena, event->string);
|
||||
next_cursor = next_mark = txt_pt(range.min.line, range.min.column + event->string.size);
|
||||
}
|
||||
|
||||
//- rjf: replace & commit -> replace entire range
|
||||
if(action.flags & UI_NavActionFlag_ReplaceAndCommit)
|
||||
#if 0
|
||||
if(event->flags & UI_EventFlag_ReplaceAndCommit)
|
||||
{
|
||||
range = txt_rng(txt_pt(cursor.line, 1), txt_pt(cursor.line, line.size+1));
|
||||
}
|
||||
#endif
|
||||
|
||||
//- rjf: determine if this event should be taken, based on bounds of cursor
|
||||
{
|
||||
if(next_cursor.column > line.size+1 || 1 > next_cursor.column || action.delta.y != 0)
|
||||
if(next_cursor.column > string.size+1 || 1 > next_cursor.column || event->delta_2s32.y != 0)
|
||||
{
|
||||
flags |= UI_NavTxtOpFlag_Invalid;
|
||||
flags |= UI_TxtOpFlag_Invalid;
|
||||
}
|
||||
next_cursor.column = Clamp(1, next_cursor.column, line.size+replace.size+1);
|
||||
next_mark.column = Clamp(1, next_mark.column, line.size+replace.size+1);
|
||||
next_cursor.column = Clamp(1, next_cursor.column, string.size+replace.size+1);
|
||||
next_mark.column = Clamp(1, next_mark.column, string.size+replace.size+1);
|
||||
}
|
||||
|
||||
//- rjf: build+fill
|
||||
UI_NavTxtOp op = {0};
|
||||
UI_TxtOp op = {0};
|
||||
{
|
||||
op.flags = flags;
|
||||
op.replace = replace;
|
||||
@@ -298,11 +307,8 @@ ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8
|
||||
return op;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Single-Line String Modification
|
||||
|
||||
internal String8
|
||||
ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace)
|
||||
ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace)
|
||||
{
|
||||
//- rjf: convert to offset range
|
||||
Rng1U64 range =
|
||||
@@ -336,7 +342,8 @@ ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range
|
||||
}
|
||||
}
|
||||
|
||||
return str8(push_base, new_size);
|
||||
String8 result = str8(push_base, new_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -489,18 +496,12 @@ ui_window(void)
|
||||
return ui_state->window;
|
||||
}
|
||||
|
||||
internal OS_EventList *
|
||||
internal UI_EventList *
|
||||
ui_events(void)
|
||||
{
|
||||
return ui_state->events;
|
||||
}
|
||||
|
||||
internal UI_NavActionList *
|
||||
ui_nav_actions(void)
|
||||
{
|
||||
return ui_state->nav_actions;
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
ui_mouse(void)
|
||||
{
|
||||
@@ -525,6 +526,79 @@ ui_dt(void)
|
||||
return ui_state->animation_dt;
|
||||
}
|
||||
|
||||
//- rjf: event consumption helpers
|
||||
|
||||
internal B32
|
||||
ui_key_press(OS_EventFlags mods, OS_Key key)
|
||||
{
|
||||
UI_EventList *list = ui_events();
|
||||
B32 result = 0;
|
||||
for(UI_EventNode *n = list->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v.kind == UI_EventKind_Press && n->v.key == key && n->v.modifiers == mods)
|
||||
{
|
||||
result = 1;
|
||||
ui_eat_event(list, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
ui_key_release(OS_EventFlags mods, OS_Key key)
|
||||
{
|
||||
UI_EventList *list = ui_events();
|
||||
B32 result = 0;
|
||||
for(UI_EventNode *n = list->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v.kind == UI_EventKind_Release && n->v.key == key && n->v.modifiers == mods)
|
||||
{
|
||||
result = 1;
|
||||
ui_eat_event(list, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
ui_text(U32 character)
|
||||
{
|
||||
UI_EventList *list = ui_events();
|
||||
B32 result = 0;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 character_text = str8_from_32(scratch.arena, str32(&character, 1));
|
||||
for(UI_EventNode *n = list->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v.kind == UI_EventKind_Text && str8_match(character_text, n->v.string, 0))
|
||||
{
|
||||
result = 1;
|
||||
ui_eat_event(list, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
ui_slot_press(UI_EventActionSlot slot)
|
||||
{
|
||||
UI_EventList *list = ui_events();
|
||||
B32 result = 0;
|
||||
for(UI_EventNode *n = list->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v.kind == UI_EventKind_Press && n->v.slot == slot)
|
||||
{
|
||||
result = 1;
|
||||
ui_eat_event(list, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: drag data
|
||||
|
||||
internal Vec2F32
|
||||
@@ -646,7 +720,7 @@ ui_box_from_key(UI_Key key)
|
||||
//~ rjf: Top-Level Building API
|
||||
|
||||
internal void
|
||||
ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_actions, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt)
|
||||
ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt)
|
||||
{
|
||||
//- rjf: reset per-build ui state
|
||||
{
|
||||
@@ -662,9 +736,9 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
}
|
||||
|
||||
//- rjf: detect mouse-moves
|
||||
for(OS_Event *e = events->first; e != 0; e = e->next)
|
||||
for(UI_EventNode *n = events->first; n != 0; n = n->next)
|
||||
{
|
||||
if(e->kind == OS_EventKind_MouseMove && os_handle_match(e->window, window))
|
||||
if(n->v.kind == UI_EventKind_MouseMove)
|
||||
{
|
||||
ui_state->last_time_mousemoved_us = os_now_microseconds();
|
||||
}
|
||||
@@ -674,7 +748,6 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
{
|
||||
ui_state->events = events;
|
||||
ui_state->window = window;
|
||||
ui_state->nav_actions = nav_actions;
|
||||
ui_state->mouse = (os_window_is_focused(window) || ui_state->last_time_mousemoved_us+500000 >= os_now_microseconds()) ? os_mouse_from_window(window) : v2f32(-100, -100);
|
||||
ui_state->animation_dt = animation_dt;
|
||||
MemoryZeroStruct(&ui_state->icon_info);
|
||||
@@ -708,43 +781,41 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
B32 nav_next = 0;
|
||||
B32 nav_prev = 0;
|
||||
Axis2 axis_lock = Axis2_Invalid;
|
||||
if(os_key_press(events, window, 0, OS_Key_Tab))
|
||||
if(ui_key_press(0, OS_Key_Tab))
|
||||
{
|
||||
nav_next = 1;
|
||||
}
|
||||
if(os_key_press(events, window, OS_EventFlag_Shift, OS_Key_Tab))
|
||||
if(ui_key_press(OS_EventFlag_Shift, OS_Key_Tab))
|
||||
{
|
||||
nav_prev = 1;
|
||||
}
|
||||
for(UI_NavActionNode *node = nav_actions->first, *next = 0;
|
||||
node != 0;
|
||||
node = next)
|
||||
for(UI_EventNode *node = events->first, *next = 0; node != 0; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
B32 taken = 0;
|
||||
if(node->v.delta.x == 0 && node->v.delta.y == 0)
|
||||
if(node->v.delta_2s32.x == 0 && node->v.delta_2s32.y == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(((node->v.delta.x > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta.x == 0) &&
|
||||
((node->v.delta.y > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta.y == 0))
|
||||
if(((node->v.delta_2s32.x > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta_2s32.x == 0) &&
|
||||
((node->v.delta_2s32.y > 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta_2s32.y == 0))
|
||||
{
|
||||
taken = 1;
|
||||
nav_next = 1;
|
||||
}
|
||||
if(((node->v.delta.x < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta.x == 0) &&
|
||||
((node->v.delta.y < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta.y == 0))
|
||||
if(((node->v.delta_2s32.x < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavX) || node->v.delta_2s32.x == 0) &&
|
||||
((node->v.delta_2s32.y < 0 && nav_root->flags & UI_BoxFlag_DefaultFocusNavY) || node->v.delta_2s32.y == 0))
|
||||
{
|
||||
taken = 1;
|
||||
nav_prev = 1;
|
||||
}
|
||||
if(node->v.flags & UI_NavActionFlag_ExplicitDirectional)
|
||||
if(node->v.flags & UI_EventFlag_ExplicitDirectional)
|
||||
{
|
||||
axis_lock = node->v.delta.x != 0 ? Axis2_X : Axis2_Y;
|
||||
axis_lock = node->v.delta_2s32.x != 0 ? Axis2_X : Axis2_Y;
|
||||
}
|
||||
if(taken)
|
||||
{
|
||||
ui_nav_eat_action_node(nav_actions, node);
|
||||
ui_eat_event(events, node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,7 +943,7 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
//- rjf: some child has the active focus -> accept escape keys to pop from the active key stack
|
||||
if(!ui_key_match(ui_key_zero(), nav_root->default_nav_focus_active_key))
|
||||
{
|
||||
for(;os_key_press(events, window, 0, OS_Key_Esc);)
|
||||
for(;ui_slot_press(UI_EventActionSlot_Cancel);)
|
||||
{
|
||||
UI_Box *prev_focus_root = nav_root;
|
||||
for(UI_Box *focus_root = ui_box_from_key(nav_root->default_nav_focus_active_key);
|
||||
@@ -900,13 +971,10 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
UI_Box *active_box = ui_box_from_key(nav_root->default_nav_focus_active_key);
|
||||
if(!ui_box_is_nil(active_box))
|
||||
{
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
for(UI_EventNode *n = events->first; n != 0; n = n->next)
|
||||
{
|
||||
if(!os_handle_match(event->window, window))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(event->kind == OS_EventKind_Press &&
|
||||
UI_Event *event = &n->v;
|
||||
if(event->kind == UI_EventKind_Press &&
|
||||
event->key == OS_Key_LeftMouseButton &&
|
||||
!contains_2f32(active_box->rect, ui_mouse()))
|
||||
{
|
||||
@@ -1015,20 +1083,6 @@ ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_act
|
||||
ui_state->active_box_key[k] = ui_key_zero();
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: reset active keys if there is clicking activity on other windows
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((event->kind == OS_EventKind_Press || event->kind == OS_EventKind_Release) &&
|
||||
!os_handle_match(event->window, window))
|
||||
{
|
||||
for(EachEnumVal(UI_MouseButtonKind, k))
|
||||
{
|
||||
ui_state->active_box_key[k] = ui_key_zero();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
@@ -1037,7 +1091,7 @@ ui_end_build(void)
|
||||
ProfBeginFunction();
|
||||
|
||||
//- rjf: escape -> close context menu
|
||||
if(ui_state->ctx_menu_open != 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Esc))
|
||||
if(ui_state->ctx_menu_open != 0 && ui_slot_press(UI_EventActionSlot_Cancel))
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
@@ -1287,12 +1341,16 @@ ui_end_build(void)
|
||||
}
|
||||
|
||||
//- rjf: close ctx menu if unconsumed clicks
|
||||
for(OS_Event *event = ui_events()->first; event != 0; event = event->next)
|
||||
{
|
||||
if(event->kind == OS_EventKind_Press && os_handle_match(event->window, ui_window()) &&
|
||||
(event->key == OS_Key_LeftMouseButton || event->key == OS_Key_RightMouseButton))
|
||||
UI_EventList *events = ui_events();
|
||||
for(UI_EventNode *n = events->first; n != 0; n = n->next)
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
UI_Event *event = &n->v;
|
||||
if(event->kind == UI_EventKind_Press &&
|
||||
(event->key == OS_Key_LeftMouseButton || event->key == OS_Key_RightMouseButton))
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1314,10 +1372,11 @@ ui_end_build(void)
|
||||
|
||||
//- rjf: clipboard commits
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
UI_Box *box = ui_box_from_key(ui_state->clipboard_copy_key);
|
||||
String8List strs = {0};
|
||||
if(!ui_box_is_nil(box))
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8List strs = {0};
|
||||
UI_BoxRec rec = {0};
|
||||
for(UI_Box *b = box; !ui_box_is_nil(b); rec = ui_box_rec_df_pre(b, box), b = rec.next)
|
||||
{
|
||||
@@ -1334,8 +1393,8 @@ ui_end_build(void)
|
||||
String8 string = str8_list_join(scratch.arena, &strs, &join);
|
||||
os_set_clipboard_text(string);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: hovering possibly-truncated drawn text -> store text
|
||||
@@ -2336,33 +2395,33 @@ ui_do_single_line_string_edits(TxtPt *cursor, TxtPt *mark, U64 string_max, Strin
|
||||
{
|
||||
B32 change = 0;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
UI_NavActionList *nav_actions = ui_nav_actions();
|
||||
for(UI_NavActionNode *n = nav_actions->first, *next = 0; n != 0; n = next)
|
||||
UI_EventList *events = ui_events();
|
||||
for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next)
|
||||
{
|
||||
next = n->next;
|
||||
|
||||
// rjf: do not consume anything that doesn't fit a single-line's operations
|
||||
if(n->v.delta.y != 0)
|
||||
if((n->v.kind != UI_EventKind_Edit && n->v.kind != UI_EventKind_Navigate && n->v.kind != UI_EventKind_Text) || n->v.delta_2s32.y != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// rjf: map this action to an op
|
||||
B32 taken = 0;
|
||||
UI_NavTxtOp op = ui_nav_single_line_txt_op_from_action(scratch.arena, n->v, *out_string, *cursor, *mark);
|
||||
UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, &n->v, *out_string, *cursor, *mark);
|
||||
|
||||
// rjf: perform replace range
|
||||
if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0)
|
||||
{
|
||||
taken = 1;
|
||||
String8 new_string = ui_nav_push_string_replace_range(scratch.arena, *out_string, r1s64(op.range.min.column, op.range.max.column), op.replace);
|
||||
String8 new_string = ui_push_string_replace_range(scratch.arena, *out_string, r1s64(op.range.min.column, op.range.max.column), op.replace);
|
||||
new_string.size = Min(string_max, new_string.size);
|
||||
MemoryCopy(out_string->str, new_string.str, new_string.size);
|
||||
out_string->size = new_string.size;
|
||||
}
|
||||
|
||||
// rjf: perform copy
|
||||
if(op.flags & UI_NavTxtOpFlag_Copy)
|
||||
if(op.flags & UI_TxtOpFlag_Copy)
|
||||
{
|
||||
taken = 1;
|
||||
os_set_clipboard_text(op.copy);
|
||||
@@ -2376,7 +2435,7 @@ ui_do_single_line_string_edits(TxtPt *cursor, TxtPt *mark, U64 string_max, Strin
|
||||
// rjf: consume event
|
||||
if(taken)
|
||||
{
|
||||
ui_nav_eat_action_node(nav_actions, n);
|
||||
ui_eat_event(events, n);
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
@@ -2435,15 +2494,13 @@ ui_signal_from_box(UI_Box *box)
|
||||
//- rjf: process events related to this box
|
||||
//
|
||||
B32 view_scrolled = 0;
|
||||
for(OS_Event *evt = ui_state->events->first, *next = 0;
|
||||
evt != 0;
|
||||
evt = next)
|
||||
for(UI_EventNode *n = ui_state->events->first, *next = 0;
|
||||
n != 0;
|
||||
n = next)
|
||||
{
|
||||
B32 taken = 0;
|
||||
next = evt->next;
|
||||
|
||||
//- rjf: skip disqualified events
|
||||
if(!os_handle_match(evt->window, ui_state->window)) {continue;}
|
||||
next = n->next;
|
||||
UI_Event *evt = &n->v;
|
||||
|
||||
//- rjf: unpack event
|
||||
Vec2F32 evt_mouse = evt->pos;
|
||||
@@ -2455,11 +2512,11 @@ ui_signal_from_box(UI_Box *box)
|
||||
B32 evt_key_is_mouse = (evt->key == OS_Key_LeftMouseButton ||
|
||||
evt->key == OS_Key_MiddleMouseButton ||
|
||||
evt->key == OS_Key_RightMouseButton);
|
||||
sig.event_flags |= evt->flags;
|
||||
sig.event_flags |= evt->modifiers;
|
||||
|
||||
//- rjf: mouse presses in box -> set hot/active; mark signal accordingly
|
||||
if(box->flags & UI_BoxFlag_MouseClickable &&
|
||||
evt->kind == OS_EventKind_Press &&
|
||||
evt->kind == UI_EventKind_Press &&
|
||||
evt_mouse_in_bounds &&
|
||||
evt_key_is_mouse)
|
||||
{
|
||||
@@ -2493,7 +2550,7 @@ ui_signal_from_box(UI_Box *box)
|
||||
|
||||
//- rjf: mouse releases in active box -> unset active; mark signal accordingly
|
||||
if(box->flags & UI_BoxFlag_MouseClickable &&
|
||||
evt->kind == OS_EventKind_Release &&
|
||||
evt->kind == UI_EventKind_Release &&
|
||||
ui_key_match(ui_state->active_box_key[evt_mouse_button_kind], box->key) &&
|
||||
evt_mouse_in_bounds &&
|
||||
evt_key_is_mouse)
|
||||
@@ -2506,7 +2563,7 @@ ui_signal_from_box(UI_Box *box)
|
||||
|
||||
//- rjf: mouse releases outside active box -> unset hot/active
|
||||
if(box->flags & UI_BoxFlag_MouseClickable &&
|
||||
evt->kind == OS_EventKind_Release &&
|
||||
evt->kind == UI_EventKind_Release &&
|
||||
ui_key_match(ui_state->active_box_key[evt_mouse_button_kind], box->key) &&
|
||||
!evt_mouse_in_bounds &&
|
||||
evt_key_is_mouse)
|
||||
@@ -2520,21 +2577,60 @@ ui_signal_from_box(UI_Box *box)
|
||||
//- rjf: focus is hot & keyboard click -> mark signal
|
||||
if(box->flags & UI_BoxFlag_KeyboardClickable &&
|
||||
is_focus_hot &&
|
||||
evt->kind == OS_EventKind_Press &&
|
||||
evt->key == OS_Key_Return)
|
||||
evt->kind == UI_EventKind_Press &&
|
||||
evt->slot == UI_EventActionSlot_Accept)
|
||||
{
|
||||
sig.f |= UI_SignalFlag_KeyboardPressed;
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: focus is hot & copy event -> remember to copy this box tree's text content
|
||||
if(is_focus_hot &&
|
||||
evt->flags & UI_EventFlag_Copy &&
|
||||
!ui_key_match(ui_key_zero(), box->key))
|
||||
{
|
||||
ui_state->clipboard_copy_key = box->key;
|
||||
taken = 1;
|
||||
}
|
||||
|
||||
//- rjf: ancestor is focused & fastpath codepoint pressed -> press
|
||||
if(box->flags & UI_BoxFlag_Clickable && box->fastpath_codepoint != 0 && evt->string.size != 0)
|
||||
{
|
||||
B32 ancestor_is_focused = 0;
|
||||
for(UI_Box *parent = box->parent; !ui_box_is_nil(parent); parent = parent->parent)
|
||||
{
|
||||
if(parent->flags & UI_BoxFlag_FocusActive)
|
||||
{
|
||||
ancestor_is_focused = 1;
|
||||
if(parent->flags & UI_BoxFlag_FocusActiveDisabled ||
|
||||
!ui_key_match(parent->default_nav_focus_active_key, ui_key_zero()))
|
||||
{
|
||||
ancestor_is_focused = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ancestor_is_focused)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String32 insertion32 = str32_from_8(scratch.arena, evt->string);
|
||||
if(insertion32.size == 1 && insertion32.str[0] == box->fastpath_codepoint)
|
||||
{
|
||||
taken = 1;
|
||||
sig.f |= UI_SignalFlag_Clicked|UI_SignalFlag_Pressed;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: scrolling
|
||||
if(box->flags & UI_BoxFlag_Scroll &&
|
||||
evt->kind == OS_EventKind_Scroll &&
|
||||
evt->flags != OS_EventFlag_Ctrl &&
|
||||
evt->kind == UI_EventKind_Scroll &&
|
||||
evt->modifiers != OS_EventFlag_Ctrl &&
|
||||
evt_mouse_in_bounds)
|
||||
{
|
||||
Vec2F32 delta = evt->delta;
|
||||
if(evt->flags & OS_EventFlag_Shift)
|
||||
Vec2F32 delta = evt->delta_2f32;
|
||||
if(evt->modifiers & OS_EventFlag_Shift)
|
||||
{
|
||||
Swap(F32, delta.x, delta.y);
|
||||
}
|
||||
@@ -2550,12 +2646,12 @@ ui_signal_from_box(UI_Box *box)
|
||||
|
||||
//- rjf: view scrolling
|
||||
if(box->flags & UI_BoxFlag_ViewScroll && box->first_touched_build_index != box->last_touched_build_index &&
|
||||
evt->kind == OS_EventKind_Scroll &&
|
||||
evt->flags != OS_EventFlag_Ctrl &&
|
||||
evt->kind == UI_EventKind_Scroll &&
|
||||
evt->modifiers != OS_EventFlag_Ctrl &&
|
||||
evt_mouse_in_bounds)
|
||||
{
|
||||
Vec2F32 delta = evt->delta;
|
||||
if(evt->flags & OS_EventFlag_Shift)
|
||||
Vec2F32 delta = evt->delta_2f32;
|
||||
if(evt->modifiers & OS_EventFlag_Shift)
|
||||
{
|
||||
Swap(F32, delta.x, delta.y);
|
||||
}
|
||||
@@ -2575,7 +2671,6 @@ ui_signal_from_box(UI_Box *box)
|
||||
}
|
||||
delta.y = 0;
|
||||
}
|
||||
os_eat_event(ui_state->events, evt);
|
||||
box->view_off_target.x += delta.x;
|
||||
box->view_off_target.y += delta.y;
|
||||
view_scrolled = 1;
|
||||
@@ -2585,58 +2680,7 @@ ui_signal_from_box(UI_Box *box)
|
||||
//- rjf: taken -> eat event
|
||||
if(taken)
|
||||
{
|
||||
os_eat_event(ui_state->events, evt);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: process nav actions related to this box
|
||||
//
|
||||
{
|
||||
for(UI_NavActionNode *n = ui_state->nav_actions->first, *next = 0;
|
||||
n != 0;
|
||||
n = next)
|
||||
{
|
||||
next = n->next;
|
||||
UI_NavAction *action = &n->v;
|
||||
B32 taken = 0;
|
||||
if(is_focus_hot && box->flags & UI_BoxFlag_KeyboardClickable && action->flags & UI_NavActionFlag_Copy)
|
||||
{
|
||||
ui_state->clipboard_copy_key = box->key;
|
||||
taken = 1;
|
||||
}
|
||||
if(box->flags & UI_BoxFlag_Clickable && box->fastpath_codepoint != 0)
|
||||
{
|
||||
B32 ancestor_is_focused = 0;
|
||||
for(UI_Box *parent = box->parent; !ui_box_is_nil(parent); parent = parent->parent)
|
||||
{
|
||||
if(parent->flags & UI_BoxFlag_FocusActive)
|
||||
{
|
||||
ancestor_is_focused = 1;
|
||||
if(parent->flags & UI_BoxFlag_FocusActiveDisabled ||
|
||||
!ui_key_match(parent->default_nav_focus_active_key, ui_key_zero()))
|
||||
{
|
||||
ancestor_is_focused = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ancestor_is_focused && action->insertion.size != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String32 insertion32 = str32_from_8(scratch.arena, action->insertion);
|
||||
if(insertion32.size == 1 && insertion32.str[0] == box->fastpath_codepoint)
|
||||
{
|
||||
taken = 1;
|
||||
sig.f |= UI_SignalFlag_Clicked|UI_SignalFlag_Pressed;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
if(taken)
|
||||
{
|
||||
ui_nav_eat_action_node(ui_nav_actions(), n);
|
||||
}
|
||||
ui_eat_event(ui_state->events, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+95
-56
@@ -57,68 +57,107 @@ typedef enum UI_FocusKind
|
||||
UI_FocusKind;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Navigation Types
|
||||
//~ rjf: Events
|
||||
|
||||
typedef enum UI_NavDeltaUnit
|
||||
// TODO(rjf): clean all this up
|
||||
|
||||
typedef enum UI_EventKind
|
||||
{
|
||||
UI_NavDeltaUnit_Element,
|
||||
UI_NavDeltaUnit_Chunk,
|
||||
UI_NavDeltaUnit_Whole,
|
||||
UI_NavDeltaUnit_EndPoint,
|
||||
UI_NavDeltaUnit_COUNT,
|
||||
UI_EventKind_Null,
|
||||
UI_EventKind_Press,
|
||||
UI_EventKind_Release,
|
||||
UI_EventKind_Text,
|
||||
UI_EventKind_Navigate,
|
||||
UI_EventKind_Edit,
|
||||
UI_EventKind_MouseMove,
|
||||
UI_EventKind_Scroll,
|
||||
UI_EventKind_AutocompleteHint,
|
||||
UI_EventKind_COUNT
|
||||
}
|
||||
UI_NavDeltaUnit;
|
||||
UI_EventKind;
|
||||
|
||||
typedef U32 UI_NavActionFlags;
|
||||
typedef enum UI_EventActionSlot
|
||||
{
|
||||
UI_EventActionSlot_Null,
|
||||
UI_EventActionSlot_Accept,
|
||||
UI_EventActionSlot_Cancel,
|
||||
UI_EventActionSlot_Edit,
|
||||
UI_EventActionSlot_COUNT
|
||||
}
|
||||
UI_EventActionSlot;
|
||||
|
||||
typedef U32 UI_EventFlags;
|
||||
enum
|
||||
{
|
||||
UI_NavActionFlag_KeepMark = (1<<0),
|
||||
UI_NavActionFlag_Delete = (1<<1),
|
||||
UI_NavActionFlag_Copy = (1<<2),
|
||||
UI_NavActionFlag_Paste = (1<<3),
|
||||
UI_NavActionFlag_ZeroDeltaOnSelect = (1<<4),
|
||||
UI_NavActionFlag_PickSelectSide = (1<<5),
|
||||
UI_NavActionFlag_CapAtLine = (1<<6),
|
||||
UI_NavActionFlag_ExplicitDirectional = (1<<7),
|
||||
UI_NavActionFlag_ReplaceAndCommit = (1<<8),
|
||||
UI_EventFlag_KeepMark = (1<<0),
|
||||
UI_EventFlag_Delete = (1<<1),
|
||||
UI_EventFlag_Copy = (1<<2),
|
||||
UI_EventFlag_Paste = (1<<3),
|
||||
UI_EventFlag_ZeroDeltaOnSelect = (1<<4),
|
||||
UI_EventFlag_PickSelectSide = (1<<5),
|
||||
UI_EventFlag_CapAtLine = (1<<6),
|
||||
UI_EventFlag_ExplicitDirectional = (1<<7),
|
||||
UI_EventFlag_Reorder = (1<<8),
|
||||
};
|
||||
|
||||
typedef struct UI_NavAction UI_NavAction;
|
||||
struct UI_NavAction
|
||||
typedef enum UI_EventDeltaUnit
|
||||
{
|
||||
UI_NavActionFlags flags;
|
||||
Vec2S32 delta;
|
||||
UI_NavDeltaUnit delta_unit;
|
||||
String8 insertion;
|
||||
UI_EventDeltaUnit_Null,
|
||||
UI_EventDeltaUnit_Char,
|
||||
UI_EventDeltaUnit_Word,
|
||||
UI_EventDeltaUnit_Line,
|
||||
UI_EventDeltaUnit_Page,
|
||||
UI_EventDeltaUnit_Whole,
|
||||
UI_EventDeltaUnit_COUNT
|
||||
}
|
||||
UI_EventDeltaUnit;
|
||||
|
||||
typedef struct UI_Event UI_Event;
|
||||
struct UI_Event
|
||||
{
|
||||
UI_EventKind kind;
|
||||
UI_EventActionSlot slot;
|
||||
UI_EventFlags flags;
|
||||
UI_EventDeltaUnit delta_unit;
|
||||
OS_Key key;
|
||||
OS_EventFlags modifiers;
|
||||
String8 string;
|
||||
Vec2F32 pos;
|
||||
Vec2F32 delta_2f32;
|
||||
Vec2S32 delta_2s32;
|
||||
U64 timestamp_us;
|
||||
};
|
||||
|
||||
typedef struct UI_NavActionNode UI_NavActionNode;
|
||||
struct UI_NavActionNode
|
||||
typedef struct UI_EventNode UI_EventNode;
|
||||
struct UI_EventNode
|
||||
{
|
||||
UI_NavActionNode *next;
|
||||
UI_NavActionNode *prev;
|
||||
UI_NavAction v;
|
||||
UI_EventNode *next;
|
||||
UI_EventNode *prev;
|
||||
UI_Event v;
|
||||
};
|
||||
|
||||
typedef struct UI_NavActionList UI_NavActionList;
|
||||
struct UI_NavActionList
|
||||
typedef struct UI_EventList UI_EventList;
|
||||
struct UI_EventList
|
||||
{
|
||||
UI_NavActionNode *first;
|
||||
UI_NavActionNode *last;
|
||||
UI_EventNode *first;
|
||||
UI_EventNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef U32 UI_NavTxtOpFlags;
|
||||
////////////////////////////////
|
||||
//~ rjf: Textual Operations
|
||||
|
||||
typedef U32 UI_TxtOpFlags;
|
||||
enum
|
||||
{
|
||||
UI_NavTxtOpFlag_Invalid = (1<<0),
|
||||
UI_NavTxtOpFlag_Copy = (1<<1),
|
||||
UI_TxtOpFlag_Invalid = (1<<0),
|
||||
UI_TxtOpFlag_Copy = (1<<1),
|
||||
};
|
||||
|
||||
typedef struct UI_NavTxtOp UI_NavTxtOp;
|
||||
struct UI_NavTxtOp
|
||||
typedef struct UI_TxtOp UI_TxtOp;
|
||||
struct UI_TxtOp
|
||||
{
|
||||
UI_NavTxtOpFlags flags;
|
||||
UI_TxtOpFlags flags;
|
||||
String8 replace;
|
||||
String8 copy;
|
||||
TxtRng range;
|
||||
@@ -485,8 +524,7 @@ struct UI_State
|
||||
//- rjf: build parameters
|
||||
UI_IconInfo icon_info;
|
||||
OS_Handle window;
|
||||
OS_EventList *events;
|
||||
UI_NavActionList *nav_actions;
|
||||
UI_EventList *events;
|
||||
Vec2F32 mouse;
|
||||
F32 animation_dt;
|
||||
B32 external_focus_commit;
|
||||
@@ -542,22 +580,18 @@ internal UI_Key ui_key_from_stringf(UI_Key seed_key, char *fmt, ...);
|
||||
internal B32 ui_key_match(UI_Key a, UI_Key b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Navigation Action List Building & Consumption Functions
|
||||
//~ rjf: Event Type Functions
|
||||
|
||||
internal void ui_nav_action_list_push(Arena *arena, UI_NavActionList *list, UI_NavAction action);
|
||||
internal void ui_nav_eat_action_node(UI_NavActionList *list, UI_NavActionNode *node);
|
||||
internal UI_EventNode *ui_event_list_push(Arena *arena, UI_EventList *list, UI_Event *v);
|
||||
internal void ui_eat_event(UI_EventList *list, UI_EventNode *node);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: High Level Navigation Action => Text Operations
|
||||
//~ rjf: Text Operation Functions
|
||||
|
||||
internal B32 ui_nav_char_is_scan_boundary(U8 c);
|
||||
internal S64 ui_nav_scanned_column_from_column(String8 string, S64 start_column, Side side);
|
||||
internal UI_NavTxtOp ui_nav_single_line_txt_op_from_action(Arena *arena, UI_NavAction action, String8 line, TxtPt cursor, TxtPt mark);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Single-Line String Modification
|
||||
|
||||
internal String8 ui_nav_push_string_replace_range(Arena *arena, String8 string, Rng1S64 col_range, String8 replace);
|
||||
internal B32 ui_char_is_scan_boundary(U8 c);
|
||||
internal S64 ui_scanned_column_from_column(String8 string, S64 start_column, Side side);
|
||||
internal UI_TxtOp ui_single_line_txt_op_from_event(Arena *arena, UI_Event *event, String8 string, TxtPt cursor, TxtPt mark);
|
||||
internal String8 ui_push_string_replace_range(Arena *arena, String8 string, Rng1S64 range, String8 replace);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Size Type Functions
|
||||
@@ -611,13 +645,18 @@ internal UI_State *ui_get_selected_state(void);
|
||||
//- rjf: per-frame info
|
||||
internal Arena * ui_build_arena(void);
|
||||
internal OS_Handle ui_window(void);
|
||||
internal OS_EventList * ui_events(void);
|
||||
internal UI_NavActionList *ui_nav_actions(void);
|
||||
internal UI_EventList * ui_events(void);
|
||||
internal Vec2F32 ui_mouse(void);
|
||||
internal F_Tag ui_icon_font(void);
|
||||
internal String8 ui_icon_string_from_kind(UI_IconKind icon_kind);
|
||||
internal F32 ui_dt(void);
|
||||
|
||||
//- rjf: event consumption helpers
|
||||
internal B32 ui_key_press(OS_EventFlags mods, OS_Key key);
|
||||
internal B32 ui_key_release(OS_EventFlags mods, OS_Key key);
|
||||
internal B32 ui_text(U32 character);
|
||||
internal B32 ui_slot_press(UI_EventActionSlot slot);
|
||||
|
||||
//- rjf: drag data
|
||||
internal Vec2F32 ui_drag_start_mouse(void);
|
||||
internal Vec2F32 ui_drag_delta(void);
|
||||
@@ -644,7 +683,7 @@ internal UI_Box * ui_box_from_key(UI_Key key);
|
||||
////////////////////////////////
|
||||
//~ rjf: Top-Level Building API
|
||||
|
||||
internal void ui_begin_build(OS_EventList *events, OS_Handle window, UI_NavActionList *nav_actions, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt);
|
||||
internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, F32 real_dt, F32 animation_dt);
|
||||
internal void ui_end_build(void);
|
||||
internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis);
|
||||
internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis);
|
||||
|
||||
Reference in New Issue
Block a user