DVUI

show_stroke_test_window

Source

Implementation

#
pub fn show_stroke_test_window() void {
    var win = dvui.floatingWindow(@src(), .{ .open_flag = &stroke_test_show }, .{});
    defer win.deinit();
    win.dragAreaSet(dvui.windowHeader("Stroke Test", "", &stroke_test_show));

    const thickness = dvui.dataGetPtrDefault(null, win.data().id, "thickness", f32, 1.0);
    const closed = dvui.dataGetPtrDefault(null, win.data().id, "closed", bool, false);
    const endcap = dvui.dataGetPtrDefault(null, win.data().id, "encap", dvui.Path.StrokeOptions.EndCapStyle, .none);

    dvui.label(@src(), "Stroke Test", .{}, .{});
    _ = dvui.checkbox(@src(), closed, "Closed (right-click)", .{});
    {
        var hbox = dvui.box(@src(), .{ .dir = .horizontal }, .{});
        defer hbox.deinit();

        dvui.label(@src(), "Endcap Style", .{}, .{});

        if (dvui.radio(@src(), endcap.* == .none, "None", .{})) {
            endcap.* = .none;
        }

        if (dvui.radio(@src(), endcap.* == .square, "Square", .{})) {
            endcap.* = .square;
        }
    }

    const dragi = dvui.dataGetPtrDefault(null, win.data().id, "dragi", ?usize, null);
    var points: std.ArrayList(dvui.Point) = .empty;
    if (dvui.dataGetSlice(null, win.data().id, "points", []dvui.Point)) |ps| points = .fromOwnedSlice(ps);
    defer dvui.dataSetSlice(null, win.data().id, "points", points.items);

    _ = dvui.sliderEntry(@src(), "thick: {d:0.2}", .{ .value = thickness }, .{ .expand = .horizontal });

    var st = dvui.box(@src(), .{}, .{ .min_size_content = .{ .w = 400, .h = 400 }, .expand = .both });
    defer st.deinit();

    const rs = st.data().contentRectScale();
    const fill_color = dvui.Color{ .r = 200, .g = 200, .b = 200, .a = 255 };
    for (points.items, 0..) |p, i| {
        const rect: dvui.Rect = .{ .x = p.x - 10, .y = p.y - 10, .w = 20, .h = 20 };
        rs.rectToPhysical(rect).fill(.round(1), .{ .color = fill_color, .fade = 1.0 });

        _ = i;
        //_ = dvui.button(@src(), i, "Floating", .{}, .{ .rect = dvui.Rect.fromPoint(p) });
    }

    var builder: dvui.Path.Builder = .init(dvui.currentWindow().arena());
    for (points.items) |p| builder.addPoint(rs.pointToPhysical(p));
    const stroke_color = dvui.Color{ .r = 0, .g = 0, .b = 255, .a = 150 };
    builder.build().stroke(.{ .thickness = rs.s * thickness.*, .color = stroke_color, .closed = closed.*, .endcap_style = endcap.* });

    for (dvui.events()) |*e| {
        if (!dvui.eventMatchSimple(e, st.data())) continue;

        switch (e.evt) {
            .mouse => |me| {
                const mp = rs.pointFromPhysical(me.p);
                switch (me.action) {
                    .press => {
                        if (me.button.pointer()) {
                            e.handle(@src(), st.data());
                            dragi.* = null;

                            for (points.items, 0..) |p, i| {
                                const dp = me.p.diff(rs.pointToPhysical(p));
                                if (@abs(dp.x) < 10 and @abs(dp.y) < 10) {
                                    dragi.* = i;
                                    break;
                                }
                            }

                            if (dragi.* == null) {
                                dragi.* = points.items.len;
                                points.append(dvui.currentWindow().arena(), mp) catch @panic("OOM");
                            } else {
                                dvui.captureMouse(st.data(), e.num);
                                dvui.dragPreStart(me.button, me.p, .{ .cursor = .crosshair });
                            }
                        }

                        if (me.button == .right) {
                            closed.* = !closed.*;
                            dvui.refresh(null, @src(), st.data().id);
                        }
                    },
                    .release => {
                        if (me.button.pointer()) {
                            e.handle(@src(), st.data());
                            dvui.captureMouse(null, e.num);
                            dvui.dragEnd();
                        }
                    },
                    .motion => {
                        e.handle(@src(), st.data());
                        if (dvui.dragging(me.p, null)) |dps| {
                            const dp = dps.scale(1 / rs.s, Point);
                            if (dragi.*) |di| {
                                points.items[di].x += dp.x;
                                points.items[di].y += dp.y;
                            }
                            dvui.refresh(null, @src(), st.data().id);
                        }
                    },
                    .wheel_y => |ticks| {
                        e.handle(@src(), st.data());
                        const base: f32 = 1.005;
                        const zs = @exp(@log(base) * ticks);
                        if (zs != 1.0) {
                            thickness.* *= zs;
                            dvui.refresh(null, @src(), st.data().id);
                        }
                    },
                    else => {},
                }
            },
            else => {},
        }
    }
}