DVUI

init

FloatingWidget is a subwindow to show any temporary floating thing. It doesn't focus itself (as a subwindow), and whether it is shown or not is entirely up to the calling code.

Don't put menus or menuItems in a floating widget because those depend on focus to work. FloatingMenu is made for that.

Use FloatingWindowWidget for a floating window that the user can change size, move around, and adjust stacking.

Parameters

#
self:*FloatingWidget
*FloatingWidget
src:std.builtin.SourceLocation
std.builtin.SourceLocation
init_opts:InitOptions
InitOptions
opts_in:Options
Options

Source

Implementation

#
pub fn init(self: *FloatingWidget, src: std.builtin.SourceLocation, init_opts: InitOptions, opts_in: Options) void {
    const scale_val = dvui.parentGet().screenRectScale(Rect{}).s / dvui.windowNaturalScale();
    var opts = opts_in;
    if (opts.min_size_content) |msc| {
        opts.min_size_content = msc.scale(scale_val, Size);
    }
    self.* = .{
        // get scale from parent
        .scale_val = scale_val,
        .init_opts = init_opts,
        .wd = WidgetData.init(src, .{ .subwindow = true }, defaults.override(opts).override(.{
            // passing options.rect will stop WidgetData.init from calling
            // rectFor/minSizeForChild which is important because we are outside
            // normal layout
            .rect = opts.rect orelse .{},
        })),
    };

    if (init_opts.from) |pt| {
        if (dvui.minSizeGet(self.data().id)) |_| {
            const ms = dvui.minSize(self.data().id, opts.min_sizeGet());
            const npt = dvui.windowRectScale().pointFromPhysical(pt);
            var start: Rect = .fromPoint(.cast(npt));
            start = start.toSize(ms);
            start.x -= start.w * (1.0 - init_opts.from_gravity_x);
            start.y -= start.h * (1.0 - init_opts.from_gravity_y);
            self.data().rect = .cast(dvui.placeOnScreen(dvui.windowRect(), .{}, .none, .cast(start)));
        } else {
            // need another frame to get our min size
            dvui.refresh(null, @src(), self.data().id);
        }
    }

    self.data().register();
    dvui.parentSet(self.widget());

    // standard subwindow stuff
    {
        const rs = self.data().rectScale();
        self.render_ftb.initReset();
        self.prev_windowInfo = dvui.subwindowCurrentSet(self.data().id, null);
        dvui.subwindowAdd(self.data().id, self.data().rect, rs.r, false, self.prev_windowInfo.id, self.init_opts.mouse_events);
        dvui.captureMouseMaintain(.{ .id = self.data().id, .rect = rs.r, .subwindow_id = self.data().id });
        self.prevClip = dvui.clipGet();
        dvui.clipSet(dvui.windowRectPixels()); // break out of whatever clipping we were in
        self.prev_scroll = dvui.ScrollContainerWidget.scrollSet(null);
    }

    self.data().borderAndBackground(.{});

    self.scaler.init(@src(), .{ .scale = &self.scale_val }, .{ .expand = .both });
}