tiny.gui.visual
Defined in tiny.gui.
API (7)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
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.
tiny.gui.visual.drawFrame[function] atlib/gui/src/visual.zig:30lib.gui.src.visual.test_widget_chrome_blits_image_paint_tinted_and_untinted[function] — test source atlib/gui/src/visual.zig:507in nearest public ownertiny.gui.visuallib.gui.src.visual.test_widget_chrome_clips_to_visible_rect[function] — test source atlib/gui/src/visual.zig:573in nearest public ownertiny.gui.visuallib.gui.src.visual.test_widget_chrome_contains_checked_marker_bar[function] — test source atlib/gui/src/visual.zig:451in nearest public ownertiny.gui.visuallib.gui.src.visual.test_widget_chrome_emits_configured_shadow[function] — test source atlib/gui/src/visual.zig:542in nearest public ownertiny.gui.visuallib.gui.src.visual.test_widget_chrome_emits_semantic_and_interaction_state[function] — test source atlib/gui/src/visual.zig:400in nearest public ownertiny.gui.visuallib.gui.src.visual.test_widget_chrome_preserves_linear_gradient_under_state_overlays[function] — test source atlib/gui/src/visual.zig:471in nearest public ownertiny.gui.visuallib.gui.src.visual.test_widget_chrome_preserves_nonfocused_border_and_compensates_state_inset_roundness[function] — test source atlib/gui/src/visual.zig:426in nearest public ownertiny.gui.visual
Complete call list for visual.drawWidgetChrome
17 direct calls.
lib.gui.src.visual.alpha[function] — private source atlib/gui/src/visual.zig:273in nearest public ownertiny.gui.visuallib.gui.src.visual.alphaUnit[function] — private source atlib/gui/src/visual.zig:112in nearest public ownertiny.gui.visuallib.gui.src.visual.backgroundColor[function] — private source atlib/gui/src/visual.zig:116in nearest public ownertiny.gui.visuallib.gui.src.visual.borderColor[function] — private source atlib/gui/src/visual.zig:125in nearest public ownertiny.gui.visuallib.gui.src.visual.drawEdgeBorders[function] — private source atlib/gui/src/visual.zig:170in nearest public ownertiny.gui.visuallib.gui.src.visual.drawImagePaint[function] — private source atlib/gui/src/visual.zig:88in nearest public ownertiny.gui.visuallib.gui.src.visual.drawInteractionState[function] — private source atlib/gui/src/visual.zig:154in nearest public ownertiny.gui.visuallib.gui.src.visual.drawSemanticState[function] — private source atlib/gui/src/visual.zig:134in nearest public ownertiny.gui.visuallib.gui.src.visual.drawShadow[function] — private source atlib/gui/src/visual.zig:201in nearest public ownertiny.gui.visuallib.gui.src.visual.fillPaintedRect[function] — private source atlib/gui/src/visual.zig:207in nearest public ownertiny.gui.visuallib.gui.src.visual.hasState[function] — private source atlib/gui/src/visual.zig:269in nearest public ownertiny.gui.visuallib.gui.src.visual.isEmpty[function] — private source atlib/gui/src/visual.zig:265in nearest public ownertiny.gui.visuallib.gui.src.visual.mix[function] — private source atlib/gui/src/visual.zig:277in nearest public ownertiny.gui.visuallib.gui.src.visual.offsetRect[function] — private source atlib/gui/src/visual.zig:239in nearest public ownertiny.gui.visuallib.gui.src.visual.sameRect[function] — private source atlib/gui/src/visual.zig:261in nearest public ownertiny.gui.visuallib.gui.src.visual.strokePaintedRect[function] — private source atlib/gui/src/visual.zig:216in nearest public ownertiny.gui.visualtiny.gui.visual.widgetHasVisibleChrome[function] atlib/gui/src/visual.zig:96
Audit
| Definitions | 7 |
|---|---|
| Public names | 7 |
| Members | 14 |
| Version | 26.7.0 |
| Revision | daab053ee433 |