UI debug break

This commit is contained in:
jacob 2026-03-30 01:16:24 -05:00
parent 629d03a24e
commit ee3ffdb02a
8 changed files with 165 additions and 55 deletions

View File

@ -154,12 +154,13 @@
#if IsRtcEnabled
#define Assert(cond) ((cond) ? 1 : (IsRunningInDebugger() ? (*(volatile i32 *)0 = 0) : Panic(Lit(__FILE__ ":" Stringize(__LINE__) ":0: assertion failed: "Stringize(cond)""))))
#if IsCompilerMsvc
#define DEBUGBREAK __debugbreak()
#define DEBUGBREAK do { if (IsRunningInDebugger()) __debugbreak(); } while (0)
#else
#define DEBUGBREAK __builtin_debugtrap()
#define DEBUGBREAK do { if (IsRunningInDebugger()) __builtin_debugtrap(); } while (0)
#endif
#define DEBUGBREAKABLE { volatile i32 __DEBUGBREAKABLE_VAR = 0; __DEBUGBREAKABLE_VAR; } (void)0
#else
#define DEBUGBREAK
#define Assert(cond) (void)(0)
#endif

View File

@ -108,7 +108,12 @@ String StringFromButton(Button button)
return name;
}
b32 IsMouseButton(Button button)
b32 IsMouseClickButton(Button button)
{
return button >= Button_M1 && button <= Button_M3;
}
b32 IsAnyMouseButton(Button button)
{
return button >= Button_M1 && button <= Button_MWheelDown;
}

View File

@ -160,4 +160,5 @@ Struct(ControllerEventsArray)
//~ Button helpers
String StringFromButton(Button button);
b32 IsMouseButton(Button button);
b32 IsMouseClickButton(Button button);
b32 IsAnyMouseButton(Button button);

View File

@ -292,6 +292,10 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas)
{
tb->end = 0;
}
else if (!(delta.flags & V_TextboxDeltaFlag_NavSelect) && tb->end != tb->start)
{
tb->end = MinI64(tb->end, tb->start);
}
else if (delta.flags & V_TextboxDeltaFlag_NavWord)
{
if (tb->end > 0 && tb->text32[tb->end - 1] == ' ')
@ -318,6 +322,10 @@ void V_ApplyTextboxDeltas(V_TextboxState *tb, V_TextboxDeltaList deltas)
{
tb->end = I64Max;
}
else if (!(delta.flags & V_TextboxDeltaFlag_NavSelect) && tb->end != tb->start)
{
tb->end = MaxI64(tb->end, tb->start);
}
else if (delta.flags & V_TextboxDeltaFlag_NavWord)
{
if (tb->end < tb->len && tb->text32[tb->end] == ' ')
@ -889,6 +897,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_ResetArena(cl, gpu_frame_arena);
// Persist state
CopyBytes(frame->real_held_buttons, prev_frame->real_held_buttons, sizeof(frame->real_held_buttons));
CopyBytes(frame->held_buttons, prev_frame->held_buttons, sizeof(frame->held_buttons));
frame->palette = prev_frame->palette;
frame->is_editing = prev_frame->is_editing;
@ -1114,24 +1123,44 @@ void V_TickForever(WaveLaneCtx *lane)
frame->has_keyboard_focus = 0;
}
//- Reset held buttons
//- Clear held buttons
b32 is_typing = !UI_IsKeyNil(prev_frame->text_input_focus);
for (Button btn = 0; btn < countof(frame->real_held_buttons); ++btn)
{
b32 clear = 0;
{
if (IsMouseClickButton(btn) && !frame->has_mouse_focus)
{
clear = 1;
}
if (!IsAnyMouseButton(btn) && !frame->has_keyboard_focus)
{
clear = 1;
}
}
if (clear)
{
frame->real_held_buttons[btn] = 0;
}
}
for (Button btn = 0; btn < countof(frame->held_buttons); ++btn)
{
if (btn == Button_M1 || btn == Button_M2 || btn == Button_M3)
b32 clear = 0;
{
if (!frame->has_mouse_focus)
if (IsMouseClickButton(btn) && !frame->has_mouse_focus)
{
clear = 1;
}
if (!IsAnyMouseButton(btn) && (!frame->has_keyboard_focus || is_typing))
{
clear = 1;
}
}
if (clear)
{
frame->held_buttons[btn] = 0;
}
}
else
{
if (!frame->has_keyboard_focus)
{
frame->held_buttons[btn] = 0;
}
}
}
//- Convert events into cmds
for (u64 cev_idx = 0; cev_idx < window_frame.controller_events.count; ++cev_idx)
@ -1164,9 +1193,9 @@ void V_TickForever(WaveLaneCtx *lane)
{
V_Hotkey hotkey = Zi;
hotkey.button = cev->button;
hotkey.ctrl = frame->held_buttons[Button_Ctrl];
hotkey.shift = frame->held_buttons[Button_Shift];
hotkey.alt = frame->held_buttons[Button_Alt];
hotkey.ctrl = frame->real_held_buttons[Button_Ctrl];
hotkey.shift = frame->real_held_buttons[Button_Shift];
hotkey.alt = frame->real_held_buttons[Button_Alt];
{
u64 hotkey_hash = HashString(StringFromStruct(&hotkey));
V_ShortcutBin *bin = &shortcut_bins[hotkey_hash % shortcut_bins_count];
@ -1203,7 +1232,7 @@ void V_TickForever(WaveLaneCtx *lane)
{
delta.flags |= V_TextboxDeltaFlag_NavRight | V_TextboxDeltaFlag_NavLine;
}
if (down && cev->button == Button_A && frame->held_buttons[Button_Ctrl])
if (down && cev->button == Button_A && frame->real_held_buttons[Button_Ctrl])
{
delta.flags |= V_TextboxDeltaFlag_NavSelect | V_TextboxDeltaFlag_NavDirect;
delta.direct_start = 0;
@ -1219,26 +1248,26 @@ void V_TickForever(WaveLaneCtx *lane)
delta.text = Lit("");
delta.flags |= V_TextboxDeltaFlag_OnlyNavIfSelectionEmpty | V_TextboxDeltaFlag_NavSelect | V_TextboxDeltaFlag_NavRight | V_TextboxDeltaFlag_UpdateText;
}
if (down && cev->button == Button_C && frame->held_buttons[Button_Ctrl])
if (down && cev->button == Button_C && frame->real_held_buttons[Button_Ctrl])
{
delta.flags |= V_TextboxDeltaFlag_CopySelectionToClipboard;
}
else if (down && cev->button == Button_V && frame->held_buttons[Button_Ctrl])
else if (down && cev->button == Button_V && frame->real_held_buttons[Button_Ctrl])
{
delta.flags |= V_TextboxDeltaFlag_InheritTextFromClipboard | V_TextboxDeltaFlag_UpdateText;
}
else if (text.len > 0 && !MatchString(text, Lit("\n")) && !MatchString(text, Lit("\t")) && !MatchString(text, Lit("\r")))
else if (text.len > 0 && !frame->real_held_buttons[Button_Alt] && !MatchString(text, Lit("\n")) && !MatchString(text, Lit("\t")) && !MatchString(text, Lit("\r")))
{
delta.flags |= V_TextboxDeltaFlag_UpdateText;
delta.text = text;
}
if (delta.flags)
{
if (frame->held_buttons[Button_Shift])
if (frame->real_held_buttons[Button_Shift])
{
delta.flags |= V_TextboxDeltaFlag_NavSelect;
}
if (frame->held_buttons[Button_Ctrl])
if (frame->real_held_buttons[Button_Ctrl])
{
delta.flags |= V_TextboxDeltaFlag_NavWord;
}
@ -1252,9 +1281,13 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
}
frame->real_held_buttons[hotkey.button] = down;
if (IsMouseClickButton(hotkey.button) || !is_typing)
{
frame->held_buttons[hotkey.button] = down;
}
}
}
//- Compute mouse delta from events
for (u64 cev_idx = 0; cev_idx < window_frame.controller_events.count; ++cev_idx)
@ -4379,7 +4412,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Push(Tag, HashF("developer command palette"));
UI_Size total_width = UI_FNT(40, 1);
UI_Size total_height = UI_FNT(40, 1);
UI_Size total_height = UI_FNT(30, 1);
UI_Size header_height = UI_FNT(1.3, 1);
UI_Size window_padding = UI_FNT(0.5, 1);
UI_Size icon_col_width = UI_FNT(1.75, 1);
@ -4393,7 +4426,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Key thumb_key = UI_KeyF("scrollbar thumb");
UI_Key scrollbar_up_key = UI_KeyF("scrollbar up");
UI_Key scrollbar_down_key = UI_KeyF("scrollbar down");
UI_Key scrollbar_container_key = UI_KeyF("scrollbar container");
UI_Key track_key = UI_KeyF("scrollbar track");
UI_BoxReports scrollbar_reps = UI_ReportsFromKey(scrollbar_key);
UI_BoxReports thumb_reps = UI_ReportsFromKey(thumb_key);
@ -4401,7 +4434,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_BoxReports lister_reps = UI_ReportsFromKey(lister_key);
UI_BoxReports scrollbar_up_reps = UI_ReportsFromKey(scrollbar_up_key);
UI_BoxReports scrollbar_down_reps = UI_ReportsFromKey(scrollbar_down_key);
UI_BoxReports scrollbar_container_reps = UI_ReportsFromKey(scrollbar_container_key);
UI_BoxReports track_reps = UI_ReportsFromKey(track_key);
f32 lister_start = lister_reps.draw.screen_rect.p0.y;
f32 lister_end = lister_reps.draw.screen_rect.p1.y;
@ -4411,9 +4444,9 @@ void V_TickForever(WaveLaneCtx *lane)
f32 scissor_end = scissor_reps.draw.screen_rect.p1.y;
f32 scissor_height = MaxF32(scissor_end - scissor_start, 1);
f32 scrollbar_container_start = scrollbar_container_reps.draw.screen_rect.p0.y;
f32 scrollbar_container_end = scrollbar_container_reps.draw.screen_rect.p1.y;
f32 scrollbar_container_height = MaxF32(scrollbar_container_end - scrollbar_container_start, 1);
f32 track_start = track_reps.draw.screen_rect.p0.y;
f32 track_end = track_reps.draw.screen_rect.p1.y;
f32 track_height = MaxF32(track_end - track_start, 1);
f32 thumb_start = thumb_reps.draw.screen_rect.p0.y;
f32 thumb_end = thumb_reps.draw.screen_rect.p1.y;
@ -4424,15 +4457,20 @@ void V_TickForever(WaveLaneCtx *lane)
if (thumb_reps.draw.m1.downs)
{
palette->drag_lister = lister_reps.draw.screen_rect;
palette->drag_container = scrollbar_container_reps.draw.screen_rect;
palette->drag_scissor = scissor_reps.draw.screen_rect;
palette->drag_track = track_reps.draw.screen_rect;
palette->drag_thumb = thumb_reps.draw.screen_rect;
palette->drag_cursor = frame->screen_cursor;
palette->drag_scroll = palette->scroll;
}
if (thumb_reps.draw.m1.held)
{
f32 delta_ratio = (frame->screen_cursor.y - palette->drag_cursor.y) / (palette->drag_container.p1.y - palette->drag_container.p0.y);
palette->scroll = palette->drag_scroll + delta_ratio * (palette->drag_lister.p1.y - palette->drag_lister.p0.y);
f32 drag_track_height = palette->drag_track.p1.y - palette->drag_track.p0.y;
f32 drag_thumb_height = palette->drag_thumb.p1.y - palette->drag_thumb.p0.y;
f32 drag_scroll_height = (palette->drag_lister.p1.y - palette->drag_lister.p0.y) - (palette->drag_scissor.p1.y - palette->drag_scissor.p0.y);
f32 delta_ratio = (frame->screen_cursor.y - palette->drag_cursor.y) / (drag_track_height - drag_thumb_height);
palette->scroll = palette->drag_scroll + delta_ratio * drag_scroll_height;
}
palette->scroll = ClampF32(palette->scroll, 0, scroll_height);
}
@ -4440,10 +4478,10 @@ void V_TickForever(WaveLaneCtx *lane)
f32 scroll_ratio = palette->scroll / scroll_height;
f32 lister_offset = scroll_ratio * scroll_height;
f32 new_thumb_size_ratio = scissor_height / lister_height;
f32 new_thumb_start = scroll_ratio * scrollbar_container_height - scroll_ratio * thumb_height;
f32 new_thumb_height = track_height * (scissor_height / lister_height);
f32 new_thumb_start = scroll_ratio * track_height - scroll_ratio * thumb_height;
b32 scrollbar_visible = new_thumb_size_ratio < 1;
b32 scrollbar_visible = new_thumb_height < track_height;
@ -4552,7 +4590,7 @@ void V_TickForever(WaveLaneCtx *lane)
//- Build searchbox
b32 is_searching = 0;
String search_text = Zi;
String search_pattern = Zi;
{
UI_Size search_height = UI_PIX(item_size_px * 1.25, 1);
@ -4587,7 +4625,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_BoxReport search_report = UI_ReportsFromKey(search_box).draw;
V_TextboxState *search_state = &palette->search_state;
b32 has_focus = UI_MatchKey(search_box, prev_frame->keyboard_focus_box);
b32 has_focus = UI_MatchKey(search_box, prev_frame->text_input_focus);
// FIXME: Remove this
has_focus = 1;
@ -4599,6 +4637,11 @@ void V_TickForever(WaveLaneCtx *lane)
V.text_input_ns = frame->time_ns;
}
if (!palette->is_showing)
{
has_focus = 0;
}
if (search_report.is_hot)
{
WND_SetCursor(window_frame, WND_CursorKind_Text);
@ -4606,7 +4649,7 @@ void V_TickForever(WaveLaneCtx *lane)
if (has_focus)
{
frame->keyboard_focus_box = search_box;
frame->text_input_focus = search_box;
if (text_input_deltas.first)
{
V.text_input_ns = frame->time_ns;
@ -4641,7 +4684,8 @@ void V_TickForever(WaveLaneCtx *lane)
search_text = V_StringFromTextbox(frame->arena, search_state);
String search_text = V_StringFromTextbox(frame->arena, search_state);
search_pattern = LowerString(frame->arena, search_text);
is_searching = search_text.len != 0;
@ -4875,6 +4919,25 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
//////////////////////////////
//- Prune non-matching items
if (is_searching)
{
for (PaletteItem *item = first_item; item;)
{
PaletteItem *next = item->next;
{
b32 prune = !StringContains(LowerString(frame->arena, item->display_name), search_pattern);
if (prune)
{
DllQueueRemove(first_item, last_item, item);
}
}
item = next;
}
}
//////////////////////////////
//- Build items
@ -5239,7 +5302,8 @@ void V_TickForever(WaveLaneCtx *lane)
Vec4 col = theme.col.hint;
Vec4 bd_col = Zi;
col = LerpSrgb(col, theme.col.button_active, scrollbar_up_reps.draw.active);
bd_col = LerpSrgb(bd_col, theme.col.button_active, scrollbar_up_reps.draw.hot);
bd_col = LerpSrgb(bd_col, theme.col.button_hot, scrollbar_up_reps.draw.hot);
bd_col = LerpSrgb(bd_col, theme.col.button_active, scrollbar_up_reps.draw.active);
UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetNext(BorderColor, bd_col);
UI_SetNext(BorderSize, 1);
@ -5254,8 +5318,8 @@ void V_TickForever(WaveLaneCtx *lane)
//- Scrollbar thumb
{
// UI_SetNext(
UI_PushCP(UI_BuildBoxEx(scrollbar_container_key));
UI_SetNext(Height, UI_GROW(1, 0));
UI_PushCP(UI_BuildBoxEx(track_key));
{
Vec4 bg = theme.col.button_hot;
Vec4 bd = bg;
@ -5264,14 +5328,15 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(BackgroundColor, bg);
UI_SetNext(Width, UI_GROW(1, 0));
UI_SetNext(Height, UI_GROW(new_thumb_size_ratio, 1));
UI_SetNext(Height, UI_PIX(new_thumb_height, 1));
UI_SetNext(BorderSize, 1);
UI_SetNext(BorderColor, bd);
UI_SetNext(Rounding, UI_RGROW(1 * theme.rounding));
UI_SetNext(FloatingPos, VEC2(0, new_thumb_start));
UI_SetNext(Anchor, UI_Region_Center);
UI_SetNext(Anchor, UI_Region_Top);
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_Floating);
// UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_Floating);
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse | UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClampY);
UI_SetNext(Anchor, UI_Region_Top);
UI_BuildBoxEx(thumb_key);
}
@ -5283,7 +5348,8 @@ void V_TickForever(WaveLaneCtx *lane)
Vec4 col = theme.col.hint;
Vec4 bd_col = Zi;
col = LerpSrgb(col, theme.col.button_active, scrollbar_down_reps.draw.active);
bd_col = LerpSrgb(bd_col, theme.col.button_active, scrollbar_down_reps.draw.hot);
bd_col = LerpSrgb(bd_col, theme.col.button_hot, scrollbar_down_reps.draw.hot);
bd_col = LerpSrgb(bd_col, theme.col.button_active, scrollbar_down_reps.draw.active);
UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetNext(BorderColor, bd_col);
UI_SetNext(BorderSize, 1);
@ -5604,10 +5670,6 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Build debug info UI

View File

@ -224,7 +224,9 @@ Struct(V_Palette)
// f32 drag_scrollbar_container_end;
Rng2 drag_lister;
Rng2 drag_container;
Rng2 drag_scissor;
Rng2 drag_track;
Rng2 drag_thumb;
Vec2 drag_cursor;
f32 drag_scroll;
@ -342,10 +344,11 @@ Struct(V_Frame)
f64 blend_sim_tick;
f64 blend_predict_tick;
Button held_buttons[Button_COUNT];
Button held_buttons[Button_COUNT]; // User input state captured for gameplay
Button real_held_buttons[Button_COUNT]; // Actual state of user input regardless of keyboard / mouse focus
V_Palette palette;
UI_Key keyboard_focus_box;
UI_Key text_input_focus;
String window_restore;

View File

@ -484,6 +484,7 @@ UI_Key UI_BuildBoxEx(UI_Key semantic_key)
n->cmd.box.is_transient = is_transient;
n->cmd.box.parent = UI_Top(Parent);
n->cmd.box.flags = (UI_Top(Flags) | UI_Top(OrFlags)) & ~UI_Top(OmitFlags);
n->cmd.box.debug_break_flags = UI_Top(DebugBreakFlags);
n->cmd.box.pref_semantic_dims[Axis_X] = UI_Top(Width);
n->cmd.box.pref_semantic_dims[Axis_Y] = UI_Top(Height);
n->cmd.box.scale = UI_Top(Scale);
@ -668,7 +669,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
is_cursor_in_box = non_corner_edge_dist >= 0 && corner_edge_dist >= 0;
}
report->is_hovered = is_cursor_in_box;
if (top_hovered_box == 0 && box->desc.flags & UI_BoxFlag_CaptureMouse && is_cursor_in_box)
if (top_hovered_box == 0 && (box->desc.flags & UI_BoxFlag_CaptureMouse) && is_cursor_in_box)
{
top_hovered_box = box;
}
@ -1109,6 +1110,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
UI_Box *box = ir.box;
if (ir.pre)
{
UI_DebugBreak(box, UI_DebugBreakFlag_Prep);
box->pre_index = pre_index;
boxes_pre[pre_index] = box;
pre_index += 1;
@ -1143,6 +1146,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_IndependentSolve);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
UI_Size size = box->desc.pref_semantic_dims[axis];
@ -1177,6 +1181,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveLayoutAxis);
if (box->parent)
{
Axis axis = box->parent->desc.child_layout_axis;
@ -1211,6 +1216,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
{
UI_Box *box = boxes_post[post_index];
UI_DebugBreak(box, UI_DebugBreakFlag_DownwardsDependentSolve);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
UI_Size size = box->desc.pref_semantic_dims[axis];
@ -1241,6 +1247,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveNonLayoutAxis);
if (box->parent)
{
Axis axis = !box->parent->desc.child_layout_axis;
@ -1256,6 +1263,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_SolveViolations);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
f32 box_size = box->solved_dims.v[axis];
@ -1338,6 +1346,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_FinalSolve);
UI_Box *parent = box->parent;
// TODO: Distinguish between baseline alignment & visual alignment
@ -1356,8 +1366,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
f32 scaled_size = 0;
if (box->solved_scale.v[axis] == 1)
{
// scaled_size = RoundF32(unscaled_size);
scaled_size = unscaled_size;
scaled_size = RoundF32(unscaled_size);
// scaled_size = unscaled_size;
}
else
{
@ -1561,6 +1571,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_BuildGpuData);
GC_Run raw_run_unscaled = box->glyph_run;
GC_Run raw_run = UI_ScaleRun(frame->arena, raw_run_unscaled, box->solved_scale);

View File

@ -95,6 +95,24 @@ Enum(UI_BoxFlag)
UI_BoxFlag_Scissor = (1 << 6),
};
////////////////////////////////////////////////////////////
//~ Debug breakpoint flags
Enum(UI_DebugBreakFlag)
{
UI_DebugBreakFlag_None = 0,
UI_DebugBreakFlag_Prep = (1 << 0),
UI_DebugBreakFlag_IndependentSolve = (1 << 1),
UI_DebugBreakFlag_UpwardsDependentSolveLayoutAxis = (1 << 2),
UI_DebugBreakFlag_DownwardsDependentSolve = (1 << 3),
UI_DebugBreakFlag_UpwardsDependentSolveNonLayoutAxis = (1 << 4),
UI_DebugBreakFlag_SolveViolations = (1 << 5),
UI_DebugBreakFlag_FinalSolve = (1 << 6),
UI_DebugBreakFlag_BuildGpuData = (1 << 7),
UI_DebugBreakFlag_All = 0xFFFFFFFF
};
////////////////////////////////////////////////////////////
//~ Style types
@ -102,6 +120,7 @@ Enum(UI_BoxFlag)
X(OmitFlags, UI_BoxFlag) \
X(OrFlags, UI_BoxFlag) \
X(Flags, UI_BoxFlag) \
X(DebugBreakFlags, UI_DebugBreakFlag) \
X(Parent, UI_Key) \
X(Tag, u64) \
X(ChildLayoutAxis, Axis) \
@ -236,6 +255,7 @@ Enum(UI_CmdKind)
Struct(UI_BoxDesc)
{
UI_BoxFlag flags;
UI_DebugBreakFlag debug_break_flags;
UI_Key key;
UI_Key parent;
@ -518,6 +538,12 @@ UI_Key UI_BuildBoxEx(UI_Key semantic_key);
void UI_SetRawTexture(UI_Key key, G_TextureRef tex, Rng2 uv);
#if IsRtcEnabled
#define UI_DebugBreak(box, target_flags) do { if (box->desc.debug_break_flags & target_flags) { DEBUGBREAK; } } while (0)
#else
#define UI_DebugBreak(...)
#endif
////////////////////////////////////////////////////////////
//~ Report

View File

@ -102,7 +102,7 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
//- Scissor
// FIXME: Inclusive
if (p.x < rect.scissor.p0.x || p.x > rect.scissor.p1.x || p.y < rect.scissor.p0.y || p.y > rect.scissor.p1.y)
if (p.x < rect.scissor.p0.x || p.x >= rect.scissor.p1.x || p.y < rect.scissor.p0.y || p.y >= rect.scissor.p1.y)
{
result = 0;
}