diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f4a8325..e171c37 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ { "label": "zig: build", "type": "shell", - "command": "zig build -Doptimize=Debug", + "command": "zig build", "group": { "kind": "build", "isDefault": true diff --git a/src/Toolbar.zig b/src/Toolbar.zig index b5cd5b0..f541994 100644 --- a/src/Toolbar.zig +++ b/src/Toolbar.zig @@ -9,12 +9,12 @@ pub const ToolDescriptor = struct { }; tools: []const ToolDescriptor, -selected_index: usize, +selected_index: ?usize, pub fn init(tools_list: []const ToolDescriptor) Toolbar { return .{ .tools = tools_list, - .selected_index = 0, + .selected_index = null, }; } @@ -22,9 +22,22 @@ pub fn deinit(_: *Toolbar) void {} pub fn currentDescriptor(self: *const Toolbar) ?*const ToolDescriptor { if (self.tools.len == 0) return null; - return &self.tools[self.selected_index]; + if (self.selected_index) |index| { + return &self.tools[index]; + } + return null; } -pub fn select(self: *Toolbar, index: usize) void { - if (index < self.tools.len) self.selected_index = index; +pub fn select(self: *Toolbar, index: ?usize) void { + if (index == self.selected_index) { + self.selected_index = null; + return; + } + if (index) |i| { + if (i < self.tools.len) { + self.selected_index = i; + } + } else { + self.selected_index = null; + } } diff --git a/src/icons.zig b/src/icons.zig index aff6e5a..97cd3a8 100644 --- a/src/icons.zig +++ b/src/icons.zig @@ -1,3 +1,6 @@ const dvui = @import("dvui"); pub const line = dvui.entypo.line_graph; +pub const ellipse = dvui.entypo.circle; +pub const arc = dvui.entypo.loop; +pub const broken = dvui.entypo.flow_line; diff --git a/src/tools.zig b/src/tools.zig index 24c4164..e2cd353 100644 --- a/src/tools.zig +++ b/src/tools.zig @@ -1,5 +1,8 @@ const Toolbar = @import("Toolbar.zig"); const line = @import("tools/line.zig"); +const ellipse = @import("tools/ellipse.zig"); +const arc = @import("tools/arc.zig"); +const broken = @import("tools/broken.zig"); const icons = @import("icons.zig"); pub const default_tools = [_]Toolbar.ToolDescriptor{ @@ -8,4 +11,19 @@ pub const default_tools = [_]Toolbar.ToolDescriptor{ .icon_tvg = icons.line, .implementation = &line.tool, }, + .{ + .name = "Ellipse", + .icon_tvg = icons.ellipse, + .implementation = &ellipse.tool, + }, + .{ + .name = "Arc", + .icon_tvg = icons.arc, + .implementation = &arc.tool, + }, + .{ + .name = "Broken line", + .icon_tvg = icons.broken, + .implementation = &broken.tool, + }, }; diff --git a/src/tools/arc.zig b/src/tools/arc.zig new file mode 100644 index 0000000..d5f58c4 --- /dev/null +++ b/src/tools/arc.zig @@ -0,0 +1,12 @@ +const Tool = @import("../Tool.zig"); +const shape = @import("../models/shape/shape.zig"); + +fn onCanvasClick(ctx: *const Tool.ToolContext) !void { + const canvas = ctx.canvas; + var obj = shape.createObject(canvas.document.allocator, .arc) catch return; + defer obj.deinit(canvas.allocator); + try obj.setProperty(canvas.document.allocator, .{ .data = .{ .position = ctx.document_point } }); + try canvas.document.addObject(obj); + canvas.requestRedraw(); +} +pub const tool = Tool.Tool{ .onCanvasClick = onCanvasClick }; diff --git a/src/tools/broken.zig b/src/tools/broken.zig new file mode 100644 index 0000000..ae3df5d --- /dev/null +++ b/src/tools/broken.zig @@ -0,0 +1,12 @@ +const Tool = @import("../Tool.zig"); +const shape = @import("../models/shape/shape.zig"); + +fn onCanvasClick(ctx: *const Tool.ToolContext) !void { + const canvas = ctx.canvas; + var obj = shape.createObject(canvas.document.allocator, .broken) catch return; + defer obj.deinit(canvas.allocator); + try obj.setProperty(canvas.document.allocator, .{ .data = .{ .position = ctx.document_point } }); + try canvas.document.addObject(obj); + canvas.requestRedraw(); +} +pub const tool = Tool.Tool{ .onCanvasClick = onCanvasClick }; diff --git a/src/tools/ellipse.zig b/src/tools/ellipse.zig new file mode 100644 index 0000000..7d17c34 --- /dev/null +++ b/src/tools/ellipse.zig @@ -0,0 +1,12 @@ +const Tool = @import("../Tool.zig"); +const shape = @import("../models/shape/shape.zig"); + +fn onCanvasClick(ctx: *const Tool.ToolContext) !void { + const canvas = ctx.canvas; + var obj = shape.createObject(canvas.document.allocator, .ellipse) catch return; + defer obj.deinit(canvas.allocator); + try obj.setProperty(canvas.document.allocator, .{ .data = .{ .position = ctx.document_point } }); + try canvas.document.addObject(obj); + canvas.requestRedraw(); +} +pub const tool = Tool.Tool{ .onCanvasClick = onCanvasClick }; diff --git a/src/ui/canvas_view.zig b/src/ui/canvas_view.zig index e2e6141..8672f1b 100644 --- a/src/ui/canvas_view.zig +++ b/src/ui/canvas_view.zig @@ -196,16 +196,21 @@ fn drawToolbar(canvas: *Canvas) void { }, ); { + var to_select: ?usize = null; for (tools_list, 0..) |*tool_desc, i| { - const is_selected = (canvas.toolbar.selected_index == i); + const is_selected = canvas.toolbar.selected_index == i; + const selected_fill = dvui.themeGet().focus; const opts: dvui.Options = .{ .id_extra = i, - .color_fill = if (is_selected) dvui.themeGet().fill else undefined, + .color_fill = if (is_selected) selected_fill else null, }; if (dvui.buttonIcon(@src(), tool_desc.name, tool_desc.icon_tvg, .{}, .{}, opts)) { - canvas.toolbar.select(i); + to_select = i; } } + if (to_select) |index| { + canvas.toolbar.select(index); + } } bar.deinit(); }