From 989502edf9a6c3dea1a7661eb3163181ba94cec2 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Tue, 2 Feb 2021 14:49:50 +0100 Subject: [PATCH] Cleaned up code, implemented rectangle selection. --- README.md | 3 ++- src/actions.zig | 2 +- src/draw.zig | 10 ++++++++++ src/level.zig | 6 ------ src/main.zig | 23 +++++++++++++++++------ src/mouse.zig | 11 +++-------- src/movement.zig | 45 ++++++++++++++++++++------------------------- 7 files changed, 53 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index aecd88f..70f2dec 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This is a work in progress program in unusable state. # Short term design decisions Subject to change. +* Efficiency, simplicity and clarity are key goals. * Fully keyboard driven modal editing. Mouse support is secondary. * GUI application made in [Zig](https://ziglang.org/) with [raylib](https://www.raylib.com/). @@ -44,7 +45,7 @@ Verbs: Modes: * ``: normal mode, default * `i`: free selection mode -* `v`: rectangle selection mode [not implemented] +* `v`: rectangle selection mode * `c`: camera mode [not implemented] # Mouse control diff --git a/src/actions.zig b/src/actions.zig index 4b78f71..9121baf 100644 --- a/src/actions.zig +++ b/src/actions.zig @@ -25,7 +25,7 @@ pub const ActionCat = enum { pub const Action = struct { category: ActionCat, // Only one of these should be set, and only one should be used. - function_move: fn (*Vec2, conf.arg_type, bool) movement.SelectionUpdate = movement.move_left, + function_move: fn (*Vec2, conf.arg_type) movement.SelectionUpdate = movement.move_left, function_verb: fn (*Level, conf.arg_type) void = verbs.delete, function_scale: fn (scaling.scale_type) scaling.scale_type = scaling.scale_reset, next_mode: Mode = Mode.normal, diff --git a/src/draw.zig b/src/draw.zig index c3b7b69..4c1378a 100644 --- a/src/draw.zig +++ b/src/draw.zig @@ -8,6 +8,7 @@ const ray = @cImport({ }); const Vec2 = @import("vec2.zig"); +const Rect = @import("rect.zig"); const scaling = @import("scaling.zig"); const Mode = @import("modes.zig").Mode; @@ -23,3 +24,12 @@ pub fn cursor(scale: scaling.scale_type, offset: Vec2, pos: Vec2, mode: Mode) vo }; ray.DrawRectangleLines(x, y, scale, scale, color); } + +/// Draw rectangle selection preview. +pub fn rectangle_selection(scale: scaling.scale_type, offset: Vec2, rect: Rect) void { + const x = (rect.left_x - offset.x) * scale; + const w = (rect.right_x - rect.left_x + 1) * scale; + const y = (rect.top_y - offset.y) * scale; + const h = (rect.bottom_y - rect.top_y + 1) * scale; + ray.DrawRectangleLines(x, y, w, h, ray.SKYBLUE); +} diff --git a/src/level.zig b/src/level.zig index bbc2458..2f676e5 100644 --- a/src/level.zig +++ b/src/level.zig @@ -135,12 +135,6 @@ pub fn select_rect(self: *Self, rect: Rect, state: bool) void { /// Apply selection update to selection *kof*. pub fn apply_selection_update(self: *Self, selection_update: SelectionUpdate) void { - // The update is exclusive, forget everything before it. - if (selection_update.exclusive) { - // Clear selection. - self.select_clear(false); - } - // Apply changes. self.select_rect(selection_update.area, selection_update.state); } diff --git a/src/main.zig b/src/main.zig index c8382a1..aef1814 100644 --- a/src/main.zig +++ b/src/main.zig @@ -17,6 +17,7 @@ const Rect = @import("rect.zig"); const Mouse = @import("mouse.zig"); const draw = @import("draw.zig"); const movement = @import("movement.zig"); +const verbs = @import("verbs.zig"); const scaling = @import("scaling.zig"); const actions = @import("actions.zig"); const ActionsDef = actions.ActionsDef; @@ -45,16 +46,19 @@ pub fn main() void { // Create camera. // TODO: Can't move camera, implement camera mode. - var camera: Vec2 = Vec2.init(0, 0); + var camera: Vec2 = comptime Vec2.init(0, 0); // Init scale, used by drawing code. var scale: scaling.scale_type = scaling.scale_default; // Create mouse. - var mouse: Mouse = Mouse.init(); + var mouse: Mouse = comptime Mouse.init(); // Create cursor. - var cursor: Vec2 = Vec2.init(0, 0); + var cursor: Vec2 = comptime Vec2.init(0, 0); + + // Used by rectangle selection mode. + var cursor_before: Vec2 = comptime Vec2.init(0, 0); // Set default mode. var mode: Mode = Mode.normal; @@ -132,14 +136,13 @@ pub fn main() void { 0; const action: actions.Action = bindings[key].*; - const exclusive_movement: bool = false; const apply_selection: bool = (mode == Mode.select); switch (action.category) { .none => std.log.info("No action bound to {}.", .{key}), .movement => { const selection_update: movement.SelectionUpdate = - action.function_move(&cursor, 1, exclusive_movement); + action.function_move(&cursor, 1); if (apply_selection and selection_update.active) { level.apply_selection_update(selection_update); } @@ -151,6 +154,12 @@ pub fn main() void { scale = action.function_scale(scale); }, .mode => { + // Rectangle selection! + if (mode == Mode.rectangle) { + const selection = Rect.init_from_vec2(cursor, cursor_before); + level.select_rect(selection, true); + } + cursor_before = cursor; // Save position before selection. mode = action.next_mode; }, } @@ -193,7 +202,7 @@ pub fn main() void { cursor = mouse.pos; // Reset selection on right click. if (right_click) { - level.apply_selection_update(movement.move_but_dont(&cursor, 1, true)); + verbs.clear_selection(&level, 1); } // Set position. mouse.start_pos = mouse.pos; @@ -219,6 +228,8 @@ pub fn main() void { level.draw(scale, camera); level.draw_selection(scale, camera); draw.cursor(scale, camera, cursor, mode); + if (mode == Mode.rectangle) + draw.rectangle_selection(scale, camera, Rect.init_from_vec2(cursor, cursor_before)); mouse.draw(scale, camera); //ray.DrawFPS(0, 0); } diff --git a/src/mouse.zig b/src/mouse.zig index 4a82549..e0a76f8 100644 --- a/src/mouse.zig +++ b/src/mouse.zig @@ -12,11 +12,10 @@ const std = @import("std"); const Vec2 = @import("vec2.zig"); const Rect = @import("rect.zig"); const scaling = @import("scaling.zig"); +const draw_fn = @import("draw.zig"); const Self = @This(); -const preview_color = ray.SKYBLUE; - pub const MouseMode = enum { wait, // Skip one turn. idle, @@ -43,15 +42,11 @@ pub fn draw(self: *Self, scale: scaling.scale_type, offset: Vec2) void { MouseMode.sel => { const x = (self.pos.x - offset.y) * scale; const y = (self.pos.y - offset.y) * scale; - ray.DrawRectangleLines(x, y, scale, scale, preview_color); + ray.DrawRectangleLines(x, y, scale, scale, ray.SKYBLUE); }, MouseMode.rect_sel => { const rect = Rect.init_from_vec2(self.pos, self.start_pos); - const x = (rect.left_x - offset.x) * scale; - const w = (rect.right_x - rect.left_x + 1) * scale; - const y = (rect.top_y - offset.y) * scale; - const h = (rect.bottom_y - rect.top_y + 1) * scale; - ray.DrawRectangleLines(x, y, w, h, preview_color); + draw_fn.rectangle_selection(scale, offset, rect); }, else => {}, } diff --git a/src/movement.zig b/src/movement.zig index 6fd96c9..a584ae1 100644 --- a/src/movement.zig +++ b/src/movement.zig @@ -17,13 +17,12 @@ const maxIntVec2 = comptime maxInt(Vec2.int_type); /// Describe changes to make on selection. pub const SelectionUpdate = struct { active: bool, - exclusive: bool, area: Rect, state: bool, }; /// Universal move system, prefer direction wrappers. -fn move(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool, dx: i2, dy: i2) SelectionUpdate { +fn move(cursor: *Vec2, arg: conf.arg_type, dx: i2, dy: i2) SelectionUpdate { const before: Vec2 = cursor.*; if (dx > 0) { @@ -51,58 +50,54 @@ fn move(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool, dx: i2, dy return SelectionUpdate{ .active = true, - .exclusive = exclusive_selection, - .area = if (exclusive_selection) - Rect.init_from_vec2(cursor.*, cursor.*) - else - Rect.init_from_vec2(before, cursor.*), + .area = Rect.init_from_vec2(before, cursor.*), .state = true, }; } /// Just don't move. -pub fn move_but_dont(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, 0, 0); +pub fn move_but_dont(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, 0, 0); } /// Try to move the cursor `n` times left. -pub fn move_left(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, -1, 0); +pub fn move_left(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, -1, 0); } /// Try to move the cursor `n` times right. -pub fn move_right(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, 1, 0); +pub fn move_right(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, 1, 0); } /// Try to move the cursor `n` times up. -pub fn move_up(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, 0, -1); +pub fn move_up(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, 0, -1); } /// Try to move the cursor `n` times down. -pub fn move_down(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, 0, 1); +pub fn move_down(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, 0, 1); } /// Try to move the cursor `n` times up and left. -pub fn move_up_left(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, -1, -1); +pub fn move_up_left(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, -1, -1); } /// Try to move the cursor `n` times up and right. -pub fn move_up_right(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, 1, -1); +pub fn move_up_right(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, 1, -1); } /// Try to move the cursor `n` times down and left. -pub fn move_down_left(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, -1, 1); +pub fn move_down_left(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, -1, 1); } /// Try to move the cursor `n` times down and right. -pub fn move_down_right(cursor: *Vec2, arg: conf.arg_type, exclusive_selection: bool) SelectionUpdate { - return move(cursor, arg, exclusive_selection, 1, 1); +pub fn move_down_right(cursor: *Vec2, arg: conf.arg_type) SelectionUpdate { + return move(cursor, arg, 1, 1); } test "move left" {