Skip to documentation
SLOP

tiny.gui.widget

Reference tiny.gui widget

Defined in tiny.gui.

API (23)

Actions

Public operations.

Types and contracts

Public types and contracts.

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

Source

Called byCallsNo direct callswidgetpointForActiontest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindByAction
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplySelectionprivate; no linkfun.sdfii.src.engine.system.ui.input.eventcaptureTargetprivate; no linkfun.sdfii.src.engine.system.ui.testexpectWidgetSemanticstest; no linkfun.sdfii.src.engine.system.ui.testtest: rendered semantics survive retr...widgetfocusedwidgetfindById
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindByRole
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callswidgetpointForTextContainingtest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindByTextContaining
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate; no linkfun.sdfii.src.engine.system.ui.input.scrollensureVisibleprivate; no linkfun.sdfii.src.engine.system.ui.input.scrollkeyboardAnchorwidgethitTestActivatablewidgetfindIndexById
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.gui.src.widgetnodeIdForActiontest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindNodeByAction
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindNodeByRole
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate; no linkfun.sdfii.src.engine.system.ui.input.eventfocusedWidgetwidgetfindByIdwidgetisFocusableForTraversalwidgetfocused
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplyPointerprivate; no linkfun.sdfii.src.engine.system.ui.input.eventrefreshPointerprivate; no linkfun.sdfii.src.validation.uihitWidgetwidgethitTestActivatabletest sourcelib.gui.src.widgettest: activatable hit testing promote...widgethitTestIndexwidgethitTest
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate; no linkfun.sdfii.src.validation.uihitWidgettest sourcelib.gui.src.widgettest: activatable hit testing promote...modelpointInRectwidgetfindIndexByIdwidgethitTestwidgetisActivatablewidgethitTestActivatable
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallswidgethitTestmodelpointInRectwidgetisDisabledWidgetwidgethitTestIndex
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.gui.src.widgettest: action interaction maps action ...private sourcelib.gui.src.widgetnodeIdForActionwidgetinteractionWidgetsForActions
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplyKeyprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplyPointerprivate; no linkfun.sdfii.src.validation.uiapplyInputprivate; no linkfun.sdfii.src.validation.uibuildAccessibilitywidgethitTestActivatablewidgetpointForActionwidgetisDisabledWidgetwidgetisActivatable
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callsprivate; no linkfun.sdfii.src.engine.system.ui.input.scrollensureVisibleprivate; no linkfun.sdfii.src.engine.system.ui.input.scrollkeyboardTargetprivate; no linkfun.sdfii.src.engine.system.ui.input.scrollpointerTargetprivate; no linkfun.sdfii.src.validation.uibuildAccessibilityprivate; no linkfun.sdfii.src.validation.uiisFocusable+4 morewidgetisDisabledWidget
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate; no linkfun.sdfii.src.engine.system.ui.input.eventfocusNextwidgetfocusedwidgetisDisabledWidgetwidgetisFocusableForTraversal
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplyKeyprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplyPointerprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplySelectionprivate; no linkfun.sdfii.src.engine.system.ui.input.eventapplyTextprivate; no linkfun.sdfii.src.engine.system.ui.input.eventkeyboardScrollprivate; no linkfun.sdfii.src.validation.uiapplyInputwidgetisDisabledWidgetwidgetisTextEditable
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindByActionwidgetisActivatablewidgetpointForWidgetwidgetpointForAction
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.gui.src.widgettest: action and role lookup traverse...widgetfindByTextContainingwidgetpointForWidgetwidgetpointForTextContaining
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callswidgetpointForActionwidgetpointForTextContainingwidgetpointForWidget
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate; no linkfun.sdfii.src.engine.system.ui.input.scrollkeyboardAnchorwidgetrootWidgetIndex
Static calls · unresolved targets: 0 · external targets: 0.

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

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

Source: lib/gui/src/widget.zig

zig
const std = @import("std");const model = @import("model.zig");const RootFrame = model.RootFrame;const UiNode = model.UiNode;const UiPoint = model.UiPoint;const WidgetFrame = model.WidgetFrame;const ui_state_disabled = model.ui_state_disabled;pub const ActionInteraction = struct {    hovered_action: ?[]const u8 = null,    captured_action: ?[]const u8 = null,    focused_action: ?[]const u8 = null,};pub const InteractionWidgets = struct {    hovered_widget: ?u64 = null,    captured_widget: ?u64 = null,    focused_widget: ?u64 = null,};pub fn hitTest(widgets: []const WidgetFrame, root_id: u64, x: f32, y: f32) ?*const WidgetFrame {    const index = hitTestIndex(widgets, root_id, x, y) orelse return null;    return &widgets[index];}pub fn hitTestIndex(widgets: []const WidgetFrame, root_id: u64, x: f32, y: f32) ?usize {    var index: usize = widgets.len;    while (index > 0) {        index -= 1;        const widget = &widgets[index];        if (widget.root_id != root_id) continue;        if (isDisabledWidget(widget)) continue;        if (widget.visible_rect.width <= 0 or widget.visible_rect.height <= 0) continue;        if (model.pointInRect(widget.rect, x, y) and model.pointInRect(widget.visible_rect, x, y)) return index;    }    return null;}pub fn hitTestActivatable(widgets: []const WidgetFrame, root_id: u64, x: f32, y: f32) ?*const WidgetFrame {    const hit = hitTest(widgets, root_id, x, y) orelse return null;    if (isActivatable(hit)) return hit;    const hit_index = findIndexById(widgets, root_id, hit.widget_id) orelse return null;    var index = hit_index;    while (index > 0) {        index -= 1;        const candidate = &widgets[index];        if (candidate.root_id != root_id) continue;        if (index + candidate.subtree_size <= hit_index) continue;        if (!isActivatable(candidate)) continue;        if (model.pointInRect(candidate.rect, x, y) and model.pointInRect(candidate.visible_rect, x, y)) return candidate;    }    return null;}pub fn findById(widgets: []const WidgetFrame, root_id: u64, widget_id: u64) ?*const WidgetFrame {    for (widgets) |*widget| {        if (widget.root_id == root_id and widget.widget_id == widget_id) return widget;    }    return null;}pub fn findIndexById(widgets: []const WidgetFrame, root_id: u64, widget_id: u64) ?usize {    for (widgets, 0..) |*widget, index| {        if (widget.root_id == root_id and widget.widget_id == widget_id) return index;    }    return null;}pub fn rootWidgetIndex(roots: []const RootFrame, root_id: u64) ?usize {    for (roots) |root| {        if (root.root_id == root_id and root.widget_count > 0) return root.widget_start;    }    return null;}pub fn focused(widgets: []const WidgetFrame, root_id: u64, widget_id: ?u64) ?*const WidgetFrame {    const current = widget_id orelse return null;    const widget = findById(widgets, root_id, current) orelse return null;    return if (isFocusableForTraversal(root_id, widget)) widget else null;}pub fn findNodeByAction(root: *const UiNode, action: []const u8) ?*const UiNode {    if (action.len == 0) return null;    if (std.mem.eql(u8, root.action, action)) return root;    for (root.children) |*child| {        if (findNodeByAction(child, action)) |found| return found;    }    return null;}pub fn findNodeByRole(root: *const UiNode, role: []const u8) ?*const UiNode {    if (role.len == 0) return null;    if (std.mem.eql(u8, root.role, role)) return root;    for (root.children) |*child| {        if (findNodeByRole(child, role)) |found| return found;    }    return null;}pub fn interactionWidgetsForActions(root: *const UiNode, interaction: ActionInteraction) InteractionWidgets {    return .{        .hovered_widget = nodeIdForAction(root, interaction.hovered_action),        .captured_widget = nodeIdForAction(root, interaction.captured_action),        .focused_widget = nodeIdForAction(root, interaction.focused_action),    };}pub fn findByAction(widgets: []const WidgetFrame, root_id: u64, action: []const u8) ?*const WidgetFrame {    if (action.len == 0) return null;    for (widgets) |*widget| {        if (widget.root_id == root_id and std.mem.eql(u8, widget.action, action)) return widget;    }    return null;}pub fn findByRole(widgets: []const WidgetFrame, root_id: u64, role: []const u8) ?*const WidgetFrame {    if (role.len == 0) return null;    for (widgets) |*widget| {        if (widget.root_id == root_id and std.mem.eql(u8, widget.role, role)) return widget;    }    return null;}pub fn findByTextContaining(widgets: []const WidgetFrame, root_id: u64, needle: []const u8) ?*const WidgetFrame {    if (needle.len == 0) return null;    for (widgets) |*widget| {        if (widget.root_id != root_id) continue;        const text = widget.text orelse continue;        if (std.mem.indexOf(u8, text.content, needle) != null) return widget;    }    return null;}pub fn pointForAction(widgets: []const WidgetFrame, root_id: u64, action: []const u8) ?UiPoint {    const widget = findByAction(widgets, root_id, action) orelse return null;    if (!isActivatable(widget)) return null;    return pointForWidget(widget);}pub fn pointForTextContaining(widgets: []const WidgetFrame, root_id: u64, needle: []const u8) ?UiPoint {    const widget = findByTextContaining(widgets, root_id, needle) orelse return null;    return pointForWidget(widget);}pub fn pointForWidget(widget: *const WidgetFrame) ?UiPoint {    if (widget.visible_rect.width <= 0 or widget.visible_rect.height <= 0) return null;    return .{        .x = widget.visible_rect.x + widget.visible_rect.width * 0.5,        .y = widget.visible_rect.y + widget.visible_rect.height * 0.5,    };}pub fn isActivatable(widget: *const WidgetFrame) bool {    return !isDisabledWidget(widget) and widget.kind != .text_input and (widget.kind == .button or widget.action.len != 0);}pub fn isFocusableForTraversal(root_id: u64, widget: *const WidgetFrame) bool {    return widget.root_id == root_id and        widget.focusable and        !isDisabledWidget(widget) and        widget.rect.width > 0 and        widget.rect.height > 0;}pub fn isDisabledNode(node: *const UiNode) bool {    return (node.state_flags & ui_state_disabled) != 0;}pub fn isDisabledWidget(widget: *const WidgetFrame) bool {    return (widget.state_flags & ui_state_disabled) != 0;}pub fn isTextEditable(widget: *const WidgetFrame) bool {    return widget.kind == .text_input and !isDisabledWidget(widget);}fn nodeIdForAction(root: *const UiNode, action: ?[]const u8) ?u64 {    const action_text = action orelse return null;    const node = findNodeByAction(root, action_text) orelse return null;    return node.widget_id;}test "activatable hit testing promotes child text hits to the owning widget" {    const widgets = [_]WidgetFrame{        .{            .root_id = 7,            .widget_id = 10,            .kind = .button,            .rect = .{ .x = 0, .y = 0, .width = 120, .height = 32 },            .visible_rect = .{ .x = 0, .y = 0, .width = 120, .height = 32 },            .paint = .{},            .scroll = .{},            .constraints = .{},            .content_size = .{ .width = 120, .height = 32 },            .focusable = true,            .action = "demo.activate",            .subtree_size = 2,        },        .{            .root_id = 7,            .widget_id = 11,            .kind = .label,            .rect = .{ .x = 8, .y = 6, .width = 72, .height = 18 },            .visible_rect = .{ .x = 8, .y = 6, .width = 72, .height = 18 },            .paint = .{},            .scroll = .{},            .constraints = .{},            .content_size = .{ .width = 72, .height = 18 },            .focusable = false,        },    };    const raw = hitTest(widgets[0..], 7, 12, 12) orelse return error.MissingRawHit;    try std.testing.expectEqual(@as(u64, 11), raw.widget_id);    const promoted = hitTestActivatable(widgets[0..], 7, 12, 12) orelse return error.MissingPromotedHit;    try std.testing.expectEqual(@as(u64, 10), promoted.widget_id);    try std.testing.expectEqualStrings("demo.activate", promoted.action);}test "action and role lookup traverse surface trees and frame facts" {    const text = model.UiText{ .content = "Alpha row" };    const nodes = [_]UiNode{        .{            .widget_id = 11,            .kind = .button,            .action = "demo.open",            .role = "scene.graph-row",        },        .{            .widget_id = 12,            .kind = .label,            .role = "scene.preview",            .text = text,        },    };    const root = UiNode{        .widget_id = 10,        .role = "scene",        .children = nodes[0..],    };    try std.testing.expectEqual(@as(u64, 11), (findNodeByAction(&root, "demo.open") orelse return error.MissingActionNode).widget_id);    try std.testing.expectEqual(@as(u64, 12), (findNodeByRole(&root, "scene.preview") orelse return error.MissingRoleNode).widget_id);    try std.testing.expect(findNodeByAction(&root, "") == null);    const widgets = [_]WidgetFrame{        .{            .root_id = 7,            .widget_id = 11,            .kind = .button,            .rect = .{ .x = 0, .y = 0, .width = 80, .height = 24 },            .visible_rect = .{ .x = 0, .y = 0, .width = 80, .height = 24 },            .paint = .{},            .scroll = .{},            .constraints = .{},            .content_size = .{ .width = 80, .height = 24 },            .focusable = true,            .action = "demo.open",            .role = "scene.graph-row",        },        .{            .root_id = 7,            .widget_id = 12,            .kind = .label,            .rect = .{ .x = 90, .y = 0, .width = 100, .height = 24 },            .visible_rect = .{ .x = 90, .y = 0, .width = 100, .height = 24 },            .paint = .{},            .scroll = .{},            .constraints = .{},            .content_size = .{ .width = 100, .height = 24 },            .focusable = false,            .role = "scene.preview",            .has_text = true,            .text = text,        },        .{            .root_id = 8,            .widget_id = 13,            .kind = .button,            .rect = .{ .x = 0, .y = 0, .width = 80, .height = 24 },            .visible_rect = .{ .x = 0, .y = 0, .width = 80, .height = 24 },            .paint = .{},            .scroll = .{},            .constraints = .{},            .content_size = .{ .width = 80, .height = 24 },            .focusable = true,            .action = "demo.open",        },        .{            .root_id = 7,            .widget_id = 14,            .kind = .button,            .rect = .{ .x = 0, .y = 30, .width = 80, .height = 24 },            .visible_rect = .{ .x = 0, .y = 30, .width = 80, .height = 24 },            .paint = .{},            .scroll = .{},            .constraints = .{},            .content_size = .{ .width = 80, .height = 24 },            .focusable = true,            .action = "demo.disabled",            .state_flags = ui_state_disabled,        },    };    try std.testing.expectEqual(@as(u64, 11), (findByAction(widgets[0..], 7, "demo.open") orelse return error.MissingActionWidget).widget_id);    try std.testing.expectEqual(@as(u64, 12), (findByRole(widgets[0..], 7, "scene.preview") orelse return error.MissingRoleWidget).widget_id);    try std.testing.expectEqual(@as(u64, 12), (findByTextContaining(widgets[0..], 7, "row") orelse return error.MissingTextWidget).widget_id);    try std.testing.expectEqual(@as(u64, 13), (findByAction(widgets[0..], 8, "demo.open") orelse return error.MissingSecondRootActionWidget).widget_id);    const point = pointForAction(widgets[0..], 7, "demo.open") orelse return error.MissingActionPoint;    try std.testing.expectEqual(@as(f32, 40), point.x);    try std.testing.expectEqual(@as(f32, 12), point.y);    try std.testing.expect(pointForAction(widgets[0..], 7, "demo.disabled") == null);    const text_point = pointForTextContaining(widgets[0..], 7, "Alpha") orelse return error.MissingTextPoint;    try std.testing.expectEqual(@as(f32, 140), text_point.x);    try std.testing.expectEqual(@as(f32, 12), text_point.y);}test "action interaction maps action descriptors to widget ids" {    const nodes = [_]UiNode{        .{            .widget_id = 21,            .kind = .button,            .action = "inspector.tabs.items",        },        .{            .widget_id = 22,            .kind = .button,            .action = "inspector.action.refresh",        },    };    const root = UiNode{        .widget_id = 20,        .children = nodes[0..],    };    const mapped = interactionWidgetsForActions(&root, .{        .hovered_action = "inspector.tabs.items",        .captured_action = "inspector.action.refresh",        .focused_action = "inspector.tabs.items",    });    try std.testing.expectEqual(@as(?u64, 21), mapped.hovered_widget);    try std.testing.expectEqual(@as(?u64, 22), mapped.captured_widget);    try std.testing.expectEqual(@as(?u64, 21), mapped.focused_widget);    try std.testing.expectEqual(@as(?u64, null), interactionWidgetsForActions(&root, .{ .hovered_action = "" }).hovered_widget);}

Complete caller list for widget.isDisabledWidget

9 direct callers.

Audit

Definitions24
Public names24
Members6
Version26.7.0
Revisiondaab053ee433