//! Input module for `zterm`. Contains structs to represent key events and mouse events. const std = @import("std"); const Point = @import("point.zig").Point; pub const Mouse = packed struct { x: u16, y: u16, button: Button, kind: Kind, pub const Button = enum(u8) { left, middle, right, none, wheel_up = 64, wheel_down = 65, wheel_right = 66, wheel_left = 67, button_8 = 128, button_9 = 129, button_10 = 130, button_11 = 131, }; pub const Kind = enum(u2) { press, release, motion, drag, }; pub fn eql(this: @This(), other: @This()) bool { return std.meta.eql(this, other); } pub fn in(this: @This(), origin: Point, size: Point) bool { return this.x >= origin.x and this.x < size.x + origin.x and this.y >= origin.y and this.y < size.y + origin.y; } }; pub const Key = packed struct { cp: u21, mod: Modifier = .{}, pub const Modifier = packed struct { shift: bool = false, alt: bool = false, ctrl: bool = false, }; /// Compare _this_ `Key` with an _other_ `Key`. /// /// # Example /// /// Configure `ctrl+c` to quit the application (done in main event loop of the application): /// /// ```zig /// switch (event) { /// .quit => break, /// .key => |key| if (key.eql(.{ .cp = 'c', .mod = .{ .ctrl = true } })) app.quit.set(), /// else => {}, /// } /// ``` pub fn eql(this: @This(), other: @This()) bool { return std.meta.eql(this, other); } /// Determine if the `Key` is an ascii character that can be printed to /// the screen. This means that the code point of the `Key` is an ascii /// character between 32 - 255 (with the exception of 127 = Delete) and no /// modifiers (alt and/or ctrl) are used. /// /// # Example /// /// Get user input's from the .key event from the application event loop: /// /// ```zig /// switch (event) { /// .key => |key| if (key.isAscii()) try this.input.append(key.cp), /// else => {}, /// } /// ``` pub fn isAscii(this: @This()) bool { return this.mod.alt == false and this.mod.ctrl == false and // no modifier keys (this.cp >= 32 and this.cp <= 126 or // ascii printable characters (except for input.Delete) this.cp >= 128 and this.cp <= 255); // extended ascii codes } test "isAscii with ascii character" { try std.testing.expectEqual(true, isAscii(.{ .cp = 'c' })); try std.testing.expectEqual(false, isAscii(.{ .cp = 'c', .mod = .{ .ctrl = true } })); try std.testing.expectEqual(false, isAscii(.{ .cp = 'c', .mod = .{ .alt = true } })); try std.testing.expectEqual(false, isAscii(.{ .cp = 'c', .mod = .{ .alt = true, .ctrl = true } })); } test "isAscii with non-ascii character" { try std.testing.expectEqual(false, isAscii(.{ .cp = Escape })); try std.testing.expectEqual(false, isAscii(.{ .cp = Enter })); try std.testing.expectEqual(false, isAscii(.{ .cp = Enter, .mod = .{ .alt = true } })); } test "isAscii with excluded input.Delete" { try std.testing.expectEqual(false, isAscii(.{ .cp = Delete })); try std.testing.expectEqual(false, isAscii(.{ .cp = Delete, .mod = .{ .alt = false, .ctrl = false } })); } }; // codepoints for keys pub const Tab: u21 = 0x09; pub const Enter: u21 = 0x0D; pub const Escape: u21 = 0x1B; pub const Space: u21 = 0x20; pub const Backspace: u21 = 0x7F; // kitty key encodings (re-used here) pub const Insert: u21 = 57348; pub const Delete: u21 = 57349; pub const Left: u21 = 57350; pub const Right: u21 = 57351; pub const Up: u21 = 57352; pub const Down: u21 = 57353; pub const PageUp: u21 = 57354; pub const PageDown: u21 = 57355; pub const Home: u21 = 57356; pub const End: u21 = 57357; pub const CapsLock: u21 = 57358; pub const ScrollLock: u21 = 57359; pub const NumLock: u21 = 57360; pub const PrintScreen: u21 = 57361; pub const Pause: u21 = 57362; pub const Menu: u21 = 57363; pub const F1: u21 = 57364; pub const F2: u21 = 57365; pub const F3: u21 = 57366; pub const F4: u21 = 57367; pub const F5: u21 = 57368; pub const F6: u21 = 57369; pub const F7: u21 = 57370; pub const F8: u21 = 57371; pub const F9: u21 = 57372; pub const F10: u21 = 57373; pub const F11: u21 = 57374; pub const F12: u21 = 57375; pub const F13: u21 = 57376; pub const F14: u21 = 57377; pub const F15: u21 = 57378; pub const F16: u21 = 57379; pub const F17: u21 = 57380; pub const F18: u21 = 57381; pub const F19: u21 = 57382; pub const F20: u21 = 57383; pub const F21: u21 = 57384; pub const F22: u21 = 57385; pub const F23: u21 = 57386; pub const F24: u21 = 57387; pub const F25: u21 = 57388; pub const F26: u21 = 57389; pub const F27: u21 = 57390; pub const F28: u21 = 57391; pub const F29: u21 = 57392; pub const F30: u21 = 57393; pub const F31: u21 = 57394; pub const F32: u21 = 57395; pub const F33: u21 = 57396; pub const F34: u21 = 57397; pub const F35: u21 = 57398; pub const Kp0: u21 = 57399; pub const Kp1: u21 = 57400; pub const Kp2: u21 = 57401; pub const Kp3: u21 = 57402; pub const Kp4: u21 = 57403; pub const Kp5: u21 = 57404; pub const Kp6: u21 = 57405; pub const Kp7: u21 = 57406; pub const Kp8: u21 = 57407; pub const Kp9: u21 = 57408; pub const KpDecimal: u21 = 57409; pub const KpDivide: u21 = 57410; pub const KpMultiply: u21 = 57411; pub const KpSubtract: u21 = 57412; pub const KpAdd: u21 = 57413; pub const KpEnter: u21 = 57414; pub const KpEqual: u21 = 57415; pub const KpSeparator: u21 = 57416; pub const KpLeft: u21 = 57417; pub const KpRight: u21 = 57418; pub const KpUp: u21 = 57419; pub const KpDown: u21 = 57420; pub const KpPageUp: u21 = 57421; pub const KpPageDown: u21 = 57422; pub const KpHome: u21 = 57423; pub const KpEnd: u21 = 57424; pub const KpInsert: u21 = 57425; pub const KpDelete: u21 = 57426; pub const KpBegin: u21 = 57427; pub const MediaPlay: u21 = 57428; pub const MediaPause: u21 = 57429; pub const MediaPlayPause: u21 = 57430; pub const MediaReverse: u21 = 57431; pub const MediaStop: u21 = 57432; pub const MediaFastForward: u21 = 57433; pub const MediaRewind: u21 = 57434; pub const MediaTrackNext: u21 = 57435; pub const MediaTrackPrevious: u21 = 57436; pub const MediaRecord: u21 = 57437; pub const LowerVolume: u21 = 57438; pub const RaiseVolume: u21 = 57439; pub const MuteVolume: u21 = 57440; pub const LeftShift: u21 = 57441; pub const LeftControl: u21 = 57442; pub const LeftAlt: u21 = 57443; pub const LeftSuper: u21 = 57444; pub const LeftHyper: u21 = 57445; pub const LeftMeta: u21 = 57446; pub const RightShift: u21 = 57447; pub const RightControl: u21 = 57448; pub const RightAlt: u21 = 57449; pub const RightSuper: u21 = 57450; pub const RightHyper: u21 = 57451; pub const RightMeta: u21 = 57452; pub const IsoLevel3Shift: u21 = 57453; pub const IsoLevel5Shift: u21 = 57454;