86 lines
2.6 KiB
Zig
86 lines
2.6 KiB
Zig
const std = @import("std");
|
|
const Property = @import("Property.zig").Property;
|
|
const PropertyData = @import("Property.zig").Data;
|
|
const Object = @This();
|
|
|
|
pub const ShapeKind = enum {
|
|
line,
|
|
ellipse,
|
|
arc,
|
|
broken,
|
|
};
|
|
|
|
const default_common_data = [_]PropertyData{
|
|
.{ .position = .{ .x = 0, .y = 0 } },
|
|
.{ .angle = 0 },
|
|
.{ .scale = .{ .scale_x = 1, .scale_y = 1 } },
|
|
.{ .visible = true },
|
|
.{ .opacity = 1.0 },
|
|
.{ .locked = false },
|
|
.{ .stroke_rgba = 0x000000FF }, // чёрный, полная непрозрачность
|
|
.{ .thickness = 2.0 },
|
|
};
|
|
|
|
pub const defaultCommonProperties: [default_common_data.len]Property = blk: {
|
|
var result: [default_common_data.len]Property = undefined;
|
|
for (default_common_data, &result) |d, *p| {
|
|
p.* = .{ .data = d };
|
|
}
|
|
break :blk result;
|
|
};
|
|
|
|
shape: ShapeKind,
|
|
properties: std.ArrayList(Property),
|
|
children: std.ArrayList(Object),
|
|
|
|
pub fn getProperty(self: Object, tag: std.meta.Tag(PropertyData)) ?*const PropertyData {
|
|
for (self.properties.items) |*prop| {
|
|
if (std.meta.activeTag(prop.data) == tag) return &prop.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
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)) {
|
|
if (p.data == .points) p.data.points.deinit(allocator);
|
|
self.properties.items[i] = prop;
|
|
return;
|
|
}
|
|
}
|
|
return error.PropertyNotFound;
|
|
}
|
|
|
|
pub fn addChild(self: *Object, allocator: std.mem.Allocator, template: Object) !void {
|
|
const obj = try template.clone(allocator);
|
|
try self.children.append(allocator, obj);
|
|
}
|
|
|
|
pub fn clone(self: Object, allocator: std.mem.Allocator) !Object {
|
|
var properties_list = std.ArrayList(Property).empty;
|
|
errdefer properties_list.deinit(allocator);
|
|
for (self.properties.items) |prop| {
|
|
try properties_list.append(allocator, try prop.clone(allocator));
|
|
}
|
|
|
|
var children_list = std.ArrayList(Object).empty;
|
|
errdefer children_list.deinit(allocator);
|
|
for (self.children.items) |child| {
|
|
try children_list.append(allocator, try child.clone(allocator));
|
|
}
|
|
|
|
return .{
|
|
.shape = self.shape,
|
|
.properties = properties_list,
|
|
.children = children_list,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *Object, allocator: std.mem.Allocator) void {
|
|
for (self.children.items) |*child| child.deinit(allocator);
|
|
self.children.deinit(allocator);
|
|
for (self.properties.items) |*prop| prop.deinit(allocator);
|
|
self.properties.deinit(allocator);
|
|
self.* = undefined;
|
|
}
|