Skip to documentation
SLOP

tiny.gui.visual

Reference tiny.gui visual

Defined in tiny.gui.

API (7)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstiny.guivisual
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callersvisualdrawWidgetChromevisualdrawFrame
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsvisualdrawFrametest sourcelib.gui.src.visualtest: widget chrome blits image paint...test sourcelib.gui.src.visualtest: widget chrome clips to visible ...test sourcelib.gui.src.visualtest: widget chrome contains checked ...test sourcelib.gui.src.visualtest: widget chrome emits configured ...+3 moreprivate sourcelib.gui.src.visualalphaprivate sourcelib.gui.src.visualalphaUnitprivate sourcelib.gui.src.visualbackgroundColorprivate sourcelib.gui.src.visualborderColorprivate sourcelib.gui.src.visualdrawEdgeBorders+12 morevisualdrawWidgetChrome
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsvisualdrawWidgetChromeprivate sourcelib.gui.src.visualedgeVisibleprivate sourcelib.gui.src.visualshadowVisiblevisualwidgetHasVisibleChrome
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/gui/src/root.zig:15

zig
pub const visual = @import("visual.zig");

Source: lib/gui/src/visual.zig

zig
const std = @import("std");const layout = @import("arrange");const model = @import("model.zig");pub const Rect = layout.Rect;pub const Color = model.UiColor;const WidgetFrame = model.WidgetFrame;pub const Palette = struct {    panel: Color = .{ .r = 246, .g = 247, .b = 249, .a = 255 },    panel_alt: Color = .{ .r = 235, .g = 238, .b = 242, .a = 255 },    text: Color = .{ .r = 28, .g = 32, .b = 36, .a = 255 },    muted: Color = .{ .r = 99, .g = 108, .b = 118, .a = 255 },    border: Color = .{ .r = 190, .g = 197, .b = 205, .a = 255 },    accent: Color = .{ .r = 30, .g = 96, .b = 184, .a = 255 },    danger: Color = .{ .r = 184, .g = 54, .b = 54, .a = 255 },    focus_fill: Color = .{ .r = 30, .g = 96, .b = 184, .a = 36 },    hover_fill: Color = .{ .r = 30, .g = 96, .b = 184, .a = 22 },    selected_fill: Color = .{ .r = 30, .g = 96, .b = 184, .a = 44 },};pub const Options = struct {    origin_x: f32 = 0,    origin_y: f32 = 0,    palette: Palette = .{},    layer: u8 = 0,};pub fn drawFrame(writer: anytype, frame: model.UiFrame, root_id: u64, options: Options) void {    for (frame.widgets) |widget| {        if (widget.root_id != root_id) continue;        if (widget.layer != options.layer) continue;        writer.beginWidgetFragment(widget.root_id, widget.widget_id);        drawWidgetChrome(writer, widget, options);        writer.endFragment();    }}pub fn drawWidgetChrome(writer: anytype, widget: WidgetFrame, options: Options) void {    if (!widgetHasVisibleChrome(widget)) return;    const rect = offsetRect(widget.rect, options);    const visible = offsetRect(widget.visible_rect, options);    if (isEmpty(rect) or isEmpty(visible)) return;    const needs_clip = !sameRect(rect, visible);    if (needs_clip) writer.beginClip(visible);    defer if (needs_clip) writer.endClip();    var background = if (widget.paint.linear_gradient == null)        backgroundColor(widget, options.palette)    else        null;    var border = borderColor(widget, options.palette);    const roundness = @max(widget.paint.corner_roundness, 0);    if (hasState(widget, model.ui_state_selected)) {        const base = background orelse options.palette.panel_alt;        var blended = mix(options.palette.selected_fill, base, alphaUnit(options.palette.selected_fill));        blended.a = base.a;        background = blended;    }    if (hasState(widget, model.ui_state_danger)) {        border = options.palette.danger;    }    if (hasState(widget, model.ui_state_disabled)) {        background = mix(options.palette.panel_alt, background orelse options.palette.panel, 0.55);        border = alpha(border orelse options.palette.border, 120);    }    drawShadow(writer, rect, roundness, widget.paint.shadow);    if (widget.paint.linear_gradient) |gradient| {        writer.fillLinearGradient(rect, roundness, 6, gradient);        if (hasState(widget, model.ui_state_selected)) {            fillPaintedRect(writer, rect, roundness, options.palette.selected_fill);        }    } else if (background) |color| {        fillPaintedRect(writer, rect, roundness, color);    }    if (widget.paint.image) |image| drawImagePaint(writer, rect, image);    const focus_visible = widget.focused and !hasState(widget, model.ui_state_disabled);    if (border) |color| {        if (!focus_visible) strokePaintedRect(writer, rect, roundness, @max(widget.paint.border_width, 1), color);    }    drawEdgeBorders(writer, rect, widget);    drawSemanticState(writer, rect, roundness, widget, options.palette);    drawInteractionState(writer, rect, roundness, widget, options.palette);}fn drawImagePaint(writer: anytype, rect: Rect, image: model.UiImagePaint) void {    if (image.tint) |tint| {        writer.drawGlyph(rect, image.index, image.source, tint);        return;    }    writer.drawImage(rect, image.index, image.source, image.opacity);}pub fn widgetHasVisibleChrome(widget: WidgetFrame) bool {    if (widget.paint.background != null) return true;    if (widget.paint.linear_gradient != null) return true;    if (widget.paint.image != null) return true;    if (widget.paint.border != null and widget.paint.border_width > 0) return true;    if (edgeVisible(widget.paint.border_edges.top)) return true;    if (edgeVisible(widget.paint.border_edges.right)) return true;    if (edgeVisible(widget.paint.border_edges.bottom)) return true;    if (edgeVisible(widget.paint.border_edges.left)) return true;    if (shadowVisible(widget.paint.shadow)) return true;    if (widget.kind == .button or widget.kind == .text_input) return true;    if (widget.state_flags != 0) return true;    if (widget.hovered or widget.focused or widget.captured) return true;    return false;}fn alphaUnit(color: Color) f32 {    return @as(f32, @floatFromInt(color.a)) / 255.0;}fn backgroundColor(widget: WidgetFrame, palette: Palette) ?Color {    if (widget.paint.background) |color| return color;    return switch (widget.kind) {        .button => alpha(palette.panel_alt, 220),        .text_input => alpha(palette.panel, 245),        else => null,    };}fn borderColor(widget: WidgetFrame, palette: Palette) ?Color {    if (widget.paint.border) |color| return color;    if (widget.paint.background != null or widget.paint.linear_gradient != null) return null;    return switch (widget.kind) {        .button, .text_input => alpha(palette.border, 190),        else => null,    };}fn drawSemanticState(writer: anytype, rect: Rect, roundness: f32, widget: WidgetFrame, palette: Palette) void {    if (hasState(widget, model.ui_state_selected)) {        writer.fillRect(.{ .x = rect.x, .y = rect.y, .width = @min(3, rect.width), .height = rect.height }, palette.accent);    }    if (hasState(widget, model.ui_state_default)) {        writer.fillRect(.{ .x = rect.x + 4, .y = rect.y, .width = @max(rect.width - 8, 0), .height = @min(2, rect.height) }, alpha(palette.accent, 190));    }    if (hasState(widget, model.ui_state_expanded)) {        writer.fillRect(.{ .x = rect.x + rect.width - 7, .y = rect.y + 6, .width = 3, .height = @max(rect.height - 12, 0) }, alpha(palette.accent, 170));    }    if (hasState(widget, model.ui_state_checked)) {        const mark = Rect{ .x = rect.x + rect.width - 12, .y = rect.y + 6, .width = 6, .height = 6 };        writer.fillRect(mark, palette.accent);        writer.fillRect(.{ .x = mark.x + 2, .y = mark.y + 2, .width = @max(mark.width - 2, 0), .height = 2 }, palette.accent);    }    if (hasState(widget, model.ui_state_disabled)) {        fillPaintedRect(writer, inset(rect, 1, 1), insetRoundness(roundness, 1), alpha(palette.panel, 92));    }}fn drawInteractionState(writer: anytype, rect: Rect, roundness: f32, widget: WidgetFrame, palette: Palette) void {    if (hasState(widget, model.ui_state_disabled)) return;    if (widget.captured) fillPaintedRect(writer, inset(rect, 1, 1), insetRoundness(roundness, 1), alpha(palette.accent, 42));    if (widget.hovered) fillPaintedRect(writer, inset(rect, 1, 1), insetRoundness(roundness, 1), palette.hover_fill);    if (widget.focused) {        fillPaintedRect(writer, inset(rect, 2, 2), insetRoundness(roundness, 2), palette.focus_fill);        strokePaintedRect(            writer,            inset(rect, -2, -2),            insetRoundness(roundness, -2),            1.4,            alpha(palette.accent, 220),        );    }}fn drawEdgeBorders(writer: anytype, rect: Rect, widget: WidgetFrame) void {    drawTopEdge(writer, rect, widget.paint.border_edges.top);    drawRightEdge(writer, rect, widget.paint.border_edges.right);    drawBottomEdge(writer, rect, widget.paint.border_edges.bottom);    drawLeftEdge(writer, rect, widget.paint.border_edges.left);}fn drawTopEdge(writer: anytype, rect: Rect, edge: model.UiBorderEdgePaint) void {    const color = edgeColor(edge) orelse return;    if (edge.width <= 0) return;    writer.fillRect(.{ .x = rect.x, .y = rect.y, .width = rect.width, .height = edge.width }, color);}fn drawRightEdge(writer: anytype, rect: Rect, edge: model.UiBorderEdgePaint) void {    const color = edgeColor(edge) orelse return;    if (edge.width <= 0) return;    writer.fillRect(.{ .x = rect.x + rect.width - edge.width, .y = rect.y, .width = edge.width, .height = rect.height }, color);}fn drawBottomEdge(writer: anytype, rect: Rect, edge: model.UiBorderEdgePaint) void {    const color = edgeColor(edge) orelse return;    if (edge.width <= 0) return;    writer.fillRect(.{ .x = rect.x, .y = rect.y + rect.height - edge.width, .width = rect.width, .height = edge.width }, color);}fn drawLeftEdge(writer: anytype, rect: Rect, edge: model.UiBorderEdgePaint) void {    const color = edgeColor(edge) orelse return;    if (edge.width <= 0) return;    writer.fillRect(.{ .x = rect.x, .y = rect.y, .width = edge.width, .height = rect.height }, color);}fn drawShadow(writer: anytype, rect: Rect, roundness: f32, shadow: model.UiShadowPaint) void {    const color = shadow.color orelse return;    if (color.a == 0 or isEmpty(rect)) return;    writer.shadowRoundedRect(rect, roundness, @max(shadow.blur_radius, 0), @max(shadow.spread, 0), shadow.offset_x, shadow.offset_y, color);}fn fillPaintedRect(writer: anytype, rect: Rect, roundness: f32, color: Color) void {    if (color.a == 0 or isEmpty(rect)) return;    if (roundness > 0) {        writer.fillRoundedRect(rect, roundness, 6, color);    } else {        writer.fillRect(rect, color);    }}fn strokePaintedRect(writer: anytype, rect: Rect, roundness: f32, width: f32, color: Color) void {    if (color.a == 0 or width <= 0 or isEmpty(rect)) return;    if (roundness > 0) {        writer.strokeRoundedRect(rect, roundness, 6, width, color);    } else {        writer.strokeRect(rect, width, color);    }}fn edgeVisible(edge: model.UiBorderEdgePaint) bool {    return edge.color != null and edge.width > 0;}fn shadowVisible(shadow: model.UiShadowPaint) bool {    const color = shadow.color orelse return false;    return color.a != 0;}fn edgeColor(edge: model.UiBorderEdgePaint) ?Color {    if (edge.color) |color| return color;    return null;}fn offsetRect(rect: Rect, options: Options) Rect {    return .{        .x = options.origin_x + rect.x,        .y = options.origin_y + rect.y,        .width = rect.width,        .height = rect.height,    };}fn inset(rect: Rect, dx: f32, dy: f32) Rect {    return .{        .x = rect.x + dx,        .y = rect.y + dy,        .width = @max(rect.width - dx * 2, 0),        .height = @max(rect.height - dy * 2, 0),    };}fn insetRoundness(roundness: f32, amount: f32) f32 {    return @max(roundness - amount, 0);}fn sameRect(left: Rect, right: Rect) bool {    return left.x == right.x and left.y == right.y and left.width == right.width and left.height == right.height;}fn isEmpty(rect: Rect) bool {    return rect.width <= 0 or rect.height <= 0;}fn hasState(widget: WidgetFrame, flag: u64) bool {    return (widget.state_flags & flag) != 0;}fn alpha(color: Color, value: u8) Color {    return .{ .r = color.r, .g = color.g, .b = color.b, .a = value };}fn mix(left: Color, right: Color, left_weight: f32) Color {    const clamped = std.math.clamp(left_weight, @as(f32, 0), @as(f32, 1));    return .{        .r = mixChannel(left.r, right.r, clamped),        .g = mixChannel(left.g, right.g, clamped),        .b = mixChannel(left.b, right.b, clamped),        .a = mixChannel(left.a, right.a, clamped),    };}fn mixChannel(left: u8, right: u8, left_weight: f32) u8 {    const value = @as(f32, @floatFromInt(left)) * left_weight +        @as(f32, @floatFromInt(right)) * (1 - left_weight);    return @intFromFloat(std.math.clamp(@round(value), @as(f32, 0), @as(f32, 255)));}const RecorderDraw = struct {    rect: Rect,    width: f32 = 0,    color: Color,    blur_radius: f32 = 0,    spread: f32 = 0,    offset_x: f32 = 0,    offset_y: f32 = 0,};const RecorderBlit = struct {    rect: Rect,    image_index: u32,    color: ?Color = null,    opacity: u8 = 255,};const Recorder = struct {    fills: usize = 0,    gradients: usize = 0,    strokes: usize = 0,    shadows: usize = 0,    clip_begins: usize = 0,    clip_ends: usize = 0,    images: usize = 0,    glyphs: usize = 0,    saw_accent_fill: bool = false,    saw_focus_stroke: bool = false,    last_clip: ?Rect = null,    last_fill: ?RecorderDraw = null,    last_fill_roundness: f32 = 0,    last_gradient: ?model.UiLinearGradient = null,    last_stroke: ?RecorderDraw = null,    last_stroke_roundness: f32 = 0,    last_shadow: ?RecorderDraw = null,    last_blit: ?RecorderBlit = null,    fn beginClip(self: *Recorder, rect: Rect) void {        self.clip_begins += 1;        self.last_clip = rect;    }    fn endClip(self: *Recorder) void {        self.clip_ends += 1;    }    fn fillRect(self: *Recorder, rect: Rect, color: Color) void {        self.last_fill_roundness = 0;        self.recordFill(rect, color);    }    fn fillRoundedRect(self: *Recorder, rect: Rect, roundness: f32, segments: u32, color: Color) void {        _ = segments;        self.last_fill_roundness = roundness;        self.recordFill(rect, color);    }    fn fillLinearGradient(self: *Recorder, rect: Rect, roundness: f32, segments: u32, gradient: model.UiLinearGradient) void {        _ = rect;        _ = roundness;        _ = segments;        self.gradients += 1;        self.last_gradient = gradient;    }    fn strokeRect(self: *Recorder, rect: Rect, width: f32, color: Color) void {        self.last_stroke_roundness = 0;        self.recordStroke(rect, width, color);    }    fn strokeRoundedRect(self: *Recorder, rect: Rect, roundness: f32, segments: u32, width: f32, color: Color) void {        _ = segments;        self.last_stroke_roundness = roundness;        self.recordStroke(rect, width, color);    }    fn shadowRoundedRect(self: *Recorder, rect: Rect, roundness: f32, blur_radius: f32, spread: f32, offset_x: f32, offset_y: f32, color: Color) void {        _ = roundness;        self.shadows += 1;        self.last_shadow = .{ .rect = rect, .color = color, .blur_radius = blur_radius, .spread = spread, .offset_x = offset_x, .offset_y = offset_y };    }    fn recordFill(self: *Recorder, rect: Rect, color: Color) void {        self.fills += 1;        self.last_fill = .{ .rect = rect, .color = color };        if (color.a != 0 and color.b > color.r) self.saw_accent_fill = true;    }    fn recordStroke(self: *Recorder, rect: Rect, width: f32, color: Color) void {        self.strokes += 1;        self.last_stroke = .{ .rect = rect, .width = width, .color = color };        if (width > 1 and color.a != 0 and color.b > color.r) self.saw_focus_stroke = true;    }    fn drawImage(self: *Recorder, rect: Rect, image_index: u32, source: Rect, opacity: u8) void {        _ = source;        self.images += 1;        self.last_blit = .{ .rect = rect, .image_index = image_index, .opacity = opacity };    }    fn drawGlyph(self: *Recorder, rect: Rect, image_index: u32, source: Rect, color: Color) void {        _ = source;        self.glyphs += 1;        self.last_blit = .{ .rect = rect, .image_index = image_index, .color = color };    }};test "widget chrome emits semantic and interaction state" {    var recorder = Recorder{};    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 2,        .kind = .button,        .rect = .{ .x = 20, .y = 12, .width = 36, .height = 16 },        .visible_rect = .{ .x = 20, .y = 12, .width = 36, .height = 16 },        .paint = .{ .corner_roundness = 6 },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 36, .height = 16 },        .focusable = true,        .focused = true,        .state_flags = model.ui_state_selected | model.ui_state_default,    }, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.strokes);    try std.testing.expect(recorder.saw_accent_fill);    try std.testing.expect(recorder.saw_focus_stroke);    try std.testing.expectEqual(@as(f32, 4), recorder.last_fill_roundness);    try std.testing.expectEqual(Rect{ .x = 22, .y = 14, .width = 32, .height = 12 }, recorder.last_fill.?.rect);    try std.testing.expectEqual(@as(f32, 8), recorder.last_stroke_roundness);    try std.testing.expectEqual(Rect{ .x = 18, .y = 10, .width = 40, .height = 20 }, recorder.last_stroke.?.rect);}test "widget chrome preserves nonfocused border and compensates state inset roundness" {    var recorder = Recorder{};    const widget = WidgetFrame{        .root_id = 1,        .widget_id = 2,        .kind = .button,        .rect = .{ .x = 8, .y = 6, .width = 48, .height = 20 },        .visible_rect = .{ .x = 8, .y = 6, .width = 48, .height = 20 },        .paint = .{ .corner_roundness = 6 },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 48, .height = 20 },        .focusable = true,        .hovered = true,        .captured = true,    };    drawWidgetChrome(&recorder, widget, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.strokes);    try std.testing.expectEqual(widget.rect, recorder.last_stroke.?.rect);    try std.testing.expectEqual(@as(f32, 6), recorder.last_stroke_roundness);    try std.testing.expectEqual(inset(widget.rect, 1, 1), recorder.last_fill.?.rect);    try std.testing.expectEqual(@as(f32, 5), recorder.last_fill_roundness);}test "widget chrome contains checked marker bar" {    var recorder = Recorder{};    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 2,        .kind = .container,        .rect = .{ .x = 20, .y = 12, .width = 36, .height = 16 },        .visible_rect = .{ .x = 20, .y = 12, .width = 36, .height = 16 },        .paint = .{},        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 36, .height = 16 },        .focusable = false,        .state_flags = model.ui_state_checked,    }, .{});    try std.testing.expectEqual(@as(usize, 2), recorder.fills);    try std.testing.expectEqual(Rect{ .x = 46, .y = 20, .width = 4, .height = 2 }, recorder.last_fill.?.rect);}test "widget chrome preserves linear gradient under state overlays" {    const gradient = model.UiLinearGradient{        .start = .{ .x = 0, .y = 0.2 },        .end = .{ .x = 1, .y = 0.8 },        .start_color = .{ .r = 20, .g = 40, .b = 80, .a = 255 },        .end_color = .{ .r = 70, .g = 120, .b = 220, .a = 255 },    };    var recorder = Recorder{};    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 2,        .kind = .button,        .rect = .{ .x = 8, .y = 6, .width = 48, .height = 20 },        .visible_rect = .{ .x = 8, .y = 6, .width = 48, .height = 20 },        .paint = .{            .background = .{ .r = 255, .g = 0, .b = 0, .a = 255 },            .linear_gradient = gradient,            .corner_roundness = 6,        },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 48, .height = 20 },        .focusable = true,        .hovered = true,        .focused = true,        .state_flags = model.ui_state_selected,    }, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.gradients);    try std.testing.expectEqual(gradient, recorder.last_gradient.?);    try std.testing.expect(recorder.fills >= 3);    try std.testing.expect(recorder.saw_accent_fill);    try std.testing.expect(recorder.saw_focus_stroke);    try std.testing.expectEqual(@as(f32, 8), recorder.last_stroke_roundness);}test "widget chrome blits image paint tinted and untinted" {    var recorder = Recorder{};    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 2,        .kind = .container,        .rect = .{ .x = 4, .y = 4, .width = 64, .height = 64 },        .visible_rect = .{ .x = 4, .y = 4, .width = 64, .height = 64 },        .paint = .{ .image = .{ .index = 3, .opacity = 200 } },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 64, .height = 64 },        .focusable = false,    }, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.images);    try std.testing.expectEqual(@as(u32, 3), recorder.last_blit.?.image_index);    try std.testing.expectEqual(@as(u8, 200), recorder.last_blit.?.opacity);    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 3,        .kind = .container,        .rect = .{ .x = 4, .y = 4, .width = 64, .height = 64 },        .visible_rect = .{ .x = 4, .y = 4, .width = 64, .height = 64 },        .paint = .{ .image = .{ .index = 5, .tint = .{ .r = 251, .g = 73, .b = 52 } } },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 64, .height = 64 },        .focusable = false,    }, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.glyphs);    try std.testing.expectEqual(@as(u32, 5), recorder.last_blit.?.image_index);    try std.testing.expectEqual(@as(u8, 251), recorder.last_blit.?.color.?.r);}test "widget chrome emits configured shadow" {    var recorder = Recorder{};    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 2,        .kind = .container,        .rect = .{ .x = 6, .y = 8, .width = 30, .height = 12 },        .visible_rect = .{ .x = 0, .y = 0, .width = 64, .height = 32 },        .paint = .{            .background = .{ .r = 255, .g = 255, .b = 255, .a = 255 },            .corner_roundness = 0.4,            .shadow = .{                .color = .{ .r = 0, .g = 0, .b = 0, .a = 80 },                .offset_x = 2,                .offset_y = 3,                .blur_radius = 4,                .spread = 1,            },        },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 30, .height = 12 },        .focusable = false,    }, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.shadows);    try std.testing.expectEqual(@as(f32, 4), recorder.last_shadow.?.blur_radius);    try std.testing.expectEqual(@as(f32, 2), recorder.last_shadow.?.offset_x);    try std.testing.expectEqual(@as(usize, 1), recorder.fills);}test "widget chrome clips to visible rect" {    var recorder = Recorder{};    drawWidgetChrome(&recorder, .{        .root_id = 1,        .widget_id = 2,        .kind = .button,        .rect = .{ .x = 8, .y = 8, .width = 30, .height = 12 },        .visible_rect = .{ .x = 20, .y = 8, .width = 18, .height = 12 },        .paint = .{ .background = .{ .r = 255, .g = 0, .b = 0, .a = 255 } },        .scroll = .{},        .constraints = .{},        .content_size = .{ .width = 30, .height = 12 },        .focusable = true,    }, .{});    try std.testing.expectEqual(@as(usize, 1), recorder.clip_begins);    try std.testing.expectEqual(@as(usize, 1), recorder.clip_ends);    try std.testing.expectEqual(@as(f32, 20), recorder.last_clip.?.x);    try std.testing.expectEqual(@as(f32, 18), recorder.last_clip.?.width);}

Complete caller list for visual.drawWidgetChrome

8 direct callers.

Complete call list for visual.drawWidgetChrome

17 direct calls.

Audit

Definitions7
Public names7
Members14
Version26.7.0
Revisiondaab053ee433