mouse: implement mouse parsing and events
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
ad3ef19b87
commit
f3cf7bcfcd
7 changed files with 93 additions and 2 deletions
|
@ -20,7 +20,7 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "vaxis",
|
||||
.root_source_file = .{ .path = "examples/image.zig" },
|
||||
.root_source_file = .{ .path = "examples/text_input.zig" },
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
|
|
@ -11,6 +11,7 @@ const log = std.log.scoped(.main);
|
|||
// for a single event loop with exhaustive switching. Booya
|
||||
const Event = union(enum) {
|
||||
key_press: vaxis.Key,
|
||||
mouse: vaxis.Mouse,
|
||||
winsize: vaxis.Winsize,
|
||||
focus_in,
|
||||
focus_out,
|
||||
|
|
|
@ -13,4 +13,34 @@ pub const Shape = enum {
|
|||
cell,
|
||||
};
|
||||
|
||||
// TODO: mouse support
|
||||
pub const Button = enum(u8) {
|
||||
left,
|
||||
middle,
|
||||
right,
|
||||
none,
|
||||
wheel_up = 64,
|
||||
wheel_down = 65,
|
||||
button_8 = 128,
|
||||
button_9 = 129,
|
||||
button_10 = 130,
|
||||
button_11 = 131,
|
||||
};
|
||||
|
||||
pub const Modifiers = packed struct(u3) {
|
||||
shift: bool = false,
|
||||
alt: bool = false,
|
||||
ctrl: bool = false,
|
||||
};
|
||||
|
||||
pub const Type = enum {
|
||||
press,
|
||||
release,
|
||||
motion,
|
||||
drag,
|
||||
};
|
||||
|
||||
col: usize,
|
||||
row: usize,
|
||||
button: Button,
|
||||
mods: Modifiers,
|
||||
type: Type,
|
||||
|
|
|
@ -2,6 +2,7 @@ const std = @import("std");
|
|||
const testing = std.testing;
|
||||
const Event = @import("event.zig").Event;
|
||||
const Key = @import("Key.zig");
|
||||
const Mouse = @import("Mouse.zig");
|
||||
const CodePointIterator = @import("ziglyph").CodePointIterator;
|
||||
const graphemeBreak = @import("ziglyph").graphemeBreak;
|
||||
|
||||
|
@ -32,6 +33,14 @@ const Sequence = struct {
|
|||
empty_state: std.StaticBitSet(16) = std.StaticBitSet(16).initEmpty(),
|
||||
};
|
||||
|
||||
const mouse_bits = struct {
|
||||
const motion: u8 = 0b00100000;
|
||||
const buttons: u8 = 0b11000011;
|
||||
const shift: u8 = 0b00000100;
|
||||
const alt: u8 = 0b00001000;
|
||||
const ctrl: u8 = 0b00010000;
|
||||
};
|
||||
|
||||
// the state of the parser
|
||||
const State = enum {
|
||||
ground,
|
||||
|
@ -226,6 +235,49 @@ pub fn parse(self: *Parser, input: []const u8) !Result {
|
|||
'E' => Key.kp_begin,
|
||||
'F' => Key.end,
|
||||
'H' => Key.home,
|
||||
'M', 'm' => { // mouse event
|
||||
const priv = seq.private_indicator orelse {
|
||||
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||
return .{ .event = null, .n = i + 1 };
|
||||
};
|
||||
if (priv != '<') {
|
||||
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||
return .{ .event = null, .n = i + 1 };
|
||||
}
|
||||
if (seq.param_idx != 3) {
|
||||
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||
return .{ .event = null, .n = i + 1 };
|
||||
}
|
||||
const button: Mouse.Button = @enumFromInt(seq.params[0] & mouse_bits.buttons);
|
||||
const motion = seq.params[0] & mouse_bits.motion > 0;
|
||||
const shift = seq.params[0] & mouse_bits.shift > 0;
|
||||
const alt = seq.params[0] & mouse_bits.alt > 0;
|
||||
const ctrl = seq.params[0] & mouse_bits.ctrl > 0;
|
||||
const col: usize = seq.params[1] - 1;
|
||||
const row: usize = seq.params[2] - 1;
|
||||
|
||||
const mouse = Mouse{
|
||||
.button = button,
|
||||
.mods = .{
|
||||
.shift = shift,
|
||||
.alt = alt,
|
||||
.ctrl = ctrl,
|
||||
},
|
||||
.col = col,
|
||||
.row = row,
|
||||
.type = blk: {
|
||||
if (motion and button != Mouse.Button.none) {
|
||||
break :blk .drag;
|
||||
}
|
||||
if (motion and button == Mouse.Button.none) {
|
||||
break :blk .motion;
|
||||
}
|
||||
if (b == 'm') break :blk .release;
|
||||
break :blk .press;
|
||||
},
|
||||
};
|
||||
return .{ .event = .{ .mouse = mouse }, .n = i + 1 };
|
||||
},
|
||||
'P' => Key.f1,
|
||||
'Q' => Key.f2,
|
||||
'R' => Key.f3,
|
||||
|
|
|
@ -157,6 +157,11 @@ pub fn run(
|
|||
vx.postEvent(.{ .key_press = mut_key });
|
||||
}
|
||||
},
|
||||
.mouse => |mouse| {
|
||||
if (@hasField(EventType, "mouse")) {
|
||||
vx.postEvent(.{ .mouse = mouse });
|
||||
}
|
||||
},
|
||||
.focus_in => {
|
||||
if (@hasField(EventType, "focus_in")) {
|
||||
vx.postEvent(.focus_in);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
pub const Key = @import("Key.zig");
|
||||
pub const Mouse = @import("Mouse.zig");
|
||||
|
||||
/// The events that Vaxis emits internally
|
||||
pub const Event = union(enum) {
|
||||
key_press: Key,
|
||||
mouse: Mouse,
|
||||
focus_in,
|
||||
focus_out,
|
||||
paste_start,
|
||||
|
|
|
@ -6,6 +6,7 @@ pub const Cell = cell.Cell;
|
|||
pub const Style = cell.Style;
|
||||
|
||||
pub const Key = @import("Key.zig");
|
||||
pub const Mouse = @import("Mouse.zig");
|
||||
pub const Winsize = @import("Tty.zig").Winsize;
|
||||
|
||||
pub const widgets = @import("widgets/main.zig");
|
||||
|
|
Loading…
Reference in a new issue