pub struct KeyBinding {
pub code: KeyCode,
pub modifiers: KeyModifiers,
}Expand description
A keyboard shortcut definition.
Fields§
§code: KeyCode§modifiers: KeyModifiersImplementations§
Source§impl KeyBinding
impl KeyBinding
Sourcepub fn new(code: KeyCode, modifiers: KeyModifiers) -> Self
pub fn new(code: KeyCode, modifiers: KeyModifiers) -> Self
Create a new key binding.
Sourcepub fn key(code: KeyCode) -> Self
pub fn key(code: KeyCode) -> Self
Create a binding for a single key (no modifiers).
Examples found in repository?
examples/01_hello_world.rs (line 24)
19 fn render(&self, cx: Scope) -> View {
20 let show_help = state!(cx, || false);
21
22 // F1 toggles help
23 cx.use_command(
24 KeyBinding::key(KeyCode::F(1)),
25 with!(show_help => move || show_help.update(|v| *v = !*v)),
26 );
27
28 View::vstack()
29 .child(View::styled_text("Hello World").bold().build())
30 .child(View::gap(1))
31 .child(View::text("Welcome to Telex!"))
32 .child(View::gap(1))
33 .child(
34 View::styled_text("F1 for help • Ctrl+Q to quit")
35 .dim()
36 .build(),
37 )
38 .child(
39 View::modal()
40 .visible(show_help.get())
41 .title("Example 01: Hello World")
42 .on_dismiss(with!(show_help => move || show_help.set(false)))
43 .child(
44 View::vstack()
45 .child(View::styled_text("What you're seeing").bold().build())
46 .child(View::text(
47 "• Basic app structure with struct + Component trait",
48 ))
49 .child(View::text(
50 "• View::text() and View::styled_text() for display",
51 ))
52 .child(View::text("• View::vstack() for vertical layout"))
53 .child(View::gap(1))
54 .child(View::styled_text("Key concepts").bold().build())
55 .child(View::text("• Every Telex app implements Component"))
56 .child(View::text("• render() returns a View tree"))
57 .child(View::text("• No state yet - this is purely static"))
58 .child(View::gap(1))
59 .child(View::styled_text("Next up").bold().build())
60 .child(View::text("→ 02_counter: add state and interactivity"))
61 .child(View::gap(1))
62 .child(View::styled_text("Press Escape to close").dim().build())
63 .build(),
64 )
65 .build(),
66 )
67 .build()
68 }More examples
examples/30_image.rs (line 35)
30 fn render(&self, cx: Scope) -> View {
31 let show_help = state!(cx, || false);
32
33 // F1 toggles help
34 cx.use_command(
35 KeyBinding::key(KeyCode::F(1)),
36 with!(show_help => move || show_help.update(|v| *v = !*v)),
37 );
38 View::vstack()
39 .spacing(1)
40 .child(
41 View::styled_text("Image Widget Demo (Kitty Graphics)")
42 .bold()
43 .build(),
44 )
45 .child(View::text("Requires Kitty, Ghostty, or WezTerm terminal"))
46 .child(View::text(""))
47 // Load image from file path
48 .child(View::text("Logo (from file path):"))
49 .child(View::image().file("assets/telex-tui.png").build())
50 .child(View::text(""))
51 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
52 .child(
53 View::modal()
54 .visible(show_help.get())
55 .title("Example 30: Image")
56 .on_dismiss(with!(show_help => move || show_help.set(false)))
57 .child(
58 View::vstack()
59 .child(View::styled_text("What you're seeing").bold().build())
60 .child(View::text("• Image display via Kitty protocol"))
61 .child(View::text("• PNG/JPEG/GIF support"))
62 .child(View::text("• Loaded from file path"))
63 .child(View::gap(1))
64 .child(View::styled_text("Key concepts").bold().build())
65 .child(View::text("• View::image() displays images"))
66 .child(View::text("• .file(\"path\") loads from disk"))
67 .child(View::text("• .bytes(data) for embedded images"))
68 .child(View::text("• Works in Kitty/Ghostty/WezTerm"))
69 .child(View::gap(1))
70 .child(View::styled_text("Try this").bold().build())
71 .child(View::text("• Run in compatible terminal"))
72 .child(View::text("• See the Telex logo rendered"))
73 .child(View::gap(1))
74 .child(View::styled_text("Next up").bold().build())
75 .child(View::text("→ 31_animated_canvas: animations"))
76 .child(View::gap(1))
77 .child(View::styled_text("Press Escape to close").dim().build())
78 .build(),
79 )
80 .build(),
81 )
82 .build()
83 }examples/04_timer.rs (line 27)
22 fn render(&self, cx: Scope) -> View {
23 let show_help = state!(cx, || false);
24
25 // F1 toggles help
26 cx.use_command(
27 KeyBinding::key(KeyCode::F(1)),
28 with!(show_help => move || show_help.update(|v| *v = !*v)),
29 );
30
31 // Stream that yields elapsed seconds
32 let elapsed = stream!(cx, || {
33 (0u64..).inspect(|&s| {
34 if s > 0 {
35 std::thread::sleep(Duration::from_secs(1));
36 }
37 })
38 });
39
40 let seconds = elapsed.get();
41 let is_running = elapsed.is_loading();
42
43 // Format as MM:SS
44 let minutes = seconds / 60;
45 let secs = seconds % 60;
46 let time_display = format!("{:02}:{:02}", minutes, secs);
47
48 View::vstack()
49 .child(View::styled_text("Timer").color(Color::Cyan).bold().build())
50 .child(View::gap(1))
51 .child(
52 View::hstack()
53 .child(View::styled_text(&time_display).bold().build())
54 .child(if is_running {
55 View::styled_text(" ●").color(Color::Green).build()
56 } else {
57 View::styled_text(" ○").dim().build()
58 })
59 .build(),
60 )
61 .child(View::gap(1))
62 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
63 .child(
64 View::modal()
65 .visible(show_help.get())
66 .title("Example 04: Timer")
67 .on_dismiss(with!(show_help => move || show_help.set(false)))
68 .child(
69 View::vstack()
70 .child(View::styled_text("What you're seeing").bold().build())
71 .child(View::text("• stream!() macro for background data"))
72 .child(View::text("• Auto-updating UI without user input"))
73 .child(View::text("• Green dot = stream is running"))
74 .child(View::gap(1))
75 .child(View::styled_text("Key concepts").bold().build())
76 .child(View::text("• Streams run in background threads"))
77 .child(View::text("• Each yielded value triggers a re-render"))
78 .child(View::text("• is_loading() tells you if stream is active"))
79 .child(View::gap(1))
80 .child(View::styled_text("Try this").bold().build())
81 .child(View::text("• Just watch - the timer ticks automatically"))
82 .child(View::text("• No button presses needed for updates"))
83 .child(View::gap(1))
84 .child(View::styled_text("Next up").bold().build())
85 .child(View::text("→ 05_todo_list: text input and list management"))
86 .child(View::gap(1))
87 .child(View::styled_text("Press Escape to close").dim().build())
88 .build(),
89 )
90 .build(),
91 )
92 .build()
93 }examples/02_counter.rs (line 28)
19 fn render(&self, cx: Scope) -> View {
20 let count = state!(cx, || 0i32);
21 let show_help = state!(cx, || false);
22
23 let increment = with!(count => move || count.update(|n| *n += 1));
24 let decrement = with!(count => move || count.update(|n| *n -= 1));
25
26 // F1 toggles help
27 cx.use_command(
28 KeyBinding::key(KeyCode::F(1)),
29 with!(show_help => move || show_help.update(|v| *v = !*v)),
30 );
31
32 View::vstack()
33 .child(View::styled_text("Counter").bold().build())
34 .child(View::gap(1))
35 .child(View::text(format!("Count: {}", count.get())))
36 .child(View::gap(1))
37 .child(
38 View::hstack()
39 .child(
40 View::button()
41 .label("Decrement")
42 .on_press(decrement)
43 .build(),
44 )
45 .child(View::text(" "))
46 .child(
47 View::button()
48 .label("Increment")
49 .on_press(increment)
50 .build(),
51 )
52 .build(),
53 )
54 .child(View::gap(1))
55 .child(
56 View::styled_text("Tab to switch • Enter to press • F1 for help • Ctrl+Q to quit")
57 .dim()
58 .build(),
59 )
60 .child(
61 View::modal()
62 .visible(show_help.get())
63 .title("Example 02: Counter")
64 .on_dismiss(with!(show_help => move || show_help.set(false)))
65 .child(
66 View::vstack()
67 .child(View::styled_text("What you're seeing").bold().build())
68 .child(View::text("• state!() macro for reactive state"))
69 .child(View::text("• View::button() with on_press callbacks"))
70 .child(View::text(
71 "• The with!() macro for capturing state in closures",
72 ))
73 .child(View::gap(1))
74 .child(View::styled_text("Key concepts").bold().build())
75 .child(View::text("• State persists across renders"))
76 .child(View::text("• Updating state triggers a re-render"))
77 .child(View::text("• Tab navigates between focusable elements"))
78 .child(View::gap(1))
79 .child(View::styled_text("Try this").bold().build())
80 .child(View::text("• Press +/- rapidly - notice instant updates"))
81 .child(View::text(
82 "• The UI stays in sync with state automatically",
83 ))
84 .child(View::gap(1))
85 .child(View::styled_text("Next up").bold().build())
86 .child(View::text("→ 03_theme_switcher: styling and colors"))
87 .child(View::gap(1))
88 .child(View::styled_text("Press Escape to close").dim().build())
89 .build(),
90 )
91 .build(),
92 )
93 .build()
94 }examples/19_status_bar.rs (line 29)
24 fn render(&self, cx: Scope) -> View {
25 let show_help = state!(cx, || false);
26
27 // F1 toggles help
28 cx.use_command(
29 KeyBinding::key(KeyCode::F(1)),
30 with!(show_help => move || show_help.update(|v| *v = !*v)),
31 );
32 View::vstack()
33 .child(View::styled_text("Status Bar Examples").bold().build())
34 .child(View::text(""))
35 .child(View::text("Basic status bar (left only):"))
36 .child(View::status_bar().left("NORMAL").build())
37 .child(View::text(""))
38 .child(View::text("Left and right sections:"))
39 .child(
40 View::status_bar()
41 .left("INSERT")
42 .right("Ln 42, Col 8")
43 .build(),
44 )
45 .child(View::text(""))
46 .child(View::text("All three sections:"))
47 .child(
48 View::status_bar()
49 .left("VISUAL")
50 .center("main.rs")
51 .right("UTF-8 | LF | Rust")
52 .build(),
53 )
54 .child(View::text(""))
55 .child(View::text("Custom colors (green on dark):"))
56 .child(
57 View::status_bar()
58 .left("SUCCESS")
59 .center("All tests passed")
60 .right("100%")
61 .fg(Color::Green)
62 .bg(Color::DarkGreen)
63 .build(),
64 )
65 .child(View::text(""))
66 .child(View::text("Editor-style status bar:"))
67 .child(
68 View::status_bar()
69 .left("-- INSERT --")
70 .center("~/projects/myapp/src/main.rs [+]")
71 .right("1/100 | 50%")
72 .build(),
73 )
74 .child(View::spacer())
75 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
76 .child(
77 View::modal()
78 .visible(show_help.get())
79 .title("Example 19: Status Bar")
80 .on_dismiss(with!(show_help => move || show_help.set(false)))
81 .child(
82 View::vstack()
83 .child(View::styled_text("What you're seeing").bold().build())
84 .child(View::text("• Status bars with left/center/right sections"))
85 .child(View::text("• Custom foreground and background colors"))
86 .child(View::text("• Editor-style status line example"))
87 .child(View::gap(1))
88 .child(View::styled_text("Key concepts").bold().build())
89 .child(View::text("• View::status_bar() creates status lines"))
90 .child(View::text("• .left(), .center(), .right() for sections"))
91 .child(View::text("• .fg() and .bg() for custom colors"))
92 .child(View::text("• Great for showing mode, file info, etc."))
93 .child(View::gap(1))
94 .child(View::styled_text("Try this").bold().build())
95 .child(View::text("• Compare different status bar styles"))
96 .child(View::text("• Notice how sections align"))
97 .child(View::gap(1))
98 .child(View::styled_text("Next up").bold().build())
99 .child(View::text("→ 20_menu_bar: dropdown menus"))
100 .child(View::gap(1))
101 .child(View::styled_text("Press Escape to close").dim().build())
102 .build(),
103 )
104 .build(),
105 )
106 .build()
107 }examples/09_syntax_comparison.rs (line 30)
24 fn render(&self, cx: Scope) -> View {
25 let use_jsx = state!(cx, || false);
26 let show_help = state!(cx, || false);
27
28 // F1 toggles help
29 cx.use_command(
30 KeyBinding::key(KeyCode::F(1)),
31 with!(show_help => move || show_help.update(|v| *v = !*v)),
32 );
33
34 let toggle = with!(use_jsx => move || use_jsx.set(!use_jsx.get()));
35
36 // Show which syntax is currently displayed
37 let syntax_name = if use_jsx.get() {
38 "view! macro (JSX-like)"
39 } else {
40 "Builder pattern"
41 };
42
43 View::vstack()
44 .child(
45 View::styled_text("Syntax Comparison")
46 .color(Color::Cyan)
47 .bold()
48 .build(),
49 )
50 .child(
51 View::styled_text("Same UI, two ways to write it")
52 .dim()
53 .build(),
54 )
55 .child(View::gap(1))
56 .child(
57 View::hstack()
58 .child(View::text("Current syntax: "))
59 .child(
60 View::styled_text(syntax_name)
61 .color(Color::Yellow)
62 .bold()
63 .build(),
64 )
65 .build(),
66 )
67 .child(View::gap(1))
68 .child(
69 View::boxed()
70 .border(true)
71 .padding(1)
72 .child(if use_jsx.get() {
73 counter_jsx(cx.clone())
74 } else {
75 counter_builder(cx.clone())
76 })
77 .build(),
78 )
79 .child(View::gap(1))
80 .child(
81 View::button()
82 .label("Toggle Syntax")
83 .on_press(toggle)
84 .build(),
85 )
86 .child(View::gap(1))
87 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
88 .child(
89 View::modal()
90 .visible(show_help.get())
91 .title("Example 09: Syntax Comparison")
92 .on_dismiss(with!(show_help => move || show_help.set(false)))
93 .child(
94 View::vstack()
95 .child(View::styled_text("What you're seeing").bold().build())
96 .child(View::text("• Two syntaxes that produce identical output"))
97 .child(View::text("• Builder: View::vstack().child(...).build()"))
98 .child(View::text("• Macro: view! { <VStack>...</VStack> }"))
99 .child(View::gap(1))
100 .child(View::styled_text("Key concepts").bold().build())
101 .child(View::text("• Builder is Rust-native, IDE-friendly"))
102 .child(View::text("• view! macro is JSX-like, less boilerplate"))
103 .child(View::text("• Choose based on your preference"))
104 .child(View::gap(1))
105 .child(View::styled_text("Try this").bold().build())
106 .child(View::text("• Toggle between syntaxes"))
107 .child(View::text("• Notice the output is identical"))
108 .child(View::text("• Check the source code to see both styles"))
109 .child(View::gap(1))
110 .child(View::styled_text("Next up").bold().build())
111 .child(View::text("→ 10_state_explained: deep dive into state"))
112 .child(View::gap(1))
113 .child(View::styled_text("Press Escape to close").dim().build())
114 .build(),
115 )
116 .build(),
117 )
118 .build()
119 }Additional examples can be found in:
- examples/35_slider.rs
- examples/15_markdown.rs
- examples/18_progress_bar.rs
- examples/16_tree.rs
- examples/05_todo_list.rs
- examples/37_error_boundary.rs
- examples/38_custom_widget.rs
- examples/10_state_explained.rs
- examples/32_effects.rs
- examples/13_split_panes.rs
- examples/07_file_browser.rs
- examples/12_text_area.rs
- examples/06_log_viewer.rs
- examples/24_async_data.rs
- examples/34_channels_and_intervals.rs
- examples/08_system_monitor.rs
- examples/39_port.rs
- examples/25_context.rs
- examples/14_tabs.rs
- examples/11_checkbox.rs
- examples/17_table.rs
- examples/29_canvas.rs
- examples/20_menu_bar.rs
- examples/26_radio_buttons.rs
- examples/21_toasts.rs
- examples/36_reducer.rs
- examples/03_theme_switcher.rs
- examples/28_shared_state.rs
- examples/27_keyed_state.rs
- examples/31_animated_canvas.rs
- examples/22_forms.rs
- examples/23_modal.rs
Sourcepub fn matches(&self, code: KeyCode, modifiers: KeyModifiers) -> bool
pub fn matches(&self, code: KeyCode, modifiers: KeyModifiers) -> bool
Check if this binding matches a key event.
Trait Implementations§
Source§impl Clone for KeyBinding
impl Clone for KeyBinding
Source§fn clone(&self) -> KeyBinding
fn clone(&self) -> KeyBinding
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for KeyBinding
impl Debug for KeyBinding
Source§impl Hash for KeyBinding
impl Hash for KeyBinding
Source§impl PartialEq for KeyBinding
impl PartialEq for KeyBinding
impl Eq for KeyBinding
impl StructuralPartialEq for KeyBinding
Auto Trait Implementations§
impl Freeze for KeyBinding
impl RefUnwindSafe for KeyBinding
impl Send for KeyBinding
impl Sync for KeyBinding
impl Unpin for KeyBinding
impl UnwindSafe for KeyBinding
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Convert
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Convert
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Convert
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Convert
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.