DVUI

init

It's expected to call this when self is undefined

Parameters

#
self:*PanedWidget
*PanedWidget
src:std.builtin.SourceLocation
std.builtin.SourceLocation
init_options:InitOptions
InitOptions
opts:Options
Options

Source

Implementation

#
pub fn init(self: *PanedWidget, src: std.builtin.SourceLocation, init_options: InitOptions, opts: Options) void {
    const defaults = Options{ .name = "Paned", .role = .pane };
    const wd = WidgetData.init(src, .{}, defaults.override(opts));

    const rect = wd.contentRect();
    const our_size = switch (init_options.direction) {
        .horizontal => rect.w,
        .vertical => rect.h,
    };

    self.* = .{
        .wd = wd,
        .init_opts = init_options,
        .collapsing = dvui.dataGet(null, wd.id, "_collapsing", bool) orelse false,
        .collapsed_state = dvui.dataGet(null, wd.id, "_collapsed", bool) orelse (our_size < init_options.collapsed_size),
        .should_autofit = dvui.dataGet(null, wd.id, "_autofit_next_frame", bool) orelse dvui.firstFrame(wd.id),

        // might be changed in processEvents
        .handle_thick = init_options.handle_size,

        .split_ratio = if (init_options.split_ratio) |srp| srp else blk: {
            const default: f32 = if (our_size < init_options.collapsed_size) 1.0 else 0.5;
            break :blk dvui.dataGetPtrDefault(null, wd.id, "_split_ratio", f32, default);
        },
    };

    if (self.init_opts.autofit_first != null) {
        // autofit on the second frame, after we know the full widget size
        if (dvui.firstFrame(wd.id)) {
            dvui.dataSet(null, wd.id, "_autofit_next_frame", true);
        } else if (self.should_autofit) {
            dvui.dataRemove(null, wd.id, "_autofit_next_frame");
        }

        if (self.should_autofit) {
            // Make the first side take the full space to begin with
            self.split_ratio.* = 1.0;
        }
    }

    if (self.collapsing) {
        self.collapsed_state = false;
    }

    if (!self.collapsing and !self.collapsed_state and our_size < self.init_opts.collapsed_size) {
        // collapsing
        self.collapsing = true;
        if (self.split_ratio.* >= 0.5) {
            self.animateSplit(1.0);
        } else {
            self.animateSplit(0.0);
        }
    }

    if ((self.collapsing or self.collapsed_state) and our_size >= self.init_opts.collapsed_size) {
        // expanding
        self.collapsing = false;
        self.collapsed_state = false;
        if (self.init_opts.uncollapse_ratio) |ratio| {
            self.animateSplit(ratio);
        } else if (self.split_ratio.* > 0.5) {
            self.animateSplit(0.5);
        } else {
            // we were on the second widget, this will
            // "remember" we were on it
            self.animateSplit(0.4999);
        }
    }

    if (dvui.animationGet(self.wd.id, "_split_ratio")) |a| {
        self.split_ratio.* = a.value();

        if (self.collapsing and a.done()) {
            self.collapsing = false;
            self.collapsed_state = true;
        }
    }

    self.data().register();

    self.data().borderAndBackground(.{});
    self.prevClip = dvui.clip(self.data().contentRectScale().r);

    dvui.parentSet(self.widget());
    if (self.data().accesskit_node()) |ak_node| {
        AccessKit.nodeAddAction(ak_node, AccessKit.Action.focus);
        AccessKit.nodeAddAction(ak_node, AccessKit.Action.set_value);
        AccessKit.nodeSetMinNumericValue(ak_node, 0);
        AccessKit.nodeSetMaxNumericValue(ak_node, 1);
        AccessKit.nodeSetNumericValue(ak_node, self.split_ratio.*);
    }
}