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(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = "vaxis",
|
.name = "vaxis",
|
||||||
.root_source_file = .{ .path = "examples/image.zig" },
|
.root_source_file = .{ .path = "examples/text_input.zig" },
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,7 @@ const log = std.log.scoped(.main);
|
||||||
// for a single event loop with exhaustive switching. Booya
|
// for a single event loop with exhaustive switching. Booya
|
||||||
const Event = union(enum) {
|
const Event = union(enum) {
|
||||||
key_press: vaxis.Key,
|
key_press: vaxis.Key,
|
||||||
|
mouse: vaxis.Mouse,
|
||||||
winsize: vaxis.Winsize,
|
winsize: vaxis.Winsize,
|
||||||
focus_in,
|
focus_in,
|
||||||
focus_out,
|
focus_out,
|
||||||
|
|
|
@ -13,4 +13,34 @@ pub const Shape = enum {
|
||||||
cell,
|
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 testing = std.testing;
|
||||||
const Event = @import("event.zig").Event;
|
const Event = @import("event.zig").Event;
|
||||||
const Key = @import("Key.zig");
|
const Key = @import("Key.zig");
|
||||||
|
const Mouse = @import("Mouse.zig");
|
||||||
const CodePointIterator = @import("ziglyph").CodePointIterator;
|
const CodePointIterator = @import("ziglyph").CodePointIterator;
|
||||||
const graphemeBreak = @import("ziglyph").graphemeBreak;
|
const graphemeBreak = @import("ziglyph").graphemeBreak;
|
||||||
|
|
||||||
|
@ -32,6 +33,14 @@ const Sequence = struct {
|
||||||
empty_state: std.StaticBitSet(16) = std.StaticBitSet(16).initEmpty(),
|
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
|
// the state of the parser
|
||||||
const State = enum {
|
const State = enum {
|
||||||
ground,
|
ground,
|
||||||
|
@ -226,6 +235,49 @@ pub fn parse(self: *Parser, input: []const u8) !Result {
|
||||||
'E' => Key.kp_begin,
|
'E' => Key.kp_begin,
|
||||||
'F' => Key.end,
|
'F' => Key.end,
|
||||||
'H' => Key.home,
|
'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,
|
'P' => Key.f1,
|
||||||
'Q' => Key.f2,
|
'Q' => Key.f2,
|
||||||
'R' => Key.f3,
|
'R' => Key.f3,
|
||||||
|
|
|
@ -157,6 +157,11 @@ pub fn run(
|
||||||
vx.postEvent(.{ .key_press = mut_key });
|
vx.postEvent(.{ .key_press = mut_key });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.mouse => |mouse| {
|
||||||
|
if (@hasField(EventType, "mouse")) {
|
||||||
|
vx.postEvent(.{ .mouse = mouse });
|
||||||
|
}
|
||||||
|
},
|
||||||
.focus_in => {
|
.focus_in => {
|
||||||
if (@hasField(EventType, "focus_in")) {
|
if (@hasField(EventType, "focus_in")) {
|
||||||
vx.postEvent(.focus_in);
|
vx.postEvent(.focus_in);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
pub const Key = @import("Key.zig");
|
pub const Key = @import("Key.zig");
|
||||||
|
pub const Mouse = @import("Mouse.zig");
|
||||||
|
|
||||||
/// The events that Vaxis emits internally
|
/// The events that Vaxis emits internally
|
||||||
pub const Event = union(enum) {
|
pub const Event = union(enum) {
|
||||||
key_press: Key,
|
key_press: Key,
|
||||||
|
mouse: Mouse,
|
||||||
focus_in,
|
focus_in,
|
||||||
focus_out,
|
focus_out,
|
||||||
paste_start,
|
paste_start,
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub const Cell = cell.Cell;
|
||||||
pub const Style = cell.Style;
|
pub const Style = cell.Style;
|
||||||
|
|
||||||
pub const Key = @import("Key.zig");
|
pub const Key = @import("Key.zig");
|
||||||
|
pub const Mouse = @import("Mouse.zig");
|
||||||
pub const Winsize = @import("Tty.zig").Winsize;
|
pub const Winsize = @import("Tty.zig").Winsize;
|
||||||
|
|
||||||
pub const widgets = @import("widgets/main.zig");
|
pub const widgets = @import("widgets/main.zig");
|
||||||
|
|
Loading…
Reference in a new issue