mirror of https://git.sr.ht/~kikoodx/kble
Actions are no longer hardcoded, dynamic bindings base.
This commit is contained in:
parent
e54660228a
commit
3361e859ed
|
@ -0,0 +1,113 @@
|
|||
// 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.
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
const movement = @import("movement.zig");
|
||||
const Vec2 = @import("vec2.zig");
|
||||
const Level = @import("level.zig");
|
||||
|
||||
pub const ActionCat = enum {
|
||||
none, // do nothing
|
||||
movement, // move and change selection
|
||||
verb, // do stuff with selection
|
||||
scale, // change draw scaling
|
||||
};
|
||||
|
||||
pub const Action = struct {
|
||||
category: ActionCat,
|
||||
toggle: bool = false, // bool that can be passed to actions, i.e. exclusive for movement
|
||||
// Only one of these should be set, and only one should be used.
|
||||
function_move: fn (*Vec2, u32, bool) movement.SelectionUpdate = movement.move_left,
|
||||
function_verb: fn (*Level) void = Level.action_delete,
|
||||
};
|
||||
|
||||
pub const ActionsDef = .{
|
||||
.none = Action{
|
||||
.category = ActionCat.none,
|
||||
},
|
||||
// Movement.
|
||||
// Left.
|
||||
.move_left = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_left,
|
||||
},
|
||||
.move_LEFT = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_left,
|
||||
},
|
||||
// Right.
|
||||
.move_right = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_right,
|
||||
},
|
||||
.move_RIGHT = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_right,
|
||||
},
|
||||
// Up.
|
||||
.move_up = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up,
|
||||
},
|
||||
.move_UP = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up,
|
||||
},
|
||||
// Down.
|
||||
.move_down = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_down,
|
||||
},
|
||||
.move_DOWN = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_down,
|
||||
},
|
||||
// Up-left.
|
||||
.move_up_left = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up_left,
|
||||
},
|
||||
.move_UP_LEFT = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up_left,
|
||||
},
|
||||
// Up-right.
|
||||
.move_up_right = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up_right,
|
||||
},
|
||||
.move_UP_RIGHT = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up_right,
|
||||
},
|
||||
// Down-left.
|
||||
.move_down_left = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_down_left,
|
||||
},
|
||||
.move_DOWN_LEFT = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_up_left,
|
||||
},
|
||||
// Down-right.
|
||||
.move_down_right = Action{
|
||||
.toggle = true,
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_down_right,
|
||||
},
|
||||
.move_DOWN_RIGHT = Action{
|
||||
.category = ActionCat.movement,
|
||||
.function_move = movement.move_down_right,
|
||||
},
|
||||
};
|
115
src/main.zig
115
src/main.zig
|
@ -15,6 +15,11 @@ const maxInt = std.math.maxInt;
|
|||
const Level = @import("level.zig");
|
||||
const Vec2 = @import("vec2.zig");
|
||||
const movement = @import("movement.zig");
|
||||
const actions = @import("actions.zig");
|
||||
const ActionsDef = actions.ActionsDef;
|
||||
const ActionCat = actions.ActionCat;
|
||||
|
||||
const char_range = 255;
|
||||
|
||||
pub fn main() !void {
|
||||
// Create allocator
|
||||
|
@ -45,6 +50,26 @@ pub fn main() !void {
|
|||
// Create cursor.
|
||||
var cursor: Vec2 = Vec2.init(0, 0);
|
||||
|
||||
// Create binding "table".
|
||||
var bindings = [_]*const actions.Action{&actions.ActionsDef.none} ** char_range;
|
||||
// Set default bindings
|
||||
bindings['h'] = &ActionsDef.move_left;
|
||||
bindings['H'] = &ActionsDef.move_LEFT;
|
||||
bindings['j'] = &ActionsDef.move_down;
|
||||
bindings['J'] = &ActionsDef.move_DOWN;
|
||||
bindings['k'] = &ActionsDef.move_up;
|
||||
bindings['K'] = &ActionsDef.move_UP;
|
||||
bindings['l'] = &ActionsDef.move_right;
|
||||
bindings['L'] = &ActionsDef.move_RIGHT;
|
||||
bindings['y'] = &ActionsDef.move_up_left;
|
||||
bindings['Y'] = &ActionsDef.move_UP_LEFT;
|
||||
bindings['u'] = &ActionsDef.move_up_right;
|
||||
bindings['U'] = &ActionsDef.move_UP_RIGHT;
|
||||
bindings['b'] = &ActionsDef.move_down_left;
|
||||
bindings['B'] = &ActionsDef.move_DOWN_LEFT;
|
||||
bindings['n'] = &ActionsDef.move_down_right;
|
||||
bindings['N'] = &ActionsDef.move_DOWN_RIGHT;
|
||||
|
||||
// Create input buffer (ASCII).
|
||||
const input_buffer_len = 255;
|
||||
var input_buffer: [input_buffer_len]u32 = undefined;
|
||||
|
@ -57,72 +82,58 @@ pub fn main() !void {
|
|||
var input_cursor: u8 = 0;
|
||||
|
||||
while (!ray.WindowShouldClose()) {
|
||||
// Get keyboard input.
|
||||
var key = ray.GetCharPressed();
|
||||
// Check if more characters have been pressed.
|
||||
while (key != 0) {
|
||||
// Add key to buffer.
|
||||
input_buffer[input_cursor] = @intCast(u32, key);
|
||||
input_cursor += 1;
|
||||
// Avoid writing out of memory.
|
||||
if (input_cursor >= input_buffer_len)
|
||||
input_cursor = input_buffer_len - 1;
|
||||
{
|
||||
// Get keyboard input.
|
||||
var key = ray.GetCharPressed();
|
||||
// Check if more characters have been pressed.
|
||||
while (key != 0) {
|
||||
// Add key to buffer.
|
||||
input_buffer[input_cursor] = @intCast(u32, key);
|
||||
input_cursor += 1;
|
||||
// Avoid writing out of memory.
|
||||
if (input_cursor >= input_buffer_len)
|
||||
input_cursor = input_buffer_len - 1;
|
||||
|
||||
key = ray.GetCharPressed();
|
||||
key = ray.GetCharPressed();
|
||||
}
|
||||
}
|
||||
|
||||
// Process buffer content.
|
||||
// Read the buffer backwards. This is placeholder logic.
|
||||
while (input_cursor > 0) {
|
||||
input_cursor -= 1;
|
||||
const action = input_buffer[input_cursor];
|
||||
const key = if (input_buffer[input_cursor] <= char_range)
|
||||
input_buffer[input_cursor]
|
||||
else
|
||||
0;
|
||||
|
||||
const movement_command = switch (action) {
|
||||
'A'...'Z' => action - 'A' + 'a',
|
||||
else => action,
|
||||
};
|
||||
const was_lowercase: bool = movement_command == action;
|
||||
const action: actions.Action = bindings[key].*;
|
||||
|
||||
// Check for movement.
|
||||
const selection_update: movement.SelectionUpdate = switch (movement_command) {
|
||||
// Movement.
|
||||
'h' => movement.move_left(&cursor, 1, was_lowercase),
|
||||
'j' => movement.move_down(&cursor, 1, was_lowercase),
|
||||
'k' => movement.move_up(&cursor, 1, was_lowercase),
|
||||
'l' => movement.move_right(&cursor, 1, was_lowercase),
|
||||
// Diagonals and rectangle selection.
|
||||
'y' => movement.move_up_left(&cursor, 1, was_lowercase),
|
||||
'u' => movement.move_up_right(&cursor, 1, was_lowercase),
|
||||
'b' => movement.move_down_left(&cursor, 1, was_lowercase),
|
||||
'n' => movement.move_down_right(&cursor, 1, was_lowercase),
|
||||
else => blk: {
|
||||
break :blk movement.SelectionUpdate{
|
||||
.active = false,
|
||||
.area = undefined,
|
||||
.exclusive = undefined,
|
||||
.state = undefined,
|
||||
};
|
||||
switch (action.category) {
|
||||
.none => {},
|
||||
.movement => {
|
||||
const selection_update: movement.SelectionUpdate =
|
||||
action.function_move(&cursor, 1, action.toggle);
|
||||
if (selection_update.active) {
|
||||
level.apply_selection_update(selection_update);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (selection_update.active) {
|
||||
level.apply_selection_update(selection_update);
|
||||
} else {
|
||||
// If didn't input movement, check for action.
|
||||
switch (action) {
|
||||
// Actions.
|
||||
'd' => level.action_delete(),
|
||||
.verb => {
|
||||
action.function_verb(&level);
|
||||
},
|
||||
.scale => {
|
||||
// TODO: move this to functions, doesn't make any sense here
|
||||
// Zoom (pog feature).
|
||||
'-' => if (scale > 3) {
|
||||
if (scale > 3) {
|
||||
scale -= 1;
|
||||
},
|
||||
'+' => if (scale < comptime maxInt(scale_type)) {
|
||||
}
|
||||
if (scale < comptime maxInt(scale_type)) {
|
||||
scale += 1;
|
||||
},
|
||||
}
|
||||
// Reset zoom.
|
||||
'=' => scale = scale_default,
|
||||
else => log("No action for {} key.", .{action}),
|
||||
}
|
||||
scale = scale_default;
|
||||
log("No action for {} key.", .{action});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue