DVUI

displayOptional

Display an optional

  • If the optional is a union or struct, StructOptions should be provided for those types in the options tuple containing default_value's.
  • These default values are used when the user creates a new optional value or activates a new the union member.
  • Basic types are assigned a default value depending on their type. e.g. 0 for numbers, "" for strings.
  • It is recommended that users handle optional pointers manually using optionalFieldWidget directly, rather than using this function. Otherwise all instances of the type will point to a single default value as defaults are per-type, not per field.

Parameters

#
src:std.builtin.SourceLocation
std.builtin.SourceLocation
ContainerT:type
type
field_name:[]const u8
[]const u8
field_value_ptr:anytype
anytype
depth:usize
usize
field_option:FieldOptions
FieldOptions
options:anytype
anytype
al:*dvui.Alignment
*dvui.Alignment
default_value:?@TypeOf(field_value_ptr.*)
?@TypeOf(field_value_ptr.*)

Source

Implementation

#
pub fn displayOptional(
    src: std.builtin.SourceLocation,
    comptime ContainerT: type,
    comptime field_name: []const u8,
    field_value_ptr: anytype,
    comptime depth: usize,
    field_option: FieldOptions,
    options: anytype,
    al: *dvui.Alignment,
    default_value: ?@TypeOf(field_value_ptr.*),
) void {
    validateFieldPtrType(field_name, &.{.optional}, "displayOptional", @TypeOf(field_value_ptr));
    if (field_option.displayMode() == .none) return;

    const optional = @typeInfo(@TypeOf(field_value_ptr.*)).optional;
    const child_field_option = field_option.childOption();
    // Shortcut some common optionals
    switch (@typeInfo(optional.child)) {
        .bool => {
            boolFieldWidgetOptional(src, field_name, field_value_ptr, child_field_option.optionBool(field_name), al);
            return;
        },
        .@"enum" => {
            enumFieldWidgetOptional(src, field_name, field_value_ptr, child_field_option.optionStandard(field_name), al);
            return;
        },
        .int, .float => {
            const fo = child_field_option.optionNumber(field_name);
            if (fo.widget_type == .number_entry) {
                numberFieldWidgetOptional(@src(), field_name, field_value_ptr, fo, al);
                return;
            }
        },
        else => {},
    }

    const read_only = @typeInfo(@TypeOf(field_value_ptr)).pointer.is_const or field_option.displayMode() != .read_write;
    if (optionalFieldWidget(src, field_name, field_value_ptr, field_option.optionOptional(field_name), al)) {
        if (!read_only) {
            if (field_value_ptr.* == null) {
                field_value_ptr.* = default_value orelse
                    defaultValue(optional.child, ContainerT, field_name, options); // If there is no default value, it will remain null.
            }
        }
        if (field_value_ptr.*) |*val| {
            displayField(@src(), ContainerT, field_name, val, depth, child_field_option, options, al);
        } else {
            log.debug("Optional field {s} cannot be selected as no default value is provided. Use struct_ui.StructOptions({s}) with a default or StructOptions({s}) with a default, setting a value for {s}.", .{
                field_name,
                @typeName(optional.child),
                @typeName(ContainerT),
                field_name,
            });
        }
    } else if (!read_only) {
        field_value_ptr.* = null;
    }
}