52 lines
1.9 KiB
Zig
52 lines
1.9 KiB
Zig
const basic_models = @import("../models/basic_models.zig");
|
|
const Point2_f = basic_models.Point2_f;
|
|
const Canvas = @import("../Canvas.zig");
|
|
const Document = @import("../models/Document.zig");
|
|
const pipeline = @import("../render/cpu/pipeline.zig");
|
|
const Transform = pipeline.Transform;
|
|
|
|
pub const ToolContext = struct {
|
|
canvas: *Canvas,
|
|
document_point: Point2_f,
|
|
selected_object_id: ?u64,
|
|
|
|
pub fn addObject(self: *const ToolContext, template: Document.Object) !void {
|
|
var obj = template;
|
|
const local_pos = self.computeLocalPosition();
|
|
try obj.setProperty(self.canvas.allocator, .{ .data = .{ .position = local_pos } });
|
|
try self.canvas.document.addObjectUnderParentId(self.canvas.allocator, self.selected_object_id, obj);
|
|
self.canvas.requestRedraw();
|
|
}
|
|
|
|
fn computeLocalPosition(self: *const ToolContext) Point2_f {
|
|
if (self.selected_object_id) |parent_id| {
|
|
if (findWorldTransformById(self.canvas.document, parent_id)) |parent_world| {
|
|
return pipeline.worldToLocalTransform(parent_world, self.document_point.x, self.document_point.y);
|
|
}
|
|
}
|
|
return self.document_point;
|
|
}
|
|
};
|
|
|
|
fn findWorldTransformById(doc: *Document, target_id: u64) ?Transform {
|
|
const identity = Transform{};
|
|
for (doc.objects.items) |*obj| {
|
|
if (findWorldTransformInTree(obj, identity, target_id)) |t| return t;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
fn findWorldTransformInTree(obj: *const Document.Object, parent: Transform, target_id: u64) ?Transform {
|
|
const local = Transform.init(obj);
|
|
const world = Transform.compose(parent, local);
|
|
if (obj.id == target_id) return world;
|
|
for (obj.children.items) |*child| {
|
|
if (findWorldTransformInTree(child, world, target_id)) |t| return t;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub const Tool = struct {
|
|
onCanvasClick: *const fn (*const ToolContext) anyerror!void,
|
|
};
|