pub struct TextAreaBuilder { /* private fields */ }Expand description
Builder for TextArea views.
Implementations§
Source§impl TextAreaBuilder
impl TextAreaBuilder
pub fn new() -> Self
Sourcepub fn value(self, value: impl Into<String>) -> Self
pub fn value(self, value: impl Into<String>) -> Self
Set the current text value.
Examples found in repository?
examples/12_text_area.rs (line 99)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn placeholder(self, placeholder: impl Into<String>) -> Self
pub fn placeholder(self, placeholder: impl Into<String>) -> Self
Set the placeholder text shown when empty.
Examples found in repository?
examples/12_text_area.rs (line 100)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn on_change(self, callback: impl Fn(String) + 'static) -> Self
pub fn on_change(self, callback: impl Fn(String) + 'static) -> Self
Set the callback for when text changes.
Examples found in repository?
examples/12_text_area.rs (line 104)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn on_cursor_change(self, callback: impl Fn(usize, usize) + 'static) -> Self
pub fn on_cursor_change(self, callback: impl Fn(usize, usize) + 'static) -> Self
Set the callback for when cursor position changes.
Examples found in repository?
examples/12_text_area.rs (line 105)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn cursor_line(self, line: usize) -> Self
pub fn cursor_line(self, line: usize) -> Self
Set the cursor line position.
Examples found in repository?
examples/12_text_area.rs (line 102)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn cursor_col(self, col: usize) -> Self
pub fn cursor_col(self, col: usize) -> Self
Set the cursor column position.
Examples found in repository?
examples/12_text_area.rs (line 103)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn rows(self, rows: u16) -> Self
pub fn rows(self, rows: u16) -> Self
Set the number of visible rows.
Examples found in repository?
examples/12_text_area.rs (line 101)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Sourcepub fn wrap_width(self, width: u16) -> Self
pub fn wrap_width(self, width: u16) -> Self
Set the width at which text automatically wraps to the next line. If not set, text is truncated at the display edge without wrapping.
Sourcepub fn build(self) -> View
pub fn build(self) -> View
Examples found in repository?
examples/12_text_area.rs (line 106)
21 fn render(&self, cx: Scope) -> View {
22 let show_help = state!(cx, || false);
23 let theme_idx = state!(cx, || 0usize);
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 // F2 cycles through themes
32 cx.use_command(
33 KeyBinding::key(KeyCode::F(2)),
34 with!(theme_idx => move || {
35 let next = (theme_idx.get() + 1) % 6;
36 theme_idx.set(next);
37 let theme = match next {
38 0 => Theme::nord(),
39 1 => Theme::dark(),
40 2 => Theme::light(),
41 3 => Theme::dracula(),
42 4 => Theme::gruvbox_dark(),
43 _ => Theme::catppuccin_mocha(),
44 };
45 set_theme(theme);
46 }),
47 );
48
49 let content = state!(cx, String::new);
50 let cursor_line = state!(cx, || 0usize);
51 let cursor_col = state!(cx, || 0usize);
52
53 // Track changes and cursor position
54 let on_change = with!(content => move |text: String| {
55 content.set(text);
56 });
57
58 let on_cursor_change = with!(cursor_line, cursor_col => move |line: usize, col: usize| {
59 cursor_line.set(line);
60 cursor_col.set(col);
61 });
62
63 // Calculate stats
64 let text = content.get();
65 let line_count = if text.is_empty() {
66 0
67 } else {
68 text.lines().count()
69 };
70 let char_count = text.chars().count();
71 let word_count = text.split_whitespace().count();
72
73 let theme_name = match theme_idx.get() {
74 0 => "Nord",
75 1 => "Dark",
76 2 => "Light",
77 3 => "Dracula",
78 4 => "Gruvbox Dark",
79 _ => "Catppuccin Mocha",
80 };
81
82 View::vstack()
83 .spacing(1)
84 .child(
85 View::hstack()
86 .child(View::styled_text("Notes").color(Color::Cyan).bold().build())
87 .child(View::spacer())
88 .child(View::styled_text(format!("Theme: {}", theme_name)).dim().build())
89 .build(),
90 )
91 .child(
92 View::styled_text("A simple multi-line text editor")
93 .dim()
94 .build(),
95 )
96 .child(View::gap(1))
97 .child(
98 View::text_area()
99 .value(content.get())
100 .placeholder("Start typing your notes here...")
101 .rows(12)
102 .cursor_line(cursor_line.get())
103 .cursor_col(cursor_col.get())
104 .on_change(on_change)
105 .on_cursor_change(on_cursor_change)
106 .build(),
107 )
108 .child(View::gap(1))
109 .child(
110 View::hstack()
111 .spacing(3)
112 .child(
113 View::styled_text(format!("Lines: {}", line_count))
114 .color(Color::DarkGrey)
115 .build(),
116 )
117 .child(
118 View::styled_text(format!("Words: {}", word_count))
119 .color(Color::DarkGrey)
120 .build(),
121 )
122 .child(
123 View::styled_text(format!("Chars: {}", char_count))
124 .color(Color::DarkGrey)
125 .build(),
126 )
127 .build(),
128 )
129 .child(View::gap(1))
130 .child(View::styled_text("F1 help • F2 theme • Ctrl+Q quit").dim().build())
131 .child(
132 View::modal()
133 .visible(show_help.get())
134 .title("Example 12: TextArea")
135 .on_dismiss(with!(show_help => move || show_help.set(false)))
136 .child(
137 View::vstack()
138 .child(View::styled_text("What you're seeing").bold().build())
139 .child(View::text("• Multi-line text editing with TextArea"))
140 .child(View::text("• Real-time line/word/char counts"))
141 .child(View::text("• Cursor position tracking"))
142 .child(View::gap(1))
143 .child(View::styled_text("Key concepts").bold().build())
144 .child(View::text("• View::text_area() for multi-line input"))
145 .child(View::text("• on_change callback for text updates"))
146 .child(View::text("• on_cursor_change for cursor tracking"))
147 .child(View::text("• placeholder text when empty"))
148 .child(View::gap(1))
149 .child(View::styled_text("Try this").bold().build())
150 .child(View::text("• Type multiple lines of text"))
151 .child(View::text("• Watch the stats update in real-time"))
152 .child(View::text("• Use arrow keys to navigate"))
153 .child(View::gap(1))
154 .child(View::styled_text("Next up").bold().build())
155 .child(View::text("→ 13_split_panes: resizable panel layouts"))
156 .child(View::gap(1))
157 .child(View::styled_text("Press Escape to close").dim().build())
158 .build(),
159 )
160 .build(),
161 )
162 .build()
163 }Trait Implementations§
Source§impl Default for TextAreaBuilder
impl Default for TextAreaBuilder
Source§fn default() -> TextAreaBuilder
fn default() -> TextAreaBuilder
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for TextAreaBuilder
impl !RefUnwindSafe for TextAreaBuilder
impl !Send for TextAreaBuilder
impl !Sync for TextAreaBuilder
impl Unpin for TextAreaBuilder
impl !UnwindSafe for TextAreaBuilder
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> 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.