Mouse support. Yes, I hate myself for this one.

This commit is contained in:
KikooDX 2021-02-01 00:30:28 +01:00
parent 1ebed24110
commit 8fc2e3fefb
5 changed files with 103 additions and 4 deletions

View File

@ -5,4 +5,7 @@
// included in all copies and substantial portions of the software.
//! Values and types used by different files and that don't fit in any.
/// Number passed to commands.
pub const arg_type = u16;
pub const arg_type: type = u16;
pub const mouse_enabled: bool = true;
pub const mouse_left_btn: c_int = 0;
pub const mouse_right_btn: c_int = 1;

View File

@ -102,7 +102,7 @@ pub fn draw_selection(self: *Self, scale: u16, offset: Vec2) void {
}
/// Set the `state` of a cell at `cursor` if possible
fn select_cell(self: *Self, cursor: Vec2, state: bool) void {
pub fn select_cell(self: *Self, cursor: Vec2, state: bool) void {
const target: u32 = @intCast(u32, cursor.y) * self.width + @intCast(u32, cursor.x);
if (target < self.width * self.height and target >= 0)
self.selection[target] = state;
@ -118,7 +118,7 @@ fn select_clear(self: *Self, state: bool) void {
}
/// Change state of all the cells in the rectangle range.
fn select_rect(self: *Self, rect: Rect, state: bool) void {
pub fn select_rect(self: *Self, rect: Rect, state: bool) void {
var cx: Rect.int_type = rect.left_x;
while (cx <= rect.right_x) {
defer cx += 1;

View File

@ -8,9 +8,13 @@ const ray = @cImport({
});
const std = @import("std");
const maxInt = std.math.maxInt;
const log = std.log.info;
const conf = @import("conf.zig");
const Level = @import("level.zig");
const Vec2 = @import("vec2.zig");
const Rect = @import("rect.zig");
const Mouse = @import("mouse.zig");
const movement = @import("movement.zig");
const scaling = @import("scaling.zig");
const actions = @import("actions.zig");
@ -43,6 +47,9 @@ pub fn main() !void {
// Init scale, used by drawing code.
var scale: scaling.scale_type = scaling.scale_default;
// Create mouse.
var mouse: Mouse = Mouse.init();
// Create cursor.
var cursor: Vec2 = Vec2.init(0, 0);
@ -132,6 +139,66 @@ pub fn main() !void {
}
}
// Mouse operations.
if (conf.mouse_enabled) {
// Update position.
{
// Set mouse offset.
ray.SetMouseOffset(camera.x, camera.y);
// Set mouse scaling.
ray.SetMouseScale(1.0 / @intToFloat(f32, scale), 1.0 / @intToFloat(f32, scale));
mouse.pos.x = @intCast(u16, ray.GetMouseX());
mouse.pos.y = @intCast(u16, ray.GetMouseY());
}
const left_press: bool = ray.IsMouseButtonPressed(conf.mouse_left_btn);
const left_release: bool = ray.IsMouseButtonReleased(conf.mouse_left_btn);
const right_press: bool = ray.IsMouseButtonPressed(conf.mouse_right_btn);
// State machine.
switch (mouse.mode) {
// See if can switch mode.
.idle => {
const mod_rect_sel: bool = ray.IsKeyDown(ray.KEY_LEFT_SHIFT) or
ray.IsKeyDown(ray.KEY_RIGHT_SHIFT);
if (left_press) { // Switch mode.
cursor = mouse.pos;
mouse.start_pos = mouse.pos;
mouse.mode = if (mod_rect_sel)
Mouse.MouseMode.rect_sel
else
Mouse.MouseMode.sel;
}
},
// Select stuff under the cursor.
.sel => {
cursor = mouse.pos;
level.select_cell(mouse.pos, true);
},
// Rectangle selection, see `left_release` for handling.
.rect_sel => {},
}
// If left button is released, get out of current mode and apply changes if necessary.
if (left_release) {
defer mouse.mode = Mouse.MouseMode.idle;
defer cursor = mouse.pos;
// Select area.
if (mouse.mode == Mouse.MouseMode.rect_sel) {
const selection = Rect.init_from_vec2(mouse.start_pos, mouse.pos);
level.select_rect(selection, true);
}
}
// Reset selection on right click.
if (right_press) {
cursor = mouse.pos;
level.apply_selection_update(movement.move_but_dont(&cursor, 1, true));
}
}
ray.BeginDrawing();
defer ray.EndDrawing();

29
src/mouse.zig Normal file
View File

@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021 KikooDX
// This file is part of [KBLE](https://sr.ht/~kikoodx/kble), which is
// MIT licensed. The MIT license requires this copyright notice to be
// included in all copies and substantial portions of the software.
//! Mouse (eurk) logic and operations.
const std = @import("std");
const Vec2 = @import("vec2.zig");
const Self = @This();
pub const MouseMode = enum {
idle,
sel,
rect_sel,
};
mode: MouseMode, // State.
pos: Vec2, // Where the cursor is.
start_pos: Vec2, // Used for rectangle selection.
pub fn init() Self {
return Self{
.mode = MouseMode.idle, // state
.pos = Vec2{ .x = 0, .y = 0 },
.start_pos = Vec2{ .x = 0, .y = 0 },
};
}

View File

@ -8,7 +8,7 @@ const std = @import("std");
const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub const scale_type = u16;
pub const scale_type = u8;
pub const scale_default: comptime_int = 16;
const scale_min: comptime_int = 3;
const scale_max: comptime_int = maxInt(scale_type);