DVUI

draggable

Parameters

#
src:std.builtin.SourceLocation
std.builtin.SourceLocation
init_opts:draggableInitOptions
draggableInitOptions
opts:dvui.Options
dvui.Options

Source

Implementation

#
pub fn draggable(src: std.builtin.SourceLocation, init_opts: draggableInitOptions, opts: dvui.Options) ?dvui.Point.Physical {
    var iw: dvui.IconWidget = undefined;
    iw.init(src, "reorder_drag_icon", init_opts.tvg_bytes orelse dvui.entypo.menu, .{}, opts);
    var ret: ?dvui.Point.Physical = null;
    loop: for (dvui.events()) |*e| {
        if (!iw.matchEvent(e))
            continue;

        switch (e.evt) {
            .mouse => |me| {
                if (me.action == .press and me.button.pointer()) {
                    e.handle(@src(), iw.data());
                    dvui.captureMouse(iw.data(), e.num);
                    const reo_rect: ?dvui.Rect.Physical = if (init_opts.reorderable) |reo| reo.data().rectScale().r else null;
                    const rect: dvui.Rect.Physical = init_opts.rect orelse reo_rect orelse iw.data().rectScale().r;
                    dvui.dragPreStart(me.button, me.p, .{ .offset = rect.topLeft().diff(me.p), .size = rect.size() });
                } else if (me.action == .motion) {
                    if (dvui.captured(iw.data().id)) {
                        e.handle(@src(), iw.data());
                        if (dvui.dragging(me.p, null)) |_| {
                            ret = me.p;
                            if (init_opts.reorderable) |reo| {
                                reo.reorder.dragStart(reo.data().id.asUsize(), me.p, e.num); // reorder grabs capture
                            }
                            break :loop;
                        }
                    }
                }
            },
            else => {},
        }
    }
    iw.draw();
    iw.deinit();
    return ret;
}