mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-25 05:04:58 -07:00
Merge branch 'dev' of https://github.com/EpicGamesExt/raddebugger into inline_merge
This commit is contained in:
@@ -69,7 +69,8 @@ dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off)
|
||||
U64 result = 0;
|
||||
for(U64 idx = 0; idx < array->count; idx += 1)
|
||||
{
|
||||
if(array->v[idx].code_off == off)
|
||||
U64 next_off = (idx+1 < array->count ? array->v[idx+1].code_off : max_U64);
|
||||
if(array->v[idx].code_off <= off && off < next_off)
|
||||
{
|
||||
result = idx;
|
||||
break;
|
||||
|
||||
@@ -1900,7 +1900,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
//
|
||||
case EXCEPTION_DEBUG_EVENT:
|
||||
{
|
||||
// NOTE(rjf): Notes on multithreaded breakpoint events
|
||||
//- NOTE(rjf): Notes on multithreaded breakpoint events
|
||||
// (2021/11/1):
|
||||
//
|
||||
// When many threads are simultaneously running, multiple threads
|
||||
@@ -1928,7 +1928,17 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
// #B. If the actual unmodified instruction is an int 3, then this
|
||||
// becomes a trap event and we do not reset RIP.
|
||||
|
||||
// NOTE(rjf): The exception record struct has a 32-bit version and a
|
||||
//- NOTE(rjf): Further notes on MULTITHREADED STEPPING ACCESS VIOLATION
|
||||
// EVENTS! @rjf @rjf @rjf
|
||||
// (2024/05/29):
|
||||
//
|
||||
// Just adding another comment here to document that the above long
|
||||
// comment went completely unnoticed by me during a pass over demon,
|
||||
// and I had removed the proper rollback stuff here without reading
|
||||
// the above comment. So this comment just serves to make that
|
||||
// original comment even heftier.
|
||||
|
||||
//- NOTE(rjf): The exception record struct has a 32-bit version and a
|
||||
// 64-bit version. We only currently handle the 64-bit version.
|
||||
|
||||
//- rjf: unpack
|
||||
@@ -1981,7 +1991,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
}
|
||||
|
||||
//- rjf: determine whether to roll back instruction pointer
|
||||
B32 should_do_rollback = (hit_user_trap);
|
||||
B32 should_do_rollback = (hit_user_trap || (is_trap && !hit_explicit_trap));
|
||||
|
||||
//- rjf: roll back thread's instruction pointer
|
||||
U64 post_trap_rip = 0;
|
||||
|
||||
+13
-5
@@ -4473,6 +4473,7 @@ df_string_from_ascii_value(Arena *arena, U8 val)
|
||||
case '\'':{result = str8_lit("\\'");}break;
|
||||
case '\\':{result = str8_lit("\\\\");}break;
|
||||
default:
|
||||
if(32 <= val && val < 255)
|
||||
{
|
||||
result = push_str8f(arena, "%c", val);
|
||||
}break;
|
||||
@@ -4511,14 +4512,21 @@ df_string_from_simple_typed_eval(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi,
|
||||
case TG_Kind_UChar32:
|
||||
{
|
||||
String8 char_str = df_string_from_ascii_value(arena, eval.imm_s64);
|
||||
if(flags & DF_EvalVizStringFlag_ReadOnlyDisplayRules)
|
||||
if(char_str.size != 0)
|
||||
{
|
||||
String8 imm_string = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator);
|
||||
result = push_str8f(arena, "'%S' (%S)", char_str, imm_string);
|
||||
if(flags & DF_EvalVizStringFlag_ReadOnlyDisplayRules)
|
||||
{
|
||||
String8 imm_string = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator);
|
||||
result = push_str8f(arena, "'%S' (%S)", char_str, imm_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = push_str8f(arena, "'%S'", char_str);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = push_str8f(arena, "'%S'", char_str);
|
||||
result = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator);
|
||||
}
|
||||
}break;
|
||||
|
||||
@@ -6206,8 +6214,8 @@ df_query_cached_unwind_from_thread(DF_Entity *thread)
|
||||
{
|
||||
node = push_array_no_zero(df_state->arena, DF_UnwindCacheNode, 1);
|
||||
}
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
MemoryZeroStruct(node);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->arena = arena_alloc();
|
||||
node->thread = handle;
|
||||
}
|
||||
|
||||
+195
-22
@@ -2903,6 +2903,13 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread));
|
||||
}break;
|
||||
case DF_EntityKind_Target:
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(ws);
|
||||
params.entity = df_handle_from_entity(entity);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget));
|
||||
}break;
|
||||
}
|
||||
}break;
|
||||
case DF_CoreCmdKind_SpawnEntityView:
|
||||
@@ -5992,7 +5999,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
//- rjf: calculate width of exp row
|
||||
if(row == viz_rows.first)
|
||||
{
|
||||
expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*0.5f;
|
||||
expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*2.5f;
|
||||
expr_column_width_px = Max(expr_column_width_px, ui_top_font_size()*10.f);
|
||||
}
|
||||
|
||||
@@ -10424,9 +10431,9 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions)
|
||||
|
||||
// rjf: draw line before next-to-execute line
|
||||
{
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
|
||||
box->parent->rect.y0 - box->font_size*0.125f,
|
||||
box->rect.x0 + box->font_size*260*u->alive_t,
|
||||
box->parent->parent->parent->rect.x0 + box->font_size*260*u->alive_t,
|
||||
box->parent->rect.y0 + box->font_size*0.125f),
|
||||
v4f32(u->thread_color.x, u->thread_color.y, u->thread_color.z, 0),
|
||||
0, 0, 1);
|
||||
@@ -10451,9 +10458,9 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions)
|
||||
{
|
||||
Vec4F32 weak_thread_color = u->thread_color;
|
||||
weak_thread_color.w *= 0.3f;
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
|
||||
box->parent->rect.y0,
|
||||
box->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
|
||||
box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
|
||||
box->parent->rect.y1),
|
||||
v4f32(0, 0, 0, 0),
|
||||
0, 0, 1);
|
||||
@@ -10491,9 +10498,9 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions)
|
||||
|
||||
// rjf: draw line before next-to-execute line
|
||||
{
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
|
||||
box->parent->rect.y0 - box->font_size*0.125f,
|
||||
box->rect.x0 + ui_top_font_size()*250.f*u->alive_t,
|
||||
box->parent->parent->parent->rect.x0 + ui_top_font_size()*250.f*u->alive_t,
|
||||
box->parent->rect.y0 + box->font_size*0.125f),
|
||||
v4f32(u->color.x, u->color.y, u->color.z, 0),
|
||||
0, 0, 1.f);
|
||||
@@ -10504,9 +10511,9 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions)
|
||||
{
|
||||
Vec4F32 weak_thread_color = u->color;
|
||||
weak_thread_color.w *= 0.3f;
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
|
||||
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
|
||||
box->parent->rect.y0,
|
||||
box->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
|
||||
box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
|
||||
box->parent->rect.y1),
|
||||
v4f32(0, 0, 0, 0),
|
||||
0, 0, 1);
|
||||
@@ -10677,24 +10684,24 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build margins
|
||||
//- rjf: build priority margin
|
||||
//
|
||||
UI_Box *margin_container_box = &ui_g_nil_box;
|
||||
if(params->flags & DF_CodeSliceFlag_Margin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build margins")
|
||||
UI_Box *priority_margin_container_box = &ui_g_nil_box;
|
||||
if(params->flags & DF_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build priority margins")
|
||||
{
|
||||
if(params->margin_float_off_px != 0)
|
||||
{
|
||||
ui_set_next_pref_width(ui_px(params->margin_width_px, 1));
|
||||
ui_set_next_pref_width(ui_px(params->priority_margin_width_px, 1));
|
||||
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
|
||||
ui_build_box_from_key(0, ui_key_zero());
|
||||
ui_set_next_fixed_x(params->margin_float_off_px);
|
||||
ui_set_next_flags(UI_BoxFlag_DrawBackground);
|
||||
}
|
||||
ui_set_next_pref_width(ui_px(params->margin_width_px, 1));
|
||||
ui_set_next_pref_width(ui_px(params->priority_margin_width_px, 1));
|
||||
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("margin_container"));
|
||||
UI_Parent(margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f))
|
||||
priority_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("priority_margin_container"));
|
||||
UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f))
|
||||
{
|
||||
U64 line_idx = 0;
|
||||
for(S64 line_num = params->line_num_range.min;
|
||||
@@ -10702,8 +10709,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
line_num += 1, line_idx += 1)
|
||||
{
|
||||
DF_EntityList line_ips = params->line_ips[line_idx];
|
||||
DF_EntityList line_bps = params->line_bps[line_idx];
|
||||
DF_EntityList line_pins = params->line_pins[line_idx];
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
ui_set_next_background_color(v4f32(0, 0, 0, 0));
|
||||
UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num);
|
||||
@@ -10714,6 +10719,175 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
{
|
||||
// rjf: unpack thread
|
||||
DF_Entity *thread = n->entity;
|
||||
if(thread != selected_thread)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
U64 unwind_count = (thread == selected_thread) ? ctrl_ctx->unwind_count : 0;
|
||||
U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_vaddr);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
U64 thread_rip_voff = df_voff_from_vaddr(module, thread_rip_vaddr);
|
||||
|
||||
// rjf: thread info => color
|
||||
Vec4F32 color = v4f32(1, 1, 1, 1);
|
||||
{
|
||||
if(unwind_count != 0)
|
||||
{
|
||||
color = df_rgba_from_theme_color(DF_ThemeColor_ThreadUnwound);
|
||||
}
|
||||
else if(thread == stopper_thread &&
|
||||
(stop_event.cause == CTRL_EventCause_InterruptedByHalt ||
|
||||
stop_event.cause == CTRL_EventCause_InterruptedByTrap ||
|
||||
stop_event.cause == CTRL_EventCause_InterruptedByException))
|
||||
{
|
||||
color = df_rgba_from_theme_color(DF_ThemeColor_FailureBackground);
|
||||
}
|
||||
else if(thread->flags & DF_EntityFlag_HasColor)
|
||||
{
|
||||
color = df_rgba_from_entity(thread);
|
||||
}
|
||||
if(df_ctrl_targets_running() && df_ctrl_last_run_frame_idx() < df_frame_index())
|
||||
{
|
||||
color.w *= 0.5f;
|
||||
}
|
||||
if(thread != selected_thread)
|
||||
{
|
||||
color.w *= 0.8f;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: build thread box
|
||||
ui_set_next_hover_cursor(OS_Cursor_UpDownLeftRight);
|
||||
ui_set_next_font(ui_icon_font());
|
||||
ui_set_next_font_size(params->font_size);
|
||||
ui_set_next_pref_width(ui_pct(1, 0));
|
||||
ui_set_next_pref_height(ui_pct(1, 0));
|
||||
ui_set_next_text_color(color);
|
||||
ui_set_next_text_alignment(UI_TextAlign_Center);
|
||||
UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%p", thread);
|
||||
UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|
|
||||
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
|
||||
UI_BoxFlag_DrawText,
|
||||
thread_box_key);
|
||||
ui_box_equip_display_string(thread_box, df_g_icon_kind_text_table[DF_IconKind_RightArrow]);
|
||||
UI_Signal thread_sig = ui_signal_from_box(thread_box);
|
||||
|
||||
// rjf: custom draw
|
||||
{
|
||||
DF_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), DF_ThreadBoxDrawExtData, 1);
|
||||
u->thread_color = color;
|
||||
u->alive_t = thread->alive_t;
|
||||
u->is_selected = (thread == selected_thread);
|
||||
u->is_frozen = df_entity_is_frozen(thread);
|
||||
ui_box_equip_custom_draw(thread_box, df_thread_box_draw_extensions, u);
|
||||
|
||||
// rjf: fill out progress t (progress into range of current line's
|
||||
// voff range)
|
||||
if(params->line_src2dasm[line_idx].first != 0)
|
||||
{
|
||||
DF_TextLineSrc2DasmInfoList *line_info_list = ¶ms->line_src2dasm[line_idx];
|
||||
DF_TextLineSrc2DasmInfo *line_info = 0;
|
||||
for(DF_TextLineSrc2DasmInfoNode *n = line_info_list->first;
|
||||
n != 0;
|
||||
n = n->next)
|
||||
{
|
||||
if(di_key_match(&n->v.dbgi_key, &dbgi_key))
|
||||
{
|
||||
line_info = &n->v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(line_info != 0)
|
||||
{
|
||||
Rng1U64 line_voff_rng = line_info->voff_range;
|
||||
Vec4F32 weak_thread_color = color;
|
||||
weak_thread_color.w *= 0.4f;
|
||||
F32 progress_t = (line_voff_rng.max != line_voff_rng.min) ? ((F32)(thread_rip_voff - line_voff_rng.min) / (F32)(line_voff_rng.max - line_voff_rng.min)) : 0;
|
||||
progress_t = Clamp(0, progress_t, 1);
|
||||
u->progress_t = progress_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: hover tooltips
|
||||
if(ui_hovering(thread_sig))
|
||||
{
|
||||
df_entity_tooltips(thread);
|
||||
}
|
||||
|
||||
// rjf: ip right-click menu
|
||||
if(ui_right_clicked(thread_sig))
|
||||
{
|
||||
DF_Handle handle = df_handle_from_entity(thread);
|
||||
if(ui_ctx_menu_is_open(ws->entity_ctx_menu_key) && df_handle_match(ws->entity_ctx_menu_entity, handle))
|
||||
{
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_ctx_menu_open(ws->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0));
|
||||
ws->entity_ctx_menu_entity = handle;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: drag start
|
||||
if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse()))
|
||||
{
|
||||
DF_DragDropPayload payload = {0};
|
||||
payload.key = thread_box->key;
|
||||
payload.entity = df_handle_from_entity(thread);
|
||||
df_drag_begin(&payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build catchall margin
|
||||
//
|
||||
UI_Box *catchall_margin_container_box = &ui_g_nil_box;
|
||||
if(params->flags & DF_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins")
|
||||
{
|
||||
if(params->margin_float_off_px != 0)
|
||||
{
|
||||
ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1));
|
||||
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
|
||||
ui_build_box_from_key(0, ui_key_zero());
|
||||
ui_set_next_fixed_x(params->margin_float_off_px + params->priority_margin_width_px);
|
||||
ui_set_next_flags(UI_BoxFlag_DrawBackground);
|
||||
}
|
||||
ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1));
|
||||
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container"));
|
||||
UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f))
|
||||
{
|
||||
U64 line_idx = 0;
|
||||
for(S64 line_num = params->line_num_range.min;
|
||||
line_num <= params->line_num_range.max;
|
||||
line_num += 1, line_idx += 1)
|
||||
{
|
||||
DF_EntityList line_ips = params->line_ips[line_idx];
|
||||
DF_EntityList line_bps = params->line_bps[line_idx];
|
||||
DF_EntityList line_pins = params->line_pins[line_idx];
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
ui_set_next_background_color(v4f32(0, 0, 0, 0));
|
||||
UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num);
|
||||
UI_Parent(line_margin_box)
|
||||
{
|
||||
//- rjf: build margin thread ip ui
|
||||
for(DF_EntityNode *n = line_ips.first; n != 0; n = n->next)
|
||||
{
|
||||
// rjf: unpack thread
|
||||
DF_Entity *thread = n->entity;
|
||||
if(thread == selected_thread)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
U64 unwind_count = (thread == selected_thread) ? ctrl_ctx->unwind_count : 0;
|
||||
U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
@@ -10760,7 +10934,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%p", thread);
|
||||
UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|
|
||||
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
|
||||
UI_BoxFlag_AnimatePosX|
|
||||
UI_BoxFlag_DrawText,
|
||||
thread_box_key);
|
||||
ui_box_equip_display_string(thread_box, df_g_icon_kind_text_table[DF_IconKind_RightArrow]);
|
||||
@@ -10831,6 +11004,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
params.entity = df_handle_from_entity(thread);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread));
|
||||
ui_kill_action();
|
||||
}
|
||||
|
||||
// rjf: drag start
|
||||
@@ -10884,7 +11058,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
UI_BoxFlag_DrawActiveEffects|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_AnimatePosX|
|
||||
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
|
||||
UI_BoxFlag_DisableTextTrunc,
|
||||
"%S##bp_%p",
|
||||
@@ -10953,7 +11126,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
|
||||
UI_BoxFlag_AnimatePosX|
|
||||
UI_BoxFlag_DisableTextTrunc,
|
||||
"%S##watch_%p",
|
||||
df_g_icon_kind_text_table[DF_IconKind_Pin],
|
||||
@@ -11236,7 +11408,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
//////////////////////////////
|
||||
//- rjf: interact with margin box & text box
|
||||
//
|
||||
UI_Signal margin_container_sig = ui_signal_from_box(margin_container_box);
|
||||
UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box);
|
||||
UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box);
|
||||
UI_Signal text_container_sig = ui_signal_from_box(text_container_box);
|
||||
DF_Entity *line_drag_entity = &df_g_nil_entity;
|
||||
{
|
||||
|
||||
+6
-4
@@ -388,9 +388,10 @@ enum
|
||||
typedef U32 DF_CodeSliceFlags;
|
||||
enum
|
||||
{
|
||||
DF_CodeSliceFlag_Clickable = (1<<0),
|
||||
DF_CodeSliceFlag_Margin = (1<<1),
|
||||
DF_CodeSliceFlag_LineNums = (1<<2),
|
||||
DF_CodeSliceFlag_Clickable = (1<<0),
|
||||
DF_CodeSliceFlag_PriorityMargin = (1<<1),
|
||||
DF_CodeSliceFlag_CatchallMargin = (1<<2),
|
||||
DF_CodeSliceFlag_LineNums = (1<<3),
|
||||
};
|
||||
|
||||
typedef struct DF_CodeSliceParams DF_CodeSliceParams;
|
||||
@@ -415,7 +416,8 @@ struct DF_CodeSliceParams
|
||||
F32 tab_size;
|
||||
String8 search_query;
|
||||
F32 line_height_px;
|
||||
F32 margin_width_px;
|
||||
F32 priority_margin_width_px;
|
||||
F32 catchall_margin_width_px;
|
||||
F32 line_num_width_px;
|
||||
F32 line_text_max_width_px;
|
||||
DF_EntityList flash_ranges;
|
||||
|
||||
@@ -570,7 +570,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
|
||||
code_slice_params.font_size = ui_top_font_size();
|
||||
code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f;
|
||||
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
|
||||
code_slice_params.margin_width_px = 0;
|
||||
code_slice_params.priority_margin_width_px = 0;
|
||||
code_slice_params.catchall_margin_width_px = 0;
|
||||
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
|
||||
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*info.lines_max_size;
|
||||
}
|
||||
@@ -731,7 +732,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
|
||||
code_slice_params.font_size = ui_top_font_size();
|
||||
code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f;
|
||||
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
|
||||
code_slice_params.margin_width_px = 0;
|
||||
code_slice_params.priority_margin_width_px = 0;
|
||||
code_slice_params.catchall_margin_width_px = 0;
|
||||
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
|
||||
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*dasm_text_info.lines_max_size;
|
||||
}
|
||||
|
||||
+64
-38
@@ -3867,13 +3867,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets)
|
||||
UI_FocusHot((row_selected && cursor.x == 0) ? UI_FocusKind_On : UI_FocusKind_Off)
|
||||
{
|
||||
UI_Signal sig = df_icon_buttonf(target->b32 ? DF_IconKind_CheckFilled : DF_IconKind_CheckHollow, 0, "###ebl_%p", target);
|
||||
if(ui_clicked(sig) && sig.event_flags == 0)
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.entity = df_handle_from_entity(target);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget));
|
||||
}
|
||||
else if(ui_clicked(sig) && sig.event_flags == OS_EventFlag_Ctrl)
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.entity = df_handle_from_entity(target);
|
||||
@@ -4835,6 +4829,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DI_Scope *scope = di_scope_open();
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view);
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
U64 selected_unwind_count = ctrl_ctx.unwind_count;
|
||||
@@ -4915,20 +4910,33 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
U64 frame_idx = row_num-1;
|
||||
CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx];
|
||||
|
||||
// rjf: determine selection
|
||||
B32 row_selected = (cs->cursor.y == row_num);
|
||||
|
||||
// rjf: regs => rip
|
||||
// rjf: unpack frame
|
||||
U64 frame_idx = row_num-1;
|
||||
CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs);
|
||||
|
||||
// rjf: rip_vaddr => module
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
|
||||
// rjf: rip => validity?
|
||||
B32 frame_valid = (rip_vaddr != 0);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
|
||||
String8 symbol_name = {0};
|
||||
String8 symbol_type_string = {0};
|
||||
if(rdi->scope_vmap != 0)
|
||||
{
|
||||
U64 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, rip_voff);
|
||||
RDI_Scope *scope = rdi_element_from_idx(rdi, scopes, scope_idx);
|
||||
U64 proc_idx = scope->proc_idx;
|
||||
RDI_Procedure *procedure = &rdi->procedures[proc_idx];
|
||||
RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, procedure->type_idx);
|
||||
TG_Key type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), procedure->type_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
|
||||
TG_Graph *graph = tg_graph_begin(rdi_addr_size_from_arch(rdi->top_level_info->architecture), 256);
|
||||
symbol_name = str8(name_ptr, name_size);
|
||||
symbol_type_string = tg_string_from_key(scratch.arena, graph, rdi, type_key);
|
||||
}
|
||||
|
||||
// rjf: build row
|
||||
if(frame_valid) UI_NamedTableVectorF("###callstack_%p_%I64x", view, frame_idx)
|
||||
@@ -4981,21 +4989,32 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: build cell for function name
|
||||
// rjf: build cell for function header
|
||||
UI_TableCell UI_Font(df_font_from_slot(DF_FontSlot_Code))
|
||||
UI_FocusHot((row_selected && cs->cursor.x == 2) ? UI_FocusKind_On : UI_FocusKind_Off)
|
||||
{
|
||||
String8 symbol = df_symbol_name_from_process_vaddr(scratch.arena, process, rip_vaddr);
|
||||
if(symbol.size == 0)
|
||||
ui_set_next_child_layout_axis(Axis2_X);
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Clip, "frame_%I64x", frame_idx);
|
||||
UI_Parent(box)
|
||||
{
|
||||
symbol = str8_lit("[external code]");
|
||||
ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_WeakText));
|
||||
if(symbol_name.size == 0)
|
||||
{
|
||||
ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_WeakText));
|
||||
ui_label(str8_lit("[unknown symbol]"));
|
||||
}
|
||||
else UI_WidthFill
|
||||
{
|
||||
D_FancyStringList symbol_name_fstrs = df_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeFunction), symbol_name);
|
||||
D_FancyStringList symbol_type_fstrs = df_fancy_string_list_from_code_string(scratch.arena, 0.5f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), symbol_type_string);
|
||||
D_FancyStringList fstrs = {0};
|
||||
d_fancy_string_list_concat_in_place(&fstrs, &symbol_name_fstrs);
|
||||
D_FancyString sep = {ui_top_font(), str8_lit(": "), df_rgba_from_theme_color(DF_ThemeColor_WeakText), ui_top_font_size()};
|
||||
d_fancy_string_list_push(scratch.arena, &fstrs, &sep);
|
||||
d_fancy_string_list_concat_in_place(&fstrs, &symbol_type_fstrs);
|
||||
UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero());
|
||||
ui_box_equip_display_fancy_strings(label, 0, &fstrs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_CodeFunction));
|
||||
}
|
||||
UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_Clickable, symbol);
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
if(ui_pressed(sig))
|
||||
{
|
||||
@@ -5046,6 +5065,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
}
|
||||
}
|
||||
|
||||
di_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -5819,7 +5839,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
//////////////////////////////
|
||||
//- rjf: calculate line-range-dependent info
|
||||
//
|
||||
F32 margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 priority_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
|
||||
TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &text_info, data, visible_line_num_range);
|
||||
|
||||
@@ -5847,7 +5868,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
if(text_info_is_ready)
|
||||
{
|
||||
// rjf: fill basics
|
||||
code_slice_params.flags = DF_CodeSliceFlag_Margin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
|
||||
code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
|
||||
code_slice_params.line_num_range = visible_line_num_range;
|
||||
code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count);
|
||||
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count);
|
||||
@@ -5862,7 +5883,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
code_slice_params.tab_size = code_tab_size;
|
||||
code_slice_params.line_height_px = code_line_height;
|
||||
code_slice_params.search_query = search_query;
|
||||
code_slice_params.margin_width_px = margin_width_px;
|
||||
code_slice_params.priority_margin_width_px = priority_margin_width_px;
|
||||
code_slice_params.catchall_margin_width_px = catchall_margin_width_px;
|
||||
code_slice_params.line_num_width_px = line_num_width_px;
|
||||
code_slice_params.line_text_max_width_px = (F32)line_size_x;
|
||||
code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker);
|
||||
@@ -6382,7 +6404,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
if(snap[Axis2_X])
|
||||
{
|
||||
String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]);
|
||||
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px);
|
||||
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px);
|
||||
Rng1S64 visible_pixel_range =
|
||||
{
|
||||
view->scroll_pos.x.idx,
|
||||
@@ -6390,7 +6412,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
};
|
||||
Rng1S64 cursor_pixel_range =
|
||||
{
|
||||
cursor_off - (S64)(big_glyph_advance*4) - (S64)(margin_width_px + line_num_width_px),
|
||||
cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px),
|
||||
cursor_off + (S64)(big_glyph_advance*4),
|
||||
};
|
||||
S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min);
|
||||
@@ -6895,7 +6917,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//////////////////////////////
|
||||
//- rjf: calculate line-range-dependent info
|
||||
//
|
||||
F32 margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 priority_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
|
||||
TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &dasm_text_info, dasm_text_data, visible_line_num_range);
|
||||
|
||||
@@ -6936,7 +6959,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
if(has_disasm)
|
||||
{
|
||||
// rjf: fill basics
|
||||
code_slice_params.flags = DF_CodeSliceFlag_Margin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
|
||||
code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
|
||||
code_slice_params.line_num_range = visible_line_num_range;
|
||||
code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count);
|
||||
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count);
|
||||
@@ -6951,7 +6974,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
code_slice_params.tab_size = code_tab_size;
|
||||
code_slice_params.line_height_px = code_line_height;
|
||||
code_slice_params.search_query = search_query;
|
||||
code_slice_params.margin_width_px = margin_width_px;
|
||||
code_slice_params.priority_margin_width_px = priority_margin_width_px;
|
||||
code_slice_params.catchall_margin_width_px = catchall_margin_width_px;
|
||||
code_slice_params.line_num_width_px = line_num_width_px;
|
||||
code_slice_params.line_text_max_width_px = (F32)line_size_x;
|
||||
code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, process, DF_EntityKind_FlashMarker);
|
||||
@@ -7750,7 +7774,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
//////////////////////////////
|
||||
//- rjf: calculate line-range-dependent info
|
||||
//
|
||||
F32 margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 priority_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
|
||||
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
|
||||
TXTI_Slice slice = txti_slice_from_handle_line_range(scratch.arena, txti_handle, visible_line_num_range);
|
||||
|
||||
@@ -7793,7 +7818,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
code_slice_params.tab_size = code_tab_size;
|
||||
code_slice_params.line_height_px = code_line_height;
|
||||
code_slice_params.search_query = search_query;
|
||||
code_slice_params.margin_width_px = margin_width_px;
|
||||
code_slice_params.priority_margin_width_px = priority_margin_width_px;
|
||||
code_slice_params.catchall_margin_width_px = catchall_margin_width_px;
|
||||
code_slice_params.line_num_width_px = line_num_width_px;
|
||||
code_slice_params.line_text_max_width_px = (F32)line_size_x;
|
||||
code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker);
|
||||
@@ -8079,7 +8105,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
if(snap[Axis2_X])
|
||||
{
|
||||
String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line);
|
||||
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px);
|
||||
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px);
|
||||
Rng1S64 visible_pixel_range =
|
||||
{
|
||||
view->scroll_pos.x.idx,
|
||||
@@ -8087,7 +8113,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
};
|
||||
Rng1S64 cursor_pixel_range =
|
||||
{
|
||||
cursor_off - (S64)(big_glyph_advance*4) - (S64)(margin_width_px + line_num_width_px),
|
||||
cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px),
|
||||
cursor_off + (S64)(big_glyph_advance*4),
|
||||
};
|
||||
S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min);
|
||||
|
||||
@@ -54,6 +54,23 @@ d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *s
|
||||
list->total_size += str->string.size;
|
||||
}
|
||||
|
||||
internal void
|
||||
d_fancy_string_list_concat_in_place(D_FancyStringList *dst, D_FancyStringList *to_push)
|
||||
{
|
||||
if(dst->last != 0 && to_push->first != 0)
|
||||
{
|
||||
dst->last->next = to_push->first;
|
||||
dst->last = to_push->last;
|
||||
dst->node_count += to_push->node_count;
|
||||
dst->total_size += to_push->total_size;
|
||||
}
|
||||
else if(to_push->first != 0)
|
||||
{
|
||||
MemoryCopyStruct(dst, to_push);
|
||||
}
|
||||
MemoryZeroStruct(to_push);
|
||||
}
|
||||
|
||||
internal String8
|
||||
d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list)
|
||||
{
|
||||
|
||||
@@ -109,6 +109,7 @@ internal U64 d_hash_from_string(String8 string);
|
||||
//~ rjf: Fancy String Type Functions
|
||||
|
||||
internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str);
|
||||
internal void d_fancy_string_list_concat_in_place(D_FancyStringList *dst, D_FancyStringList *to_push);
|
||||
internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list);
|
||||
internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs);
|
||||
internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src);
|
||||
|
||||
@@ -180,7 +180,7 @@ global read_only TG_Type tg_type_nil =
|
||||
{
|
||||
/* kind */ TG_Kind_Null,
|
||||
/* flags */ 0,
|
||||
/* name */ {(U8*)"<nil>",5},
|
||||
/* name */ {(U8*)"???",3},
|
||||
};
|
||||
|
||||
global read_only TG_Type tg_type_variadic =
|
||||
|
||||
+25
-8
@@ -1155,7 +1155,13 @@ ui_end_build(void)
|
||||
|
||||
//- rjf: ensure special floating roots are within screen bounds
|
||||
UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root};
|
||||
B32 force_contain[] = {0, 1};
|
||||
B32 force_contain[] =
|
||||
{
|
||||
(ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) &&
|
||||
ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero()) &&
|
||||
ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero())),
|
||||
1,
|
||||
};
|
||||
for(U64 idx = 0; idx < ArrayCount(floating_roots); idx += 1)
|
||||
{
|
||||
UI_Box *root = floating_roots[idx];
|
||||
@@ -1164,11 +1170,10 @@ ui_end_build(void)
|
||||
Rng2F32 window_rect = os_client_rect_from_window(ui_window());
|
||||
Vec2F32 window_dim = dim_2f32(window_rect);
|
||||
Rng2F32 root_rect = root->rect;
|
||||
Vec2F32 root_rect_dim = dim_2f32(root_rect);
|
||||
Vec2F32 shift =
|
||||
{
|
||||
-ClampBot(0, root_rect.x1 - window_rect.x1) * (root_rect_dim.x < root->font_size*15.f || force_contain[idx]),
|
||||
-ClampBot(0, root_rect.y1 - window_rect.y1) * (root_rect_dim.y < root->font_size*15.f || force_contain[idx]),
|
||||
-ClampBot(0, root_rect.x1 - window_rect.x1) * (force_contain[idx]),
|
||||
-ClampBot(0, root_rect.y1 - window_rect.y1) * (force_contain[idx]),
|
||||
};
|
||||
Rng2F32 new_root_rect = shift_2f32(root_rect, shift);
|
||||
root->fixed_position = new_root_rect.p0;
|
||||
@@ -1420,14 +1425,22 @@ ui_end_build(void)
|
||||
{
|
||||
if(b->flags & UI_BoxFlag_DrawText && !(b->flags & UI_BoxFlag_DisableTextTrunc))
|
||||
{
|
||||
Rng2F32 rect = b->rect;
|
||||
for(UI_Box *p = b->parent; !ui_box_is_nil(p); p = p->parent)
|
||||
{
|
||||
if(p->flags & UI_BoxFlag_Clip)
|
||||
{
|
||||
rect = intersect_2f32(rect, p->rect);
|
||||
}
|
||||
}
|
||||
String8 box_display_string = ui_box_display_string(b);
|
||||
Vec2F32 text_pos = ui_box_text_position(b);
|
||||
Vec2F32 drawn_text_dim = b->display_string_runs.dim;
|
||||
B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > b->rect.x1);
|
||||
B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > rect.x1);
|
||||
B32 mouse_is_hovering = contains_2f32(r2f32p(text_pos.x,
|
||||
b->rect.y0,
|
||||
Min(text_pos.x+drawn_text_dim.x, b->rect.x1),
|
||||
b->rect.y1),
|
||||
rect.y0,
|
||||
Min(text_pos.x+drawn_text_dim.x, rect.x1),
|
||||
rect.y1),
|
||||
ui_state->mouse);
|
||||
if(text_is_truncated && mouse_is_hovering)
|
||||
{
|
||||
@@ -1443,6 +1456,10 @@ ui_end_build(void)
|
||||
goto break_all_hover_string;
|
||||
}
|
||||
}
|
||||
if(b != box && ui_key_match(b->key, ui_hot_key()))
|
||||
{
|
||||
goto break_all_hover_string;
|
||||
}
|
||||
if(b != box && contains_2f32(b->rect, ui_state->mouse) && b->flags & UI_BoxFlag_DrawText)
|
||||
{
|
||||
goto break_all_hover_string;
|
||||
|
||||
Reference in New Issue
Block a user