Event Handling
ratatui_ruby provides a rich, object-oriented event system that supports multiple coding styles, from simple boolean predicates to modern Ruby pattern matching.
Events are retrieved using RatatuiRuby.poll_event. This method returns an instance of a subclass of RatatuiRuby::Event (e.g., RatatuiRuby::Event::Key, RatatuiRuby::Event::Mouse). When no event is available, it returns RatatuiRuby::Event::None—a null object that safely responds to all event predicates with false.
1. Blocking vs. Polling
Most applications run in a loop (e.g., a game loop or UI loop). To prevent high CPU usage, the loop should wait briefly for input.
-
Default (Polling):
RatatuiRuby.poll_event(no args) waits for 0.016s (approx 60 FPS). If no event occurs, it returnsRatatuiRuby::Event::None. This keeps the application responsive. -
Blocking:
RatatuiRuby.poll_event(timeout: nil)waits forever until an event occurs. Use this for scripts that only react to input and do not need to update the UI on a timer. -
Non-Blocking:
RatatuiRuby.poll_event(timeout: 0.0)returns immediately.
2. Symbol and String Comparison (Simplest)
For simple key events, RatatuiRuby::Event::Key objects can be compared directly to Symbols or Strings. This is often the quickest way to get started.
-
String: Matches the key character (e.g., “a”, “q”).
-
Symbol: Matches special keys (e.g.,
:enter,:esc) or modifier combinations (e.g.,:ctrl_c).
[!NOTE] On macOS, the Option key is mapped to
alt. The Command key is typically intercepted by the terminal emulator and may not be sent to the application, or it may be mapped to Meta/Alt depending on your terminal settings.
For a complete list of supported keys, modifiers, and event types, please refer to the API Documentation for RatatuiRuby::Event.
event = RatatuiRuby.poll_event # 1. Check for quit keys if event == "q" || event == :ctrl_c break end # 2. Check for special key if event == :enter submit_form end
3. Predicate Methods (Intermediate)
If you need more control or logic (e.g. if/elsif), or need to handle non-key events like Resize or Mouse, use the predicate methods.
Polymorphic Predicates
Safe to call on any event object. They return true only for the matching event type.
Available: key?, mouse?, resize?, paste?, focus_gained?, focus_lost?.
event = RatatuiRuby.poll_event if event.key? handle_keypress(event) elsif event.mouse? handle_click(event) elsif event.resize? resize_layout(event.width, event.height) end
Helper Predicates
Specific to certain event classes to simplify checks.
RatatuiRuby::Event::Key
-
ctrl?,alt?,shift?: Check if modifier is held. -
text?: Returnstrueif the event is a printable character (length == 1).
if event.key? && event.ctrl? && event.code == "s" save_file end
RatatuiRuby::Event::Mouse
-
down?,up?,drag?: Check mouse action. -
scroll_up?,scroll_down?: Check scroll direction.
if event.mouse? && event.scroll_up? scroll_view(-1) end
4. Pattern Matching (Powerful)
For complex applications, Ruby 3.0+ Pattern Matching with the type: discriminator is the most idiomatic and concise approach.
loop do case RatatuiRuby.poll_event # Match specific key code in type: :key, code: "q" break # Match complex combo in type: :key, code: "c", modifiers: ["ctrl"] break # Capture variables in type: :key, code: "up" | "down" => direction move_cursor(direction) # Match mouse events in type: :mouse, kind: "down", x:, y: handle_click(x, y) in type: :none # No event available, continue loop end end
Summary of Event Classes
| Event Class | Discriminator (type:) |
Attributes | Predicate |
|---|---|---|---|
RatatuiRuby::Event::Key |
:key |
code, modifiers
|
key? |
RatatuiRuby::Event::Mouse |
:mouse |
kind, x, y, button, modifiers
|
mouse? |
RatatuiRuby::Event::Resize |
:resize |
width, height
|
resize? |
RatatuiRuby::Event::Paste |
:paste |
content |
paste? |
RatatuiRuby::Event::FocusGained |
:focus_gained |
(none) | focus_gained? |
RatatuiRuby::Event::FocusLost |
:focus_lost |
(none) | focus_lost? |
RatatuiRuby::Event::None |
:none |
(none) | none? |