1
0
Fork 0
zenolith/src/treevents/KeyInput.zig

72 lines
2.5 KiB
Zig

//! This treevent is fired when a key is typed, pressed or released on the keyboard.
//! When a key is pressed BOTH an event with the .down action and one with the .press action (afterwards)
//! will be fired. The latter may be repeated if the key is held down afterwards.
const key = @import("../key.zig");
const treev = @import("../treevent.zig");
const Widget = @import("../widget.zig").Widget;
pub const ptrfire = true;
pub const Action = enum {
down,
up,
/// Fired for a key being "pressed". This may be repeated when a key is held down.
press,
};
action: Action,
/// This is the logical, remapped key.
/// This may be null if, for example, text was entered using an input method
/// without any key being actually pressed or if the platform gets text events that cannot be
/// correlated to a keypress from a badly designed, GLFW-style API.
key: ?key.Keycode,
/// This is the physical key, or null if it isn't known to the platform.
physical: ?key.Keycode = null,
/// The modifiers that were active while this key was held.
modifiers: key.Modifiers = .{},
/// The modifiers that were "used up" in generating the text from this key.
/// To get the effective modifiers, you should exclude modifiers that are set here.
/// Credit for this API design goes to Ghostty!
consumed_modifiers: key.Modifiers = .{},
/// The UTF-8 encoded text that was generated by this key event,
/// or an empty string if no text was generated.
text: []const u8 = "",
/// True if the key event was emitted by a key being held down.
repeat: bool = false,
/// Set this to true if you've handled the key event. It will stop postFire handling.
handled: bool = false,
const KeyPress = @This();
/// Returns this event's modifiers with the consumed modifiers excluded.
pub fn effectiveModifiers(self: KeyPress) key.Modifiers {
return .{
.shift = self.modifiers.shift and !self.consumed_modifiers.shift,
.ctrl = self.modifiers.ctrl and !self.consumed_modifiers.ctrl,
.alt = self.modifiers.alt and !self.consumed_modifiers.alt,
.meta = self.modifiers.meta and !self.consumed_modifiers.meta,
.mode = self.modifiers.mode and !self.consumed_modifiers.mode,
};
}
pub fn dispatch(self: *KeyPress, widget: *Widget) !void {
for (widget.children()) |child| {
try child.treevent(self);
}
}
pub fn postFire(self: *KeyPress, widget: *Widget) !void {
if (!self.handled and self.action == .press and self.key == .tab) {
try treev.fire(widget, treev.FocusNext{});
}
}