Кнопки для точек на кривой
This commit is contained in:
@@ -41,6 +41,7 @@ pub fn getProperty(self: Object, tag: std.meta.Tag(PropertyData)) ?*const Proper
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Забирает владение Property
|
||||
pub fn setProperty(self: *Object, allocator: std.mem.Allocator, prop: Property) !void {
|
||||
for (self.properties.items, 0..) |*p, i| {
|
||||
if (std.meta.activeTag(p.data) == std.meta.activeTag(prop.data)) {
|
||||
|
||||
@@ -8,6 +8,7 @@ const PropertyData = @import("../models/Property.zig").Data;
|
||||
const Rect_i = @import("../models/basic_models.zig").Rect_i;
|
||||
const Tool = @import("../toolbar/Tool.zig");
|
||||
const RenderStats = @import("../render/RenderStats.zig");
|
||||
const icons = @import("../icons.zig");
|
||||
|
||||
pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale: dvui.RectScale) void {
|
||||
var textured = dvui_ext.texturedBox(content_rect_scale, dvui.Rect.all(20));
|
||||
@@ -66,7 +67,10 @@ pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale:
|
||||
var properties_box = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .horizontal },
|
||||
.{},
|
||||
.{
|
||||
.gravity_x = 1.0,
|
||||
.gravity_y = 0.0,
|
||||
},
|
||||
);
|
||||
{
|
||||
drawPropertiesPanel(canvas, obj);
|
||||
@@ -307,13 +311,12 @@ fn drawPropertiesPanel(canvas: *Canvas, selected_object: *Document.Object) void
|
||||
@src(),
|
||||
.{ .dir = .vertical },
|
||||
.{
|
||||
.gravity_x = 1.0,
|
||||
.gravity_y = 0.0,
|
||||
.padding = dvui.Rect.all(8),
|
||||
.corner_radius = dvui.Rect.all(8),
|
||||
.background = true,
|
||||
.color_fill = dvui.Color.black.opacity(0.2),
|
||||
.min_size_content = .{ .w = 220 },
|
||||
.min_size_content = .width(300),
|
||||
.max_size_content = .width(300),
|
||||
.margin = dvui.Rect{ .w = 32, .y = 16, .h = 100 },
|
||||
},
|
||||
);
|
||||
@@ -394,17 +397,12 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
switch (prop.data) {
|
||||
.position => |pos| {
|
||||
var next = pos;
|
||||
const doc = canvas.document;
|
||||
const min_x = -doc.size.w;
|
||||
const max_x = doc.size.w;
|
||||
const min_y = -doc.size.h;
|
||||
const max_y = doc.size.h;
|
||||
var changed = false;
|
||||
{
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "x:", .{}, .{});
|
||||
const T = @TypeOf(next.x);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.x, .min = @as(T, min_x), .max = @as(T, max_x) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.x }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -412,7 +410,7 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "y:", .{}, .{});
|
||||
const T = @TypeOf(next.y);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.y, .min = @as(T, min_y), .max = @as(T, max_y) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.y }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -483,13 +481,12 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
},
|
||||
.size => |size| {
|
||||
var next = size;
|
||||
const doc = canvas.document;
|
||||
var changed = false;
|
||||
{
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "w:", .{}, .{});
|
||||
const T = @TypeOf(next.w);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.w, .min = @as(T, 0.0), .max = @as(T, doc.size.w) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.w, .min = @as(T, 0.0) }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -497,7 +494,7 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "h:", .{}, .{});
|
||||
const T = @TypeOf(next.h);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.h, .min = @as(T, 0.0), .max = @as(T, doc.size.h) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.h, .min = @as(T, 0.0) }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -508,13 +505,12 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
},
|
||||
.radii => |radii| {
|
||||
var next = radii;
|
||||
const doc = canvas.document;
|
||||
var changed = false;
|
||||
{
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "x:", .{}, .{});
|
||||
const T = @TypeOf(next.x);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.x, .min = @as(T, 0.0), .max = @as(T, doc.size.w) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.x, .min = @as(T, 0.0) }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -522,7 +518,7 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "y:", .{}, .{});
|
||||
const T = @TypeOf(next.y);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.y, .min = @as(T, 0.0), .max = @as(T, doc.size.h) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.y, .min = @as(T, 0.0) }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -533,17 +529,12 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
},
|
||||
.end_point => |pt| {
|
||||
var next = pt;
|
||||
const doc = canvas.document;
|
||||
const min_x = -doc.size.w;
|
||||
const max_x = doc.size.w;
|
||||
const min_y = -doc.size.h;
|
||||
const max_y = doc.size.h;
|
||||
var changed = false;
|
||||
{
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "x:", .{}, .{});
|
||||
const T = @TypeOf(next.x);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.x, .min = @as(T, min_x), .max = @as(T, max_x) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.x }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -551,7 +542,7 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
var subrow = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .horizontal });
|
||||
dvui.labelNoFmt(@src(), "y:", .{}, .{});
|
||||
const T = @TypeOf(next.y);
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.y, .min = @as(T, min_y), .max = @as(T, max_y) }, .{ .expand = .horizontal });
|
||||
const res = dvui.textEntryNumber(@src(), T, .{ .value = &next.y }, .{ .expand = .horizontal });
|
||||
subrow.deinit();
|
||||
changed = res.changed or changed;
|
||||
}
|
||||
@@ -561,7 +552,127 @@ fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Prope
|
||||
}
|
||||
},
|
||||
.points => |points| {
|
||||
dvui.label(@src(), "Points: {d}", .{points.items.len}, .{});
|
||||
var list = points.clone(canvas.allocator) catch {
|
||||
dvui.label(@src(), "Points: {d}", .{points.items.len}, .{});
|
||||
return;
|
||||
};
|
||||
dvui.label(@src(), "Points: {d}", .{list.items.len}, .{});
|
||||
|
||||
var changed = false;
|
||||
var to_delete: ?usize = null;
|
||||
|
||||
for (list.items, 0..) |*pt, i| {
|
||||
// Одна строка: крестик удаления + paned с X/Y пополам
|
||||
var subrow = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .horizontal },
|
||||
.{
|
||||
.expand = .horizontal,
|
||||
.id_extra = i,
|
||||
},
|
||||
);
|
||||
{
|
||||
// Крестик удаления
|
||||
if (dvui.buttonIcon(@src(), "Delete", icons.cross, .{}, .{}, .{
|
||||
.id_extra = i,
|
||||
.gravity_y = 0.5,
|
||||
.margin = .{
|
||||
.x = 8,
|
||||
},
|
||||
})) {
|
||||
to_delete = i;
|
||||
}
|
||||
|
||||
// Панель с X и Y, разделёнными пополам
|
||||
var split_ratio: f32 = 0.5;
|
||||
var paned = dvui.paned(
|
||||
@src(),
|
||||
.{
|
||||
.direction = .horizontal,
|
||||
.collapsed_size = 0.0,
|
||||
.split_ratio = &split_ratio,
|
||||
.handle_size = 0,
|
||||
},
|
||||
.{
|
||||
.expand = .horizontal,
|
||||
},
|
||||
);
|
||||
{
|
||||
if (paned.showFirst()) {
|
||||
var x_box = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .horizontal },
|
||||
.{ .expand = .both },
|
||||
);
|
||||
{
|
||||
dvui.labelNoFmt(@src(), "x:", .{}, .{
|
||||
.gravity_y = 0.5,
|
||||
});
|
||||
const Tx = @TypeOf(pt.x);
|
||||
const res_x = dvui.textEntryNumber(
|
||||
@src(),
|
||||
Tx,
|
||||
.{ .value = &pt.x },
|
||||
.{ .expand = .horizontal },
|
||||
);
|
||||
changed = res_x.changed or changed;
|
||||
}
|
||||
x_box.deinit();
|
||||
}
|
||||
|
||||
if (paned.showSecond()) {
|
||||
var y_box = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .horizontal },
|
||||
.{ .expand = .both },
|
||||
);
|
||||
{
|
||||
dvui.labelNoFmt(@src(), "y:", .{}, .{
|
||||
.gravity_y = 0.5,
|
||||
});
|
||||
const Ty = @TypeOf(pt.y);
|
||||
const res_y = dvui.textEntryNumber(
|
||||
@src(),
|
||||
Ty,
|
||||
.{ .value = &pt.y },
|
||||
.{ .expand = .horizontal },
|
||||
);
|
||||
changed = res_y.changed or changed;
|
||||
}
|
||||
y_box.deinit();
|
||||
}
|
||||
}
|
||||
paned.deinit();
|
||||
}
|
||||
subrow.deinit();
|
||||
}
|
||||
|
||||
// Удаление выбранной точки
|
||||
if (to_delete) |idx| {
|
||||
_ = list.orderedRemove(idx);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Кнопка добавления новой точки (одна на весь список)
|
||||
if (dvui.button(@src(), "Add point", .{}, .{})) {
|
||||
const T = @TypeOf(list.items[0]);
|
||||
const new_point: T = if (list.items.len > 0)
|
||||
list.items[list.items.len - 1]
|
||||
else
|
||||
.{ .x = 0, .y = 0 };
|
||||
list.append(canvas.allocator, new_point) catch {};
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
obj.setProperty(canvas.allocator, .{ .data = .{ .points = list } }) catch {
|
||||
list.deinit(canvas.allocator);
|
||||
return;
|
||||
};
|
||||
canvas.requestRedraw();
|
||||
} else {
|
||||
list.deinit(canvas.allocator);
|
||||
}
|
||||
},
|
||||
.fill_rgba => |rgba| {
|
||||
drawColorEditor(canvas, obj, rgba, true);
|
||||
|
||||
Reference in New Issue
Block a user