Files
Zivro/src/models/Object.zig

94 lines
2.8 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;
};
id: u64,
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, next_id: *u64) !void {
const obj = try template.clone(allocator, next_id);
try self.children.append(allocator, obj);
}
pub fn clone(self: Object, allocator: std.mem.Allocator, next_id: *u64) !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, next_id));
}
return .{
.id = allocId(next_id),
.shape = self.shape,
.properties = properties_list,
.children = children_list,
};
}
fn allocId(next_id: *u64) u64 {
const id = next_id.*;
next_id.* += 1;
return id;
}
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;
}