DVUI

dropdownEnum

Show @tagName of choice, and click to display all tags in that enum in a floating menu.

Returns true if any enum value was selected (even the already chosen one).

See DropdownWidget for more advanced usage.

Only valid between Window.beginand Window.end.

Parameters

#
src:std.builtin.SourceLocation
std.builtin.SourceLocation
T:type
type
choice:DropdownChoice(T)
DropdownChoice(T)
init_opts:DropdownInitOptions
DropdownInitOptions
opts:Options
Options

Source

Implementation

#
pub fn dropdownEnum(src: std.builtin.SourceLocation, T: type, choice: DropdownChoice(T), init_opts: DropdownInitOptions, opts: Options) bool {
    if (@typeInfo(T) != .@"enum") @compileError("Expected enum, found '" ++ @typeName(T) ++ "'");

    // Adjust selected index by 1 if the placeholder is showing
    const selected_index: ?usize = switch (choice) {
        .choice => |ch| @intFromEnum(ch.*),
        .choice_nullable => |ch| if (ch.*) |_|
            if (init_opts.null_selectable) @as(usize, @intFromEnum(ch.*.?)) + 1 else @intFromEnum(ch.*.?)
        else
            null,
    };

    var dd: dvui.DropdownWidget = undefined;
    dd.init(
        src,
        switch (choice) {
            .choice => |ch| .{ .selected_index = @intFromEnum(ch.*), .label = @tagName(ch.*) },
            .choice_nullable => |ch| if (ch.* == null)
                .{ .placeholder = init_opts.placeholder orelse dropdown_placeholder_default }
            else
                .{ .selected_index = selected_index, .label = @tagName(ch.*.?) },
        },
        opts,
    );
    defer dd.deinit();

    var ret = false;
    if (dd.dropped()) {
        if (choice == .choice_nullable and init_opts.null_selectable) {
            var mi = dd.addChoice();
            defer mi.deinit();
            dvui.labelNoFmt(@src(), init_opts.placeholder orelse dropdown_placeholder_default, .{}, opts.strip().override(.{
                .gravity_y = 0.5,
                .color_text = opts.color(.text).opacity(0.65),
            }));
            if (mi.activeRect()) |_| {
                dd.close();
                choice.choice_nullable.* = null;
                ret = true;
            }
        }
        inline for (@typeInfo(T).@"enum".fields) |e| {
            if (dd.addChoiceLabel(e.name)) {
                switch (choice) {
                    inline else => |ch| {
                        ch.* = @field(T, e.name);
                        ret = true;
                    },
                }
            }
        }
    }

    return ret;
}