pub struct TextInputBuilder<'a> { /* private fields */ }
Implementations§
Source§impl<'a> TextInputBuilder<'a>
impl<'a> TextInputBuilder<'a>
Sourcepub fn flags(self, flags: TextInputFlags) -> TextInputBuilder<'a>
pub fn flags(self, flags: TextInputFlags) -> TextInputBuilder<'a>
Examples found in repository?
examples/partials.rs (line 278)
250 fn build_partial<W: Into<ControlHandle>>(data: &mut PeopleUi, parent: Option<W>) -> Result<(), NwgError> {
251 let parent = parent.unwrap().into();
252
253 nwg::Label::builder()
254 .text("Name:")
255 .h_align(nwg::HTextAlign::Right)
256 .parent(&parent)
257 .build(&mut data.label1)?;
258
259 nwg::Label::builder()
260 .text("Age:")
261 .h_align(nwg::HTextAlign::Right)
262 .parent(&parent)
263 .build(&mut data.label2)?;
264
265 nwg::Label::builder()
266 .text("Job:")
267 .h_align(nwg::HTextAlign::Right)
268 .parent(&parent)
269 .build(&mut data.label3)?;
270
271 nwg::TextInput::builder()
272 .text("John Doe")
273 .parent(&parent)
274 .build(&mut data.name_input)?;
275
276 nwg::TextInput::builder()
277 .text("75")
278 .flags(nwg::TextInputFlags::VISIBLE | nwg::TextInputFlags::NUMBER)
279 .parent(&parent)
280 .build(&mut data.age_input)?;
281
282 nwg::TextInput::builder()
283 .text("Programmer")
284 .parent(&parent)
285 .build(&mut data.job_input)?;
286
287 nwg::Button::builder()
288 .text("Save")
289 .parent(&parent)
290 .build(&mut data.save_btn)?;
291
292 nwg::GridLayout::builder()
293 .parent(&parent)
294 .max_size([1000, 150])
295 .min_size([100, 120])
296 .child(0, 0, &data.label1)
297 .child(0, 1, &data.label2)
298 .child(0, 2, &data.label3)
299 .child(1, 0, &data.name_input)
300 .child(1, 1, &data.age_input)
301 .child(1, 2, &data.job_input)
302 .build(&data.layout)?;
303
304 nwg::GridLayout::builder()
305 .min_size([100, 200])
306 .max_column(Some(2))
307 .max_row(Some(6))
308 .child(1, 5, &data.save_btn)
309 .parent(&parent)
310 .build(&data.layout2)?;
311
312 Ok(())
313 }
pub fn ex_flags(self, flags: u32) -> TextInputBuilder<'a>
Sourcepub fn text(self, text: &'a str) -> TextInputBuilder<'a>
pub fn text(self, text: &'a str) -> TextInputBuilder<'a>
Examples found in repository?
examples/partial_simple.rs (line 93)
89 fn build_partial<W: Into<nwg::ControlHandle>>(data: &mut SubmitForm, parent: Option<W>) -> Result<(), nwg::NwgError> {
90 let parent = parent.unwrap().into();
91
92 nwg::TextInput::builder()
93 .text(&data.form_data)
94 .parent(&parent)
95 .build(&mut data.value)?;
96
97 nwg::Button::builder()
98 .text("Save")
99 .parent(&parent)
100 .build(&mut data.sumbit_button)?;
101
102 nwg::GridLayout::builder()
103 .child(0, 0, &data.value)
104 .child(0, 1, &data.sumbit_button)
105 .parent(&parent)
106 .build(&data.layout)?;
107
108 Ok(())
109 }
More examples
examples/basic_barebone.rs (line 29)
12fn main() {
13 nwg::init().expect("Failed to init Native Windows GUI");
14 nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
15
16 let mut window = Default::default();
17 let mut name_edit = Default::default();
18 let mut hello_button = Default::default();
19 let layout = Default::default();
20
21 nwg::Window::builder()
22 .size((300, 115))
23 .position((300, 300))
24 .title("Basic example")
25 .build(&mut window)
26 .unwrap();
27
28 nwg::TextInput::builder()
29 .text("Heisenberg")
30 .focus(true)
31 .parent(&window)
32 .build(&mut name_edit)
33 .unwrap();
34
35 nwg::Button::builder()
36 .text("Say my name")
37 .parent(&window)
38 .build(&mut hello_button)
39 .unwrap();
40
41 nwg::GridLayout::builder()
42 .parent(&window)
43 .spacing(1)
44 .child(0, 0, &name_edit)
45 .child_item(nwg::GridLayoutItem::new(&hello_button, 0, 1, 1, 2))
46 .build(&layout)
47 .unwrap();
48
49 let window = Rc::new(window);
50 let events_window = window.clone();
51
52 let handler = nwg::full_bind_event_handler(&window.handle, move |evt, _evt_data, handle| {
53 use nwg::Event as E;
54
55 match evt {
56 E::OnWindowClose =>
57 if &handle == &events_window as &nwg::Window {
58 nwg::modal_info_message(&events_window.handle, "Goodbye", &format!("Goodbye {}", name_edit.text()));
59 nwg::stop_thread_dispatch();
60 },
61 E::OnButtonClick =>
62 if &handle == &hello_button {
63 nwg::modal_info_message(&events_window.handle, "Hello", &format!("Hello {}", name_edit.text()));
64 },
65 _ => {}
66 }
67 });
68
69 nwg::dispatch_thread_events();
70 nwg::unbind_event_handler(&handler);
71}
examples/basic.rs (line 60)
46 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47 use nwg::Event as E;
48
49 // Controls
50 nwg::Window::builder()
51 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52 .size((300, 135))
53 .position((300, 300))
54 .title("Basic example")
55 .build(&mut data.window)?;
56
57 nwg::TextInput::builder()
58 .size((280, 35))
59 .position((10, 10))
60 .text("Heisenberg")
61 .parent(&data.window)
62 .focus(true)
63 .build(&mut data.name_edit)?;
64
65 nwg::Button::builder()
66 .size((280, 70))
67 .position((10, 50))
68 .text("Say my name")
69 .parent(&data.window)
70 .build(&mut data.hello_button)?;
71
72 // Wrap-up
73 let ui = BasicAppUi {
74 inner: Rc::new(data),
75 default_handler: Default::default(),
76 };
77
78 // Events
79 let evt_ui = Rc::downgrade(&ui.inner);
80 let handle_events = move |evt, _evt_data, handle| {
81 if let Some(ui) = evt_ui.upgrade() {
82 match evt {
83 E::OnButtonClick =>
84 if &handle == &ui.hello_button {
85 BasicApp::say_hello(&ui);
86 },
87 E::OnWindowClose =>
88 if &handle == &ui.window {
89 BasicApp::say_goodbye(&ui);
90 },
91 _ => {}
92 }
93 }
94 };
95
96 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98 return Ok(ui);
99 }
examples/basic_layout.rs (line 59)
47 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
48 use nwg::Event as E;
49
50 // Controls
51 nwg::Window::builder()
52 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
53 .size((300, 115))
54 .position((300, 300))
55 .title("Basic example")
56 .build(&mut data.window)?;
57
58 nwg::TextInput::builder()
59 .text("Heisenberg")
60 .parent(&data.window)
61 .focus(true)
62 .build(&mut data.name_edit)?;
63
64 nwg::Button::builder()
65 .text("Say my name")
66 .parent(&data.window)
67 .build(&mut data.hello_button)?;
68
69 // Wrap-up
70 let ui = BasicAppUi {
71 inner: Rc::new(data),
72 default_handler: Default::default(),
73 };
74
75 // Events
76 let evt_ui = Rc::downgrade(&ui.inner);
77 let handle_events = move |evt, _evt_data, handle| {
78 if let Some(evt_ui) = evt_ui.upgrade() {
79 match evt {
80 E::OnButtonClick =>
81 if &handle == &evt_ui.hello_button {
82 BasicApp::say_hello(&evt_ui);
83 },
84 E::OnWindowClose =>
85 if &handle == &evt_ui.window {
86 BasicApp::say_goodbye(&evt_ui);
87 },
88 _ => {}
89 }
90 }
91 };
92
93 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
94
95 // Layouts
96 nwg::GridLayout::builder()
97 .parent(&ui.window)
98 .spacing(1)
99 .child(0, 0, &ui.name_edit)
100 .child_item(nwg::GridLayoutItem::new(&ui.hello_button, 0, 1, 1, 2))
101 .build(&ui.layout)?;
102
103 return Ok(ui);
104 }
examples/partials.rs (line 272)
250 fn build_partial<W: Into<ControlHandle>>(data: &mut PeopleUi, parent: Option<W>) -> Result<(), NwgError> {
251 let parent = parent.unwrap().into();
252
253 nwg::Label::builder()
254 .text("Name:")
255 .h_align(nwg::HTextAlign::Right)
256 .parent(&parent)
257 .build(&mut data.label1)?;
258
259 nwg::Label::builder()
260 .text("Age:")
261 .h_align(nwg::HTextAlign::Right)
262 .parent(&parent)
263 .build(&mut data.label2)?;
264
265 nwg::Label::builder()
266 .text("Job:")
267 .h_align(nwg::HTextAlign::Right)
268 .parent(&parent)
269 .build(&mut data.label3)?;
270
271 nwg::TextInput::builder()
272 .text("John Doe")
273 .parent(&parent)
274 .build(&mut data.name_input)?;
275
276 nwg::TextInput::builder()
277 .text("75")
278 .flags(nwg::TextInputFlags::VISIBLE | nwg::TextInputFlags::NUMBER)
279 .parent(&parent)
280 .build(&mut data.age_input)?;
281
282 nwg::TextInput::builder()
283 .text("Programmer")
284 .parent(&parent)
285 .build(&mut data.job_input)?;
286
287 nwg::Button::builder()
288 .text("Save")
289 .parent(&parent)
290 .build(&mut data.save_btn)?;
291
292 nwg::GridLayout::builder()
293 .parent(&parent)
294 .max_size([1000, 150])
295 .min_size([100, 120])
296 .child(0, 0, &data.label1)
297 .child(0, 1, &data.label2)
298 .child(0, 2, &data.label3)
299 .child(1, 0, &data.name_input)
300 .child(1, 1, &data.age_input)
301 .child(1, 2, &data.job_input)
302 .build(&data.layout)?;
303
304 nwg::GridLayout::builder()
305 .min_size([100, 200])
306 .max_column(Some(2))
307 .max_row(Some(6))
308 .child(1, 5, &data.save_btn)
309 .parent(&parent)
310 .build(&data.layout2)?;
311
312 Ok(())
313 }
314
315 fn process_event<'a>(&self, _evt: nwg::Event, _evt_data: &nwg::EventData, _handle: ControlHandle) {
316 }
317
318 fn handles(&self) -> Vec<&ControlHandle> {
319 Vec::new()
320 }
321 }
322}
323
324mod partial_animal_ui {
325 use native_windows_gui as nwg;
326 use self::nwg::{PartialUi, NwgError, ControlHandle};
327 use super::*;
328
329 impl PartialUi for AnimalUi {
330
331 fn build_partial<W: Into<ControlHandle>>(data: &mut AnimalUi, parent: Option<W>) -> Result<(), NwgError> {
332 let parent = parent.unwrap().into();
333
334 nwg::Label::builder()
335 .text("Name:")
336 .h_align(nwg::HTextAlign::Right)
337 .parent(&parent)
338 .build(&mut data.label1)?;
339
340 nwg::Label::builder()
341 .text("Race:")
342 .h_align(nwg::HTextAlign::Right)
343 .parent(&parent)
344 .build(&mut data.label2)?;
345
346 nwg::Label::builder()
347 .text("Is fluffy:")
348 .h_align(nwg::HTextAlign::Right)
349 .parent(&parent)
350 .build(&mut data.label3)?;
351
352 nwg::TextInput::builder()
353 .text("Mittens")
354 .parent(&parent)
355 .build(&mut data.name_input)?;
356
357 nwg::ComboBox::builder()
358 .collection(vec!["Cat", "Dog", "Pidgeon", "Monkey"])
359 .selected_index(Some(0))
360 .parent(&parent)
361 .build(&mut data.race_input)?;
362
363 nwg::CheckBox::builder()
364 .text("")
365 .check_state(nwg::CheckBoxState::Checked)
366 .parent(&parent)
367 .build(&mut data.is_soft_input)?;
368
369 nwg::Button::builder()
370 .text("Save")
371 .parent(&parent)
372 .build(&mut data.save_btn)?;
373
374 nwg::GridLayout::builder()
375 .parent(&parent)
376 .max_size([1000, 150])
377 .min_size([100, 120])
378 .child(0, 0, &data.label1)
379 .child(0, 1, &data.label2)
380 .child(0, 2, &data.label3)
381 .child(1, 0, &data.name_input)
382 .child(1, 1, &data.race_input)
383 .child(1, 2, &data.is_soft_input)
384 .build(&data.layout)?;
385
386 nwg::GridLayout::builder()
387 .min_size([100, 200])
388 .max_column(Some(2))
389 .max_row(Some(6))
390 .child(1, 5, &data.save_btn)
391 .parent(&parent)
392 .build(&data.layout2)?;
393
394 Ok(())
395 }
396
397 fn process_event<'a>(&self, _evt: nwg::Event, _evt_data: &nwg::EventData, _handle: ControlHandle) {
398 }
399
400 fn handles(&self) -> Vec<&ControlHandle> {
401 Vec::new()
402 }
403 }
404}
405
406mod partial_food_ui {
407 use native_windows_gui as nwg;
408 use self::nwg::{PartialUi, NwgError, ControlHandle};
409 use super::*;
410
411 impl PartialUi for FoodUi {
412 fn build_partial<W: Into<ControlHandle>>(data: &mut FoodUi, parent: Option<W>) -> Result<(), NwgError> {
413 let parent = parent.unwrap().into();
414
415 nwg::Label::builder()
416 .text("Name:")
417 .h_align(nwg::HTextAlign::Right)
418 .parent(&parent)
419 .build(&mut data.label1)?;
420
421 nwg::Label::builder()
422 .text("Tasty:")
423 .h_align(nwg::HTextAlign::Right)
424 .parent(&parent)
425 .build(&mut data.label2)?;
426
427 nwg::TextInput::builder()
428 .text("Banana")
429 .parent(&parent)
430 .build(&mut data.name_input)?;
431
432 nwg::CheckBox::builder()
433 .text("")
434 .check_state(nwg::CheckBoxState::Checked)
435 .parent(&parent)
436 .build(&mut data.tasty_input)?;
437
438 nwg::Button::builder()
439 .text("Save")
440 .parent(&parent)
441 .build(&mut data.save_btn)?;
442
443 nwg::GridLayout::builder()
444 .parent(&parent)
445 .max_size([1000, 90])
446 .min_size([100, 80])
447 .child(0, 0, &data.label1)
448 .child(0, 1, &data.label2)
449 .child(1, 0, &data.name_input)
450 .child(1, 1, &data.tasty_input)
451 .build(&data.layout)?;
452
453 nwg::GridLayout::builder()
454 .min_size([100, 200])
455 .max_column(Some(2))
456 .max_row(Some(6))
457 .child(1, 5, &data.save_btn)
458 .parent(&parent)
459 .build(&data.layout2)?;
460
461 Ok(())
462 }
examples/message_bank.rs (line 100)
88 fn build_ui(mut data: MessageBank) -> Result<MessageBankUi, nwg::NwgError> {
89 use nwg::Event as E;
90
91 // Controls
92 nwg::Window::builder()
93 .flags(nwg::WindowFlags::MAIN_WINDOW | nwg::WindowFlags::VISIBLE)
94 .size((400, 300))
95 .position((800, 300))
96 .title("My message bank")
97 .build(&mut data.window)?;
98
99 nwg::TextInput::builder()
100 .text("Hello World!")
101 .focus(true)
102 .parent(&data.window)
103 .build(&mut data.message_content)?;
104
105 nwg::Button::builder()
106 .text("Save")
107 .parent(&data.window)
108 .build(&mut data.add_message_btn)?;
109
110 nwg::TextInput::builder()
111 .text("Title")
112 .parent(&data.window)
113 .build(&mut data.message_title)?;
114
115 // Wrap-up
116 let ui = MessageBankUi {
117 inner: Rc::new(data),
118 default_handler: Default::default(),
119 };
120
121 // Events
122 let window_handles = [&ui.window.handle];
123
124 for handle in window_handles.iter() {
125 let evt_ui = Rc::downgrade(&ui.inner);
126 let handle_events = move |evt, _evt_data, handle| {
127 if let Some(evt_ui) = evt_ui.upgrade() {
128 match evt {
129 E::OnButtonClick => {
130 if &handle == &evt_ui.add_message_btn { MessageBank::add_message(&evt_ui); }
131 },
132 E::OnWindowClose => {
133 if &handle == &evt_ui.window { MessageBank::exit(&evt_ui); }
134 },
135 _ => {}
136 }
137 }
138 };
139
140 ui.default_handler.borrow_mut().push(
141 nwg::full_bind_event_handler(handle, handle_events)
142 );
143 }
144
145 // Layout
146 nwg::GridLayout::builder()
147 .parent(&ui.window)
148 .max_row(Some(6))
149 .child(0, 0, &ui.add_message_btn)
150 .child_item(nwg::GridLayoutItem::new(&ui.message_title, 1, 0, 2, 1))
151 .child_item(nwg::GridLayoutItem::new(&ui.message_content, 3, 0, 3, 1))
152 .build(&ui.layout)?;
153
154 return Ok(ui);
155 }
Additional examples can be found in:
pub fn placeholder_text( self, placeholder_text: Option<&'a str>, ) -> TextInputBuilder<'a>
Sourcepub fn size(self, size: (i32, i32)) -> TextInputBuilder<'a>
pub fn size(self, size: (i32, i32)) -> TextInputBuilder<'a>
Examples found in repository?
examples/basic.rs (line 58)
46 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47 use nwg::Event as E;
48
49 // Controls
50 nwg::Window::builder()
51 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52 .size((300, 135))
53 .position((300, 300))
54 .title("Basic example")
55 .build(&mut data.window)?;
56
57 nwg::TextInput::builder()
58 .size((280, 35))
59 .position((10, 10))
60 .text("Heisenberg")
61 .parent(&data.window)
62 .focus(true)
63 .build(&mut data.name_edit)?;
64
65 nwg::Button::builder()
66 .size((280, 70))
67 .position((10, 50))
68 .text("Say my name")
69 .parent(&data.window)
70 .build(&mut data.hello_button)?;
71
72 // Wrap-up
73 let ui = BasicAppUi {
74 inner: Rc::new(data),
75 default_handler: Default::default(),
76 };
77
78 // Events
79 let evt_ui = Rc::downgrade(&ui.inner);
80 let handle_events = move |evt, _evt_data, handle| {
81 if let Some(ui) = evt_ui.upgrade() {
82 match evt {
83 E::OnButtonClick =>
84 if &handle == &ui.hello_button {
85 BasicApp::say_hello(&ui);
86 },
87 E::OnWindowClose =>
88 if &handle == &ui.window {
89 BasicApp::say_goodbye(&ui);
90 },
91 _ => {}
92 }
93 }
94 };
95
96 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98 return Ok(ui);
99 }
Sourcepub fn position(self, pos: (i32, i32)) -> TextInputBuilder<'a>
pub fn position(self, pos: (i32, i32)) -> TextInputBuilder<'a>
Examples found in repository?
examples/basic.rs (line 59)
46 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47 use nwg::Event as E;
48
49 // Controls
50 nwg::Window::builder()
51 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52 .size((300, 135))
53 .position((300, 300))
54 .title("Basic example")
55 .build(&mut data.window)?;
56
57 nwg::TextInput::builder()
58 .size((280, 35))
59 .position((10, 10))
60 .text("Heisenberg")
61 .parent(&data.window)
62 .focus(true)
63 .build(&mut data.name_edit)?;
64
65 nwg::Button::builder()
66 .size((280, 70))
67 .position((10, 50))
68 .text("Say my name")
69 .parent(&data.window)
70 .build(&mut data.hello_button)?;
71
72 // Wrap-up
73 let ui = BasicAppUi {
74 inner: Rc::new(data),
75 default_handler: Default::default(),
76 };
77
78 // Events
79 let evt_ui = Rc::downgrade(&ui.inner);
80 let handle_events = move |evt, _evt_data, handle| {
81 if let Some(ui) = evt_ui.upgrade() {
82 match evt {
83 E::OnButtonClick =>
84 if &handle == &ui.hello_button {
85 BasicApp::say_hello(&ui);
86 },
87 E::OnWindowClose =>
88 if &handle == &ui.window {
89 BasicApp::say_goodbye(&ui);
90 },
91 _ => {}
92 }
93 }
94 };
95
96 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98 return Ok(ui);
99 }
pub fn limit(self, limit: usize) -> TextInputBuilder<'a>
pub fn password(self, psw: Option<char>) -> TextInputBuilder<'a>
Sourcepub fn align(self, align: HTextAlign) -> TextInputBuilder<'a>
pub fn align(self, align: HTextAlign) -> TextInputBuilder<'a>
Examples found in repository?
examples/calculator.rs (line 155)
143 fn build_ui(mut data: Calculator) -> Result<CalculatorUi, nwg::NwgError> {
144 use nwg::Event as E;
145
146 // Controls
147 nwg::Window::builder()
148 .size((300, 150))
149 .position((300, 300))
150 .title("Calculator")
151 .build(&mut data.window)?;
152
153 nwg::TextInput::builder()
154 .text("")
155 .align(nwg::HTextAlign::Right)
156 .readonly(true)
157 .parent(&data.window)
158 .build(&mut data.input)?;
159
160 nwg::Button::builder()
161 .text("1")
162 .parent(&data.window)
163 .focus(true)
164 .build(&mut data.btn1)?;
165
166 nwg::Button::builder().text("2").parent(&data.window).build(&mut data.btn2)?;
167 nwg::Button::builder().text("3").parent(&data.window).build(&mut data.btn3)?;
168 nwg::Button::builder().text("4").parent(&data.window).build(&mut data.btn4)?;
169 nwg::Button::builder().text("5").parent(&data.window).build(&mut data.btn5)?;
170 nwg::Button::builder().text("6").parent(&data.window).build(&mut data.btn6)?;
171 nwg::Button::builder().text("7").parent(&data.window).build(&mut data.btn7)?;
172 nwg::Button::builder().text("8").parent(&data.window).build(&mut data.btn8)?;
173 nwg::Button::builder().text("9").parent(&data.window).build(&mut data.btn9)?;
174 nwg::Button::builder().text("0").parent(&data.window).build(&mut data.btn0)?;
175
176 nwg::Button::builder().text("+").parent(&data.window).build(&mut data.btn_plus)?;
177 nwg::Button::builder().text("-").parent(&data.window).build(&mut data.btn_minus)?;
178 nwg::Button::builder().text("*").parent(&data.window).build(&mut data.btn_mult)?;
179 nwg::Button::builder().text("/").parent(&data.window).build(&mut data.btn_divide)?;
180 nwg::Button::builder().text("Clear").parent(&data.window).build(&mut data.btn_clear)?;
181 nwg::Button::builder().text("=").parent(&data.window).build(&mut data.btn_process)?;
182
183
184 // Wrap-up
185 let ui = CalculatorUi {
186 inner: Rc::new(data),
187 default_handler: Default::default()
188 };
189
190 // Events
191 let window_handles = [&ui.window.handle];
192 for handle in window_handles.iter() {
193 let evt_ui = Rc::downgrade(&ui.inner);
194 let handle_events = move |evt, _evt_data, handle| {
195 if let Some(evt_ui) = evt_ui.upgrade() {
196 match evt {
197 E::OnButtonClick =>
198 if &handle == &evt_ui.btn0 { Calculator::number(&evt_ui, &evt_ui.btn0); }
199 else if &handle == &evt_ui.btn1 { Calculator::number(&evt_ui, &evt_ui.btn1); }
200 else if &handle == &evt_ui.btn2 { Calculator::number(&evt_ui, &evt_ui.btn2); }
201 else if &handle == &evt_ui.btn3 { Calculator::number(&evt_ui, &evt_ui.btn3); }
202 else if &handle == &evt_ui.btn4 { Calculator::number(&evt_ui, &evt_ui.btn4); }
203 else if &handle == &evt_ui.btn5 { Calculator::number(&evt_ui, &evt_ui.btn5); }
204 else if &handle == &evt_ui.btn6 { Calculator::number(&evt_ui, &evt_ui.btn6); }
205 else if &handle == &evt_ui.btn7 { Calculator::number(&evt_ui, &evt_ui.btn7); }
206 else if &handle == &evt_ui.btn8 { Calculator::number(&evt_ui, &evt_ui.btn8); }
207 else if &handle == &evt_ui.btn9 { Calculator::number(&evt_ui, &evt_ui.btn9); }
208
209 else if &handle == &evt_ui.btn_plus { Calculator::number(&evt_ui, &evt_ui.btn_plus); }
210 else if &handle == &evt_ui.btn_minus { Calculator::number(&evt_ui, &evt_ui.btn_minus); }
211 else if &handle == &evt_ui.btn_mult { Calculator::number(&evt_ui, &evt_ui.btn_mult); }
212 else if &handle == &evt_ui.btn_divide { Calculator::number(&evt_ui, &evt_ui.btn_divide); }
213
214 else if &handle == &evt_ui.btn_clear { Calculator::clear(&evt_ui); }
215
216 else if &handle == &evt_ui.btn_process { Calculator::compute(&evt_ui); }
217 E::OnWindowClose =>
218 if &handle == &evt_ui.window {
219 Calculator::exit(&evt_ui);
220 },
221 _ => {}
222 }
223 }
224 };
225
226 ui.default_handler.borrow_mut().push(
227 nwg::full_bind_event_handler(handle, handle_events)
228 );
229 }
230
231 // Layouts
232 nwg::GridLayout::builder()
233 .parent(&ui.window)
234 .spacing(2)
235 .min_size([150, 140])
236 .child_item(nwg::GridLayoutItem::new(&ui.input, 0, 0, 5, 1))
237 .child(0, 1, &ui.btn1)
238 .child(1, 1, &ui.btn2)
239 .child(2, 1, &ui.btn3)
240 .child(0, 2, &ui.btn4)
241 .child(1, 2, &ui.btn5)
242 .child(2, 2, &ui.btn6)
243 .child(0, 3, &ui.btn7)
244 .child(1, 3, &ui.btn8)
245 .child(2, 3, &ui.btn9)
246 .child(3, 1, &ui.btn_plus)
247 .child(4, 1, &ui.btn_minus)
248 .child(3, 2, &ui.btn_mult)
249 .child(4, 2, &ui.btn_divide)
250 .child_item(nwg::GridLayoutItem::new(&ui.btn_clear, 3, 3, 2, 1))
251 .child_item(nwg::GridLayoutItem::new(&ui.btn_process, 3, 4, 2, 1))
252 .child_item(nwg::GridLayoutItem::new(&ui.btn0, 0, 4, 3, 1))
253 .build(&ui.layout)?;
254
255 return Ok(ui);
256 }
Sourcepub fn readonly(self, read: bool) -> TextInputBuilder<'a>
pub fn readonly(self, read: bool) -> TextInputBuilder<'a>
Examples found in repository?
examples/calculator.rs (line 156)
143 fn build_ui(mut data: Calculator) -> Result<CalculatorUi, nwg::NwgError> {
144 use nwg::Event as E;
145
146 // Controls
147 nwg::Window::builder()
148 .size((300, 150))
149 .position((300, 300))
150 .title("Calculator")
151 .build(&mut data.window)?;
152
153 nwg::TextInput::builder()
154 .text("")
155 .align(nwg::HTextAlign::Right)
156 .readonly(true)
157 .parent(&data.window)
158 .build(&mut data.input)?;
159
160 nwg::Button::builder()
161 .text("1")
162 .parent(&data.window)
163 .focus(true)
164 .build(&mut data.btn1)?;
165
166 nwg::Button::builder().text("2").parent(&data.window).build(&mut data.btn2)?;
167 nwg::Button::builder().text("3").parent(&data.window).build(&mut data.btn3)?;
168 nwg::Button::builder().text("4").parent(&data.window).build(&mut data.btn4)?;
169 nwg::Button::builder().text("5").parent(&data.window).build(&mut data.btn5)?;
170 nwg::Button::builder().text("6").parent(&data.window).build(&mut data.btn6)?;
171 nwg::Button::builder().text("7").parent(&data.window).build(&mut data.btn7)?;
172 nwg::Button::builder().text("8").parent(&data.window).build(&mut data.btn8)?;
173 nwg::Button::builder().text("9").parent(&data.window).build(&mut data.btn9)?;
174 nwg::Button::builder().text("0").parent(&data.window).build(&mut data.btn0)?;
175
176 nwg::Button::builder().text("+").parent(&data.window).build(&mut data.btn_plus)?;
177 nwg::Button::builder().text("-").parent(&data.window).build(&mut data.btn_minus)?;
178 nwg::Button::builder().text("*").parent(&data.window).build(&mut data.btn_mult)?;
179 nwg::Button::builder().text("/").parent(&data.window).build(&mut data.btn_divide)?;
180 nwg::Button::builder().text("Clear").parent(&data.window).build(&mut data.btn_clear)?;
181 nwg::Button::builder().text("=").parent(&data.window).build(&mut data.btn_process)?;
182
183
184 // Wrap-up
185 let ui = CalculatorUi {
186 inner: Rc::new(data),
187 default_handler: Default::default()
188 };
189
190 // Events
191 let window_handles = [&ui.window.handle];
192 for handle in window_handles.iter() {
193 let evt_ui = Rc::downgrade(&ui.inner);
194 let handle_events = move |evt, _evt_data, handle| {
195 if let Some(evt_ui) = evt_ui.upgrade() {
196 match evt {
197 E::OnButtonClick =>
198 if &handle == &evt_ui.btn0 { Calculator::number(&evt_ui, &evt_ui.btn0); }
199 else if &handle == &evt_ui.btn1 { Calculator::number(&evt_ui, &evt_ui.btn1); }
200 else if &handle == &evt_ui.btn2 { Calculator::number(&evt_ui, &evt_ui.btn2); }
201 else if &handle == &evt_ui.btn3 { Calculator::number(&evt_ui, &evt_ui.btn3); }
202 else if &handle == &evt_ui.btn4 { Calculator::number(&evt_ui, &evt_ui.btn4); }
203 else if &handle == &evt_ui.btn5 { Calculator::number(&evt_ui, &evt_ui.btn5); }
204 else if &handle == &evt_ui.btn6 { Calculator::number(&evt_ui, &evt_ui.btn6); }
205 else if &handle == &evt_ui.btn7 { Calculator::number(&evt_ui, &evt_ui.btn7); }
206 else if &handle == &evt_ui.btn8 { Calculator::number(&evt_ui, &evt_ui.btn8); }
207 else if &handle == &evt_ui.btn9 { Calculator::number(&evt_ui, &evt_ui.btn9); }
208
209 else if &handle == &evt_ui.btn_plus { Calculator::number(&evt_ui, &evt_ui.btn_plus); }
210 else if &handle == &evt_ui.btn_minus { Calculator::number(&evt_ui, &evt_ui.btn_minus); }
211 else if &handle == &evt_ui.btn_mult { Calculator::number(&evt_ui, &evt_ui.btn_mult); }
212 else if &handle == &evt_ui.btn_divide { Calculator::number(&evt_ui, &evt_ui.btn_divide); }
213
214 else if &handle == &evt_ui.btn_clear { Calculator::clear(&evt_ui); }
215
216 else if &handle == &evt_ui.btn_process { Calculator::compute(&evt_ui); }
217 E::OnWindowClose =>
218 if &handle == &evt_ui.window {
219 Calculator::exit(&evt_ui);
220 },
221 _ => {}
222 }
223 }
224 };
225
226 ui.default_handler.borrow_mut().push(
227 nwg::full_bind_event_handler(handle, handle_events)
228 );
229 }
230
231 // Layouts
232 nwg::GridLayout::builder()
233 .parent(&ui.window)
234 .spacing(2)
235 .min_size([150, 140])
236 .child_item(nwg::GridLayoutItem::new(&ui.input, 0, 0, 5, 1))
237 .child(0, 1, &ui.btn1)
238 .child(1, 1, &ui.btn2)
239 .child(2, 1, &ui.btn3)
240 .child(0, 2, &ui.btn4)
241 .child(1, 2, &ui.btn5)
242 .child(2, 2, &ui.btn6)
243 .child(0, 3, &ui.btn7)
244 .child(1, 3, &ui.btn8)
245 .child(2, 3, &ui.btn9)
246 .child(3, 1, &ui.btn_plus)
247 .child(4, 1, &ui.btn_minus)
248 .child(3, 2, &ui.btn_mult)
249 .child(4, 2, &ui.btn_divide)
250 .child_item(nwg::GridLayoutItem::new(&ui.btn_clear, 3, 3, 2, 1))
251 .child_item(nwg::GridLayoutItem::new(&ui.btn_process, 3, 4, 2, 1))
252 .child_item(nwg::GridLayoutItem::new(&ui.btn0, 0, 4, 3, 1))
253 .build(&ui.layout)?;
254
255 return Ok(ui);
256 }
pub fn font(self, font: Option<&'a Font>) -> TextInputBuilder<'a>
pub fn background_color(self, color: Option<[u8; 3]>) -> TextInputBuilder<'a>
Sourcepub fn focus(self, focus: bool) -> TextInputBuilder<'a>
pub fn focus(self, focus: bool) -> TextInputBuilder<'a>
Examples found in repository?
examples/basic_barebone.rs (line 30)
12fn main() {
13 nwg::init().expect("Failed to init Native Windows GUI");
14 nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
15
16 let mut window = Default::default();
17 let mut name_edit = Default::default();
18 let mut hello_button = Default::default();
19 let layout = Default::default();
20
21 nwg::Window::builder()
22 .size((300, 115))
23 .position((300, 300))
24 .title("Basic example")
25 .build(&mut window)
26 .unwrap();
27
28 nwg::TextInput::builder()
29 .text("Heisenberg")
30 .focus(true)
31 .parent(&window)
32 .build(&mut name_edit)
33 .unwrap();
34
35 nwg::Button::builder()
36 .text("Say my name")
37 .parent(&window)
38 .build(&mut hello_button)
39 .unwrap();
40
41 nwg::GridLayout::builder()
42 .parent(&window)
43 .spacing(1)
44 .child(0, 0, &name_edit)
45 .child_item(nwg::GridLayoutItem::new(&hello_button, 0, 1, 1, 2))
46 .build(&layout)
47 .unwrap();
48
49 let window = Rc::new(window);
50 let events_window = window.clone();
51
52 let handler = nwg::full_bind_event_handler(&window.handle, move |evt, _evt_data, handle| {
53 use nwg::Event as E;
54
55 match evt {
56 E::OnWindowClose =>
57 if &handle == &events_window as &nwg::Window {
58 nwg::modal_info_message(&events_window.handle, "Goodbye", &format!("Goodbye {}", name_edit.text()));
59 nwg::stop_thread_dispatch();
60 },
61 E::OnButtonClick =>
62 if &handle == &hello_button {
63 nwg::modal_info_message(&events_window.handle, "Hello", &format!("Hello {}", name_edit.text()));
64 },
65 _ => {}
66 }
67 });
68
69 nwg::dispatch_thread_events();
70 nwg::unbind_event_handler(&handler);
71}
More examples
examples/basic.rs (line 62)
46 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47 use nwg::Event as E;
48
49 // Controls
50 nwg::Window::builder()
51 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52 .size((300, 135))
53 .position((300, 300))
54 .title("Basic example")
55 .build(&mut data.window)?;
56
57 nwg::TextInput::builder()
58 .size((280, 35))
59 .position((10, 10))
60 .text("Heisenberg")
61 .parent(&data.window)
62 .focus(true)
63 .build(&mut data.name_edit)?;
64
65 nwg::Button::builder()
66 .size((280, 70))
67 .position((10, 50))
68 .text("Say my name")
69 .parent(&data.window)
70 .build(&mut data.hello_button)?;
71
72 // Wrap-up
73 let ui = BasicAppUi {
74 inner: Rc::new(data),
75 default_handler: Default::default(),
76 };
77
78 // Events
79 let evt_ui = Rc::downgrade(&ui.inner);
80 let handle_events = move |evt, _evt_data, handle| {
81 if let Some(ui) = evt_ui.upgrade() {
82 match evt {
83 E::OnButtonClick =>
84 if &handle == &ui.hello_button {
85 BasicApp::say_hello(&ui);
86 },
87 E::OnWindowClose =>
88 if &handle == &ui.window {
89 BasicApp::say_goodbye(&ui);
90 },
91 _ => {}
92 }
93 }
94 };
95
96 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98 return Ok(ui);
99 }
examples/basic_layout.rs (line 61)
47 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
48 use nwg::Event as E;
49
50 // Controls
51 nwg::Window::builder()
52 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
53 .size((300, 115))
54 .position((300, 300))
55 .title("Basic example")
56 .build(&mut data.window)?;
57
58 nwg::TextInput::builder()
59 .text("Heisenberg")
60 .parent(&data.window)
61 .focus(true)
62 .build(&mut data.name_edit)?;
63
64 nwg::Button::builder()
65 .text("Say my name")
66 .parent(&data.window)
67 .build(&mut data.hello_button)?;
68
69 // Wrap-up
70 let ui = BasicAppUi {
71 inner: Rc::new(data),
72 default_handler: Default::default(),
73 };
74
75 // Events
76 let evt_ui = Rc::downgrade(&ui.inner);
77 let handle_events = move |evt, _evt_data, handle| {
78 if let Some(evt_ui) = evt_ui.upgrade() {
79 match evt {
80 E::OnButtonClick =>
81 if &handle == &evt_ui.hello_button {
82 BasicApp::say_hello(&evt_ui);
83 },
84 E::OnWindowClose =>
85 if &handle == &evt_ui.window {
86 BasicApp::say_goodbye(&evt_ui);
87 },
88 _ => {}
89 }
90 }
91 };
92
93 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
94
95 // Layouts
96 nwg::GridLayout::builder()
97 .parent(&ui.window)
98 .spacing(1)
99 .child(0, 0, &ui.name_edit)
100 .child_item(nwg::GridLayoutItem::new(&ui.hello_button, 0, 1, 1, 2))
101 .build(&ui.layout)?;
102
103 return Ok(ui);
104 }
examples/message_bank.rs (line 101)
88 fn build_ui(mut data: MessageBank) -> Result<MessageBankUi, nwg::NwgError> {
89 use nwg::Event as E;
90
91 // Controls
92 nwg::Window::builder()
93 .flags(nwg::WindowFlags::MAIN_WINDOW | nwg::WindowFlags::VISIBLE)
94 .size((400, 300))
95 .position((800, 300))
96 .title("My message bank")
97 .build(&mut data.window)?;
98
99 nwg::TextInput::builder()
100 .text("Hello World!")
101 .focus(true)
102 .parent(&data.window)
103 .build(&mut data.message_content)?;
104
105 nwg::Button::builder()
106 .text("Save")
107 .parent(&data.window)
108 .build(&mut data.add_message_btn)?;
109
110 nwg::TextInput::builder()
111 .text("Title")
112 .parent(&data.window)
113 .build(&mut data.message_title)?;
114
115 // Wrap-up
116 let ui = MessageBankUi {
117 inner: Rc::new(data),
118 default_handler: Default::default(),
119 };
120
121 // Events
122 let window_handles = [&ui.window.handle];
123
124 for handle in window_handles.iter() {
125 let evt_ui = Rc::downgrade(&ui.inner);
126 let handle_events = move |evt, _evt_data, handle| {
127 if let Some(evt_ui) = evt_ui.upgrade() {
128 match evt {
129 E::OnButtonClick => {
130 if &handle == &evt_ui.add_message_btn { MessageBank::add_message(&evt_ui); }
131 },
132 E::OnWindowClose => {
133 if &handle == &evt_ui.window { MessageBank::exit(&evt_ui); }
134 },
135 _ => {}
136 }
137 }
138 };
139
140 ui.default_handler.borrow_mut().push(
141 nwg::full_bind_event_handler(handle, handle_events)
142 );
143 }
144
145 // Layout
146 nwg::GridLayout::builder()
147 .parent(&ui.window)
148 .max_row(Some(6))
149 .child(0, 0, &ui.add_message_btn)
150 .child_item(nwg::GridLayoutItem::new(&ui.message_title, 1, 0, 2, 1))
151 .child_item(nwg::GridLayoutItem::new(&ui.message_content, 3, 0, 3, 1))
152 .build(&ui.layout)?;
153
154 return Ok(ui);
155 }
Sourcepub fn parent<C: Into<ControlHandle>>(self, p: C) -> TextInputBuilder<'a>
pub fn parent<C: Into<ControlHandle>>(self, p: C) -> TextInputBuilder<'a>
Examples found in repository?
examples/partial_simple.rs (line 94)
89 fn build_partial<W: Into<nwg::ControlHandle>>(data: &mut SubmitForm, parent: Option<W>) -> Result<(), nwg::NwgError> {
90 let parent = parent.unwrap().into();
91
92 nwg::TextInput::builder()
93 .text(&data.form_data)
94 .parent(&parent)
95 .build(&mut data.value)?;
96
97 nwg::Button::builder()
98 .text("Save")
99 .parent(&parent)
100 .build(&mut data.sumbit_button)?;
101
102 nwg::GridLayout::builder()
103 .child(0, 0, &data.value)
104 .child(0, 1, &data.sumbit_button)
105 .parent(&parent)
106 .build(&data.layout)?;
107
108 Ok(())
109 }
More examples
examples/basic_barebone.rs (line 31)
12fn main() {
13 nwg::init().expect("Failed to init Native Windows GUI");
14 nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
15
16 let mut window = Default::default();
17 let mut name_edit = Default::default();
18 let mut hello_button = Default::default();
19 let layout = Default::default();
20
21 nwg::Window::builder()
22 .size((300, 115))
23 .position((300, 300))
24 .title("Basic example")
25 .build(&mut window)
26 .unwrap();
27
28 nwg::TextInput::builder()
29 .text("Heisenberg")
30 .focus(true)
31 .parent(&window)
32 .build(&mut name_edit)
33 .unwrap();
34
35 nwg::Button::builder()
36 .text("Say my name")
37 .parent(&window)
38 .build(&mut hello_button)
39 .unwrap();
40
41 nwg::GridLayout::builder()
42 .parent(&window)
43 .spacing(1)
44 .child(0, 0, &name_edit)
45 .child_item(nwg::GridLayoutItem::new(&hello_button, 0, 1, 1, 2))
46 .build(&layout)
47 .unwrap();
48
49 let window = Rc::new(window);
50 let events_window = window.clone();
51
52 let handler = nwg::full_bind_event_handler(&window.handle, move |evt, _evt_data, handle| {
53 use nwg::Event as E;
54
55 match evt {
56 E::OnWindowClose =>
57 if &handle == &events_window as &nwg::Window {
58 nwg::modal_info_message(&events_window.handle, "Goodbye", &format!("Goodbye {}", name_edit.text()));
59 nwg::stop_thread_dispatch();
60 },
61 E::OnButtonClick =>
62 if &handle == &hello_button {
63 nwg::modal_info_message(&events_window.handle, "Hello", &format!("Hello {}", name_edit.text()));
64 },
65 _ => {}
66 }
67 });
68
69 nwg::dispatch_thread_events();
70 nwg::unbind_event_handler(&handler);
71}
examples/basic.rs (line 61)
46 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47 use nwg::Event as E;
48
49 // Controls
50 nwg::Window::builder()
51 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52 .size((300, 135))
53 .position((300, 300))
54 .title("Basic example")
55 .build(&mut data.window)?;
56
57 nwg::TextInput::builder()
58 .size((280, 35))
59 .position((10, 10))
60 .text("Heisenberg")
61 .parent(&data.window)
62 .focus(true)
63 .build(&mut data.name_edit)?;
64
65 nwg::Button::builder()
66 .size((280, 70))
67 .position((10, 50))
68 .text("Say my name")
69 .parent(&data.window)
70 .build(&mut data.hello_button)?;
71
72 // Wrap-up
73 let ui = BasicAppUi {
74 inner: Rc::new(data),
75 default_handler: Default::default(),
76 };
77
78 // Events
79 let evt_ui = Rc::downgrade(&ui.inner);
80 let handle_events = move |evt, _evt_data, handle| {
81 if let Some(ui) = evt_ui.upgrade() {
82 match evt {
83 E::OnButtonClick =>
84 if &handle == &ui.hello_button {
85 BasicApp::say_hello(&ui);
86 },
87 E::OnWindowClose =>
88 if &handle == &ui.window {
89 BasicApp::say_goodbye(&ui);
90 },
91 _ => {}
92 }
93 }
94 };
95
96 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98 return Ok(ui);
99 }
examples/basic_layout.rs (line 60)
47 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
48 use nwg::Event as E;
49
50 // Controls
51 nwg::Window::builder()
52 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
53 .size((300, 115))
54 .position((300, 300))
55 .title("Basic example")
56 .build(&mut data.window)?;
57
58 nwg::TextInput::builder()
59 .text("Heisenberg")
60 .parent(&data.window)
61 .focus(true)
62 .build(&mut data.name_edit)?;
63
64 nwg::Button::builder()
65 .text("Say my name")
66 .parent(&data.window)
67 .build(&mut data.hello_button)?;
68
69 // Wrap-up
70 let ui = BasicAppUi {
71 inner: Rc::new(data),
72 default_handler: Default::default(),
73 };
74
75 // Events
76 let evt_ui = Rc::downgrade(&ui.inner);
77 let handle_events = move |evt, _evt_data, handle| {
78 if let Some(evt_ui) = evt_ui.upgrade() {
79 match evt {
80 E::OnButtonClick =>
81 if &handle == &evt_ui.hello_button {
82 BasicApp::say_hello(&evt_ui);
83 },
84 E::OnWindowClose =>
85 if &handle == &evt_ui.window {
86 BasicApp::say_goodbye(&evt_ui);
87 },
88 _ => {}
89 }
90 }
91 };
92
93 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
94
95 // Layouts
96 nwg::GridLayout::builder()
97 .parent(&ui.window)
98 .spacing(1)
99 .child(0, 0, &ui.name_edit)
100 .child_item(nwg::GridLayoutItem::new(&ui.hello_button, 0, 1, 1, 2))
101 .build(&ui.layout)?;
102
103 return Ok(ui);
104 }
examples/partials.rs (line 273)
250 fn build_partial<W: Into<ControlHandle>>(data: &mut PeopleUi, parent: Option<W>) -> Result<(), NwgError> {
251 let parent = parent.unwrap().into();
252
253 nwg::Label::builder()
254 .text("Name:")
255 .h_align(nwg::HTextAlign::Right)
256 .parent(&parent)
257 .build(&mut data.label1)?;
258
259 nwg::Label::builder()
260 .text("Age:")
261 .h_align(nwg::HTextAlign::Right)
262 .parent(&parent)
263 .build(&mut data.label2)?;
264
265 nwg::Label::builder()
266 .text("Job:")
267 .h_align(nwg::HTextAlign::Right)
268 .parent(&parent)
269 .build(&mut data.label3)?;
270
271 nwg::TextInput::builder()
272 .text("John Doe")
273 .parent(&parent)
274 .build(&mut data.name_input)?;
275
276 nwg::TextInput::builder()
277 .text("75")
278 .flags(nwg::TextInputFlags::VISIBLE | nwg::TextInputFlags::NUMBER)
279 .parent(&parent)
280 .build(&mut data.age_input)?;
281
282 nwg::TextInput::builder()
283 .text("Programmer")
284 .parent(&parent)
285 .build(&mut data.job_input)?;
286
287 nwg::Button::builder()
288 .text("Save")
289 .parent(&parent)
290 .build(&mut data.save_btn)?;
291
292 nwg::GridLayout::builder()
293 .parent(&parent)
294 .max_size([1000, 150])
295 .min_size([100, 120])
296 .child(0, 0, &data.label1)
297 .child(0, 1, &data.label2)
298 .child(0, 2, &data.label3)
299 .child(1, 0, &data.name_input)
300 .child(1, 1, &data.age_input)
301 .child(1, 2, &data.job_input)
302 .build(&data.layout)?;
303
304 nwg::GridLayout::builder()
305 .min_size([100, 200])
306 .max_column(Some(2))
307 .max_row(Some(6))
308 .child(1, 5, &data.save_btn)
309 .parent(&parent)
310 .build(&data.layout2)?;
311
312 Ok(())
313 }
314
315 fn process_event<'a>(&self, _evt: nwg::Event, _evt_data: &nwg::EventData, _handle: ControlHandle) {
316 }
317
318 fn handles(&self) -> Vec<&ControlHandle> {
319 Vec::new()
320 }
321 }
322}
323
324mod partial_animal_ui {
325 use native_windows_gui as nwg;
326 use self::nwg::{PartialUi, NwgError, ControlHandle};
327 use super::*;
328
329 impl PartialUi for AnimalUi {
330
331 fn build_partial<W: Into<ControlHandle>>(data: &mut AnimalUi, parent: Option<W>) -> Result<(), NwgError> {
332 let parent = parent.unwrap().into();
333
334 nwg::Label::builder()
335 .text("Name:")
336 .h_align(nwg::HTextAlign::Right)
337 .parent(&parent)
338 .build(&mut data.label1)?;
339
340 nwg::Label::builder()
341 .text("Race:")
342 .h_align(nwg::HTextAlign::Right)
343 .parent(&parent)
344 .build(&mut data.label2)?;
345
346 nwg::Label::builder()
347 .text("Is fluffy:")
348 .h_align(nwg::HTextAlign::Right)
349 .parent(&parent)
350 .build(&mut data.label3)?;
351
352 nwg::TextInput::builder()
353 .text("Mittens")
354 .parent(&parent)
355 .build(&mut data.name_input)?;
356
357 nwg::ComboBox::builder()
358 .collection(vec!["Cat", "Dog", "Pidgeon", "Monkey"])
359 .selected_index(Some(0))
360 .parent(&parent)
361 .build(&mut data.race_input)?;
362
363 nwg::CheckBox::builder()
364 .text("")
365 .check_state(nwg::CheckBoxState::Checked)
366 .parent(&parent)
367 .build(&mut data.is_soft_input)?;
368
369 nwg::Button::builder()
370 .text("Save")
371 .parent(&parent)
372 .build(&mut data.save_btn)?;
373
374 nwg::GridLayout::builder()
375 .parent(&parent)
376 .max_size([1000, 150])
377 .min_size([100, 120])
378 .child(0, 0, &data.label1)
379 .child(0, 1, &data.label2)
380 .child(0, 2, &data.label3)
381 .child(1, 0, &data.name_input)
382 .child(1, 1, &data.race_input)
383 .child(1, 2, &data.is_soft_input)
384 .build(&data.layout)?;
385
386 nwg::GridLayout::builder()
387 .min_size([100, 200])
388 .max_column(Some(2))
389 .max_row(Some(6))
390 .child(1, 5, &data.save_btn)
391 .parent(&parent)
392 .build(&data.layout2)?;
393
394 Ok(())
395 }
396
397 fn process_event<'a>(&self, _evt: nwg::Event, _evt_data: &nwg::EventData, _handle: ControlHandle) {
398 }
399
400 fn handles(&self) -> Vec<&ControlHandle> {
401 Vec::new()
402 }
403 }
404}
405
406mod partial_food_ui {
407 use native_windows_gui as nwg;
408 use self::nwg::{PartialUi, NwgError, ControlHandle};
409 use super::*;
410
411 impl PartialUi for FoodUi {
412 fn build_partial<W: Into<ControlHandle>>(data: &mut FoodUi, parent: Option<W>) -> Result<(), NwgError> {
413 let parent = parent.unwrap().into();
414
415 nwg::Label::builder()
416 .text("Name:")
417 .h_align(nwg::HTextAlign::Right)
418 .parent(&parent)
419 .build(&mut data.label1)?;
420
421 nwg::Label::builder()
422 .text("Tasty:")
423 .h_align(nwg::HTextAlign::Right)
424 .parent(&parent)
425 .build(&mut data.label2)?;
426
427 nwg::TextInput::builder()
428 .text("Banana")
429 .parent(&parent)
430 .build(&mut data.name_input)?;
431
432 nwg::CheckBox::builder()
433 .text("")
434 .check_state(nwg::CheckBoxState::Checked)
435 .parent(&parent)
436 .build(&mut data.tasty_input)?;
437
438 nwg::Button::builder()
439 .text("Save")
440 .parent(&parent)
441 .build(&mut data.save_btn)?;
442
443 nwg::GridLayout::builder()
444 .parent(&parent)
445 .max_size([1000, 90])
446 .min_size([100, 80])
447 .child(0, 0, &data.label1)
448 .child(0, 1, &data.label2)
449 .child(1, 0, &data.name_input)
450 .child(1, 1, &data.tasty_input)
451 .build(&data.layout)?;
452
453 nwg::GridLayout::builder()
454 .min_size([100, 200])
455 .max_column(Some(2))
456 .max_row(Some(6))
457 .child(1, 5, &data.save_btn)
458 .parent(&parent)
459 .build(&data.layout2)?;
460
461 Ok(())
462 }
examples/message_bank.rs (line 102)
88 fn build_ui(mut data: MessageBank) -> Result<MessageBankUi, nwg::NwgError> {
89 use nwg::Event as E;
90
91 // Controls
92 nwg::Window::builder()
93 .flags(nwg::WindowFlags::MAIN_WINDOW | nwg::WindowFlags::VISIBLE)
94 .size((400, 300))
95 .position((800, 300))
96 .title("My message bank")
97 .build(&mut data.window)?;
98
99 nwg::TextInput::builder()
100 .text("Hello World!")
101 .focus(true)
102 .parent(&data.window)
103 .build(&mut data.message_content)?;
104
105 nwg::Button::builder()
106 .text("Save")
107 .parent(&data.window)
108 .build(&mut data.add_message_btn)?;
109
110 nwg::TextInput::builder()
111 .text("Title")
112 .parent(&data.window)
113 .build(&mut data.message_title)?;
114
115 // Wrap-up
116 let ui = MessageBankUi {
117 inner: Rc::new(data),
118 default_handler: Default::default(),
119 };
120
121 // Events
122 let window_handles = [&ui.window.handle];
123
124 for handle in window_handles.iter() {
125 let evt_ui = Rc::downgrade(&ui.inner);
126 let handle_events = move |evt, _evt_data, handle| {
127 if let Some(evt_ui) = evt_ui.upgrade() {
128 match evt {
129 E::OnButtonClick => {
130 if &handle == &evt_ui.add_message_btn { MessageBank::add_message(&evt_ui); }
131 },
132 E::OnWindowClose => {
133 if &handle == &evt_ui.window { MessageBank::exit(&evt_ui); }
134 },
135 _ => {}
136 }
137 }
138 };
139
140 ui.default_handler.borrow_mut().push(
141 nwg::full_bind_event_handler(handle, handle_events)
142 );
143 }
144
145 // Layout
146 nwg::GridLayout::builder()
147 .parent(&ui.window)
148 .max_row(Some(6))
149 .child(0, 0, &ui.add_message_btn)
150 .child_item(nwg::GridLayoutItem::new(&ui.message_title, 1, 0, 2, 1))
151 .child_item(nwg::GridLayoutItem::new(&ui.message_content, 3, 0, 3, 1))
152 .build(&ui.layout)?;
153
154 return Ok(ui);
155 }
Additional examples can be found in:
Sourcepub fn build(self, out: &mut TextInput) -> Result<(), NwgError>
pub fn build(self, out: &mut TextInput) -> Result<(), NwgError>
Examples found in repository?
examples/partial_simple.rs (line 95)
89 fn build_partial<W: Into<nwg::ControlHandle>>(data: &mut SubmitForm, parent: Option<W>) -> Result<(), nwg::NwgError> {
90 let parent = parent.unwrap().into();
91
92 nwg::TextInput::builder()
93 .text(&data.form_data)
94 .parent(&parent)
95 .build(&mut data.value)?;
96
97 nwg::Button::builder()
98 .text("Save")
99 .parent(&parent)
100 .build(&mut data.sumbit_button)?;
101
102 nwg::GridLayout::builder()
103 .child(0, 0, &data.value)
104 .child(0, 1, &data.sumbit_button)
105 .parent(&parent)
106 .build(&data.layout)?;
107
108 Ok(())
109 }
More examples
examples/basic_barebone.rs (line 32)
12fn main() {
13 nwg::init().expect("Failed to init Native Windows GUI");
14 nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
15
16 let mut window = Default::default();
17 let mut name_edit = Default::default();
18 let mut hello_button = Default::default();
19 let layout = Default::default();
20
21 nwg::Window::builder()
22 .size((300, 115))
23 .position((300, 300))
24 .title("Basic example")
25 .build(&mut window)
26 .unwrap();
27
28 nwg::TextInput::builder()
29 .text("Heisenberg")
30 .focus(true)
31 .parent(&window)
32 .build(&mut name_edit)
33 .unwrap();
34
35 nwg::Button::builder()
36 .text("Say my name")
37 .parent(&window)
38 .build(&mut hello_button)
39 .unwrap();
40
41 nwg::GridLayout::builder()
42 .parent(&window)
43 .spacing(1)
44 .child(0, 0, &name_edit)
45 .child_item(nwg::GridLayoutItem::new(&hello_button, 0, 1, 1, 2))
46 .build(&layout)
47 .unwrap();
48
49 let window = Rc::new(window);
50 let events_window = window.clone();
51
52 let handler = nwg::full_bind_event_handler(&window.handle, move |evt, _evt_data, handle| {
53 use nwg::Event as E;
54
55 match evt {
56 E::OnWindowClose =>
57 if &handle == &events_window as &nwg::Window {
58 nwg::modal_info_message(&events_window.handle, "Goodbye", &format!("Goodbye {}", name_edit.text()));
59 nwg::stop_thread_dispatch();
60 },
61 E::OnButtonClick =>
62 if &handle == &hello_button {
63 nwg::modal_info_message(&events_window.handle, "Hello", &format!("Hello {}", name_edit.text()));
64 },
65 _ => {}
66 }
67 });
68
69 nwg::dispatch_thread_events();
70 nwg::unbind_event_handler(&handler);
71}
examples/basic.rs (line 63)
46 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47 use nwg::Event as E;
48
49 // Controls
50 nwg::Window::builder()
51 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52 .size((300, 135))
53 .position((300, 300))
54 .title("Basic example")
55 .build(&mut data.window)?;
56
57 nwg::TextInput::builder()
58 .size((280, 35))
59 .position((10, 10))
60 .text("Heisenberg")
61 .parent(&data.window)
62 .focus(true)
63 .build(&mut data.name_edit)?;
64
65 nwg::Button::builder()
66 .size((280, 70))
67 .position((10, 50))
68 .text("Say my name")
69 .parent(&data.window)
70 .build(&mut data.hello_button)?;
71
72 // Wrap-up
73 let ui = BasicAppUi {
74 inner: Rc::new(data),
75 default_handler: Default::default(),
76 };
77
78 // Events
79 let evt_ui = Rc::downgrade(&ui.inner);
80 let handle_events = move |evt, _evt_data, handle| {
81 if let Some(ui) = evt_ui.upgrade() {
82 match evt {
83 E::OnButtonClick =>
84 if &handle == &ui.hello_button {
85 BasicApp::say_hello(&ui);
86 },
87 E::OnWindowClose =>
88 if &handle == &ui.window {
89 BasicApp::say_goodbye(&ui);
90 },
91 _ => {}
92 }
93 }
94 };
95
96 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98 return Ok(ui);
99 }
examples/basic_layout.rs (line 62)
47 fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
48 use nwg::Event as E;
49
50 // Controls
51 nwg::Window::builder()
52 .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
53 .size((300, 115))
54 .position((300, 300))
55 .title("Basic example")
56 .build(&mut data.window)?;
57
58 nwg::TextInput::builder()
59 .text("Heisenberg")
60 .parent(&data.window)
61 .focus(true)
62 .build(&mut data.name_edit)?;
63
64 nwg::Button::builder()
65 .text("Say my name")
66 .parent(&data.window)
67 .build(&mut data.hello_button)?;
68
69 // Wrap-up
70 let ui = BasicAppUi {
71 inner: Rc::new(data),
72 default_handler: Default::default(),
73 };
74
75 // Events
76 let evt_ui = Rc::downgrade(&ui.inner);
77 let handle_events = move |evt, _evt_data, handle| {
78 if let Some(evt_ui) = evt_ui.upgrade() {
79 match evt {
80 E::OnButtonClick =>
81 if &handle == &evt_ui.hello_button {
82 BasicApp::say_hello(&evt_ui);
83 },
84 E::OnWindowClose =>
85 if &handle == &evt_ui.window {
86 BasicApp::say_goodbye(&evt_ui);
87 },
88 _ => {}
89 }
90 }
91 };
92
93 *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
94
95 // Layouts
96 nwg::GridLayout::builder()
97 .parent(&ui.window)
98 .spacing(1)
99 .child(0, 0, &ui.name_edit)
100 .child_item(nwg::GridLayoutItem::new(&ui.hello_button, 0, 1, 1, 2))
101 .build(&ui.layout)?;
102
103 return Ok(ui);
104 }
examples/partials.rs (line 274)
250 fn build_partial<W: Into<ControlHandle>>(data: &mut PeopleUi, parent: Option<W>) -> Result<(), NwgError> {
251 let parent = parent.unwrap().into();
252
253 nwg::Label::builder()
254 .text("Name:")
255 .h_align(nwg::HTextAlign::Right)
256 .parent(&parent)
257 .build(&mut data.label1)?;
258
259 nwg::Label::builder()
260 .text("Age:")
261 .h_align(nwg::HTextAlign::Right)
262 .parent(&parent)
263 .build(&mut data.label2)?;
264
265 nwg::Label::builder()
266 .text("Job:")
267 .h_align(nwg::HTextAlign::Right)
268 .parent(&parent)
269 .build(&mut data.label3)?;
270
271 nwg::TextInput::builder()
272 .text("John Doe")
273 .parent(&parent)
274 .build(&mut data.name_input)?;
275
276 nwg::TextInput::builder()
277 .text("75")
278 .flags(nwg::TextInputFlags::VISIBLE | nwg::TextInputFlags::NUMBER)
279 .parent(&parent)
280 .build(&mut data.age_input)?;
281
282 nwg::TextInput::builder()
283 .text("Programmer")
284 .parent(&parent)
285 .build(&mut data.job_input)?;
286
287 nwg::Button::builder()
288 .text("Save")
289 .parent(&parent)
290 .build(&mut data.save_btn)?;
291
292 nwg::GridLayout::builder()
293 .parent(&parent)
294 .max_size([1000, 150])
295 .min_size([100, 120])
296 .child(0, 0, &data.label1)
297 .child(0, 1, &data.label2)
298 .child(0, 2, &data.label3)
299 .child(1, 0, &data.name_input)
300 .child(1, 1, &data.age_input)
301 .child(1, 2, &data.job_input)
302 .build(&data.layout)?;
303
304 nwg::GridLayout::builder()
305 .min_size([100, 200])
306 .max_column(Some(2))
307 .max_row(Some(6))
308 .child(1, 5, &data.save_btn)
309 .parent(&parent)
310 .build(&data.layout2)?;
311
312 Ok(())
313 }
314
315 fn process_event<'a>(&self, _evt: nwg::Event, _evt_data: &nwg::EventData, _handle: ControlHandle) {
316 }
317
318 fn handles(&self) -> Vec<&ControlHandle> {
319 Vec::new()
320 }
321 }
322}
323
324mod partial_animal_ui {
325 use native_windows_gui as nwg;
326 use self::nwg::{PartialUi, NwgError, ControlHandle};
327 use super::*;
328
329 impl PartialUi for AnimalUi {
330
331 fn build_partial<W: Into<ControlHandle>>(data: &mut AnimalUi, parent: Option<W>) -> Result<(), NwgError> {
332 let parent = parent.unwrap().into();
333
334 nwg::Label::builder()
335 .text("Name:")
336 .h_align(nwg::HTextAlign::Right)
337 .parent(&parent)
338 .build(&mut data.label1)?;
339
340 nwg::Label::builder()
341 .text("Race:")
342 .h_align(nwg::HTextAlign::Right)
343 .parent(&parent)
344 .build(&mut data.label2)?;
345
346 nwg::Label::builder()
347 .text("Is fluffy:")
348 .h_align(nwg::HTextAlign::Right)
349 .parent(&parent)
350 .build(&mut data.label3)?;
351
352 nwg::TextInput::builder()
353 .text("Mittens")
354 .parent(&parent)
355 .build(&mut data.name_input)?;
356
357 nwg::ComboBox::builder()
358 .collection(vec!["Cat", "Dog", "Pidgeon", "Monkey"])
359 .selected_index(Some(0))
360 .parent(&parent)
361 .build(&mut data.race_input)?;
362
363 nwg::CheckBox::builder()
364 .text("")
365 .check_state(nwg::CheckBoxState::Checked)
366 .parent(&parent)
367 .build(&mut data.is_soft_input)?;
368
369 nwg::Button::builder()
370 .text("Save")
371 .parent(&parent)
372 .build(&mut data.save_btn)?;
373
374 nwg::GridLayout::builder()
375 .parent(&parent)
376 .max_size([1000, 150])
377 .min_size([100, 120])
378 .child(0, 0, &data.label1)
379 .child(0, 1, &data.label2)
380 .child(0, 2, &data.label3)
381 .child(1, 0, &data.name_input)
382 .child(1, 1, &data.race_input)
383 .child(1, 2, &data.is_soft_input)
384 .build(&data.layout)?;
385
386 nwg::GridLayout::builder()
387 .min_size([100, 200])
388 .max_column(Some(2))
389 .max_row(Some(6))
390 .child(1, 5, &data.save_btn)
391 .parent(&parent)
392 .build(&data.layout2)?;
393
394 Ok(())
395 }
396
397 fn process_event<'a>(&self, _evt: nwg::Event, _evt_data: &nwg::EventData, _handle: ControlHandle) {
398 }
399
400 fn handles(&self) -> Vec<&ControlHandle> {
401 Vec::new()
402 }
403 }
404}
405
406mod partial_food_ui {
407 use native_windows_gui as nwg;
408 use self::nwg::{PartialUi, NwgError, ControlHandle};
409 use super::*;
410
411 impl PartialUi for FoodUi {
412 fn build_partial<W: Into<ControlHandle>>(data: &mut FoodUi, parent: Option<W>) -> Result<(), NwgError> {
413 let parent = parent.unwrap().into();
414
415 nwg::Label::builder()
416 .text("Name:")
417 .h_align(nwg::HTextAlign::Right)
418 .parent(&parent)
419 .build(&mut data.label1)?;
420
421 nwg::Label::builder()
422 .text("Tasty:")
423 .h_align(nwg::HTextAlign::Right)
424 .parent(&parent)
425 .build(&mut data.label2)?;
426
427 nwg::TextInput::builder()
428 .text("Banana")
429 .parent(&parent)
430 .build(&mut data.name_input)?;
431
432 nwg::CheckBox::builder()
433 .text("")
434 .check_state(nwg::CheckBoxState::Checked)
435 .parent(&parent)
436 .build(&mut data.tasty_input)?;
437
438 nwg::Button::builder()
439 .text("Save")
440 .parent(&parent)
441 .build(&mut data.save_btn)?;
442
443 nwg::GridLayout::builder()
444 .parent(&parent)
445 .max_size([1000, 90])
446 .min_size([100, 80])
447 .child(0, 0, &data.label1)
448 .child(0, 1, &data.label2)
449 .child(1, 0, &data.name_input)
450 .child(1, 1, &data.tasty_input)
451 .build(&data.layout)?;
452
453 nwg::GridLayout::builder()
454 .min_size([100, 200])
455 .max_column(Some(2))
456 .max_row(Some(6))
457 .child(1, 5, &data.save_btn)
458 .parent(&parent)
459 .build(&data.layout2)?;
460
461 Ok(())
462 }
examples/message_bank.rs (line 103)
88 fn build_ui(mut data: MessageBank) -> Result<MessageBankUi, nwg::NwgError> {
89 use nwg::Event as E;
90
91 // Controls
92 nwg::Window::builder()
93 .flags(nwg::WindowFlags::MAIN_WINDOW | nwg::WindowFlags::VISIBLE)
94 .size((400, 300))
95 .position((800, 300))
96 .title("My message bank")
97 .build(&mut data.window)?;
98
99 nwg::TextInput::builder()
100 .text("Hello World!")
101 .focus(true)
102 .parent(&data.window)
103 .build(&mut data.message_content)?;
104
105 nwg::Button::builder()
106 .text("Save")
107 .parent(&data.window)
108 .build(&mut data.add_message_btn)?;
109
110 nwg::TextInput::builder()
111 .text("Title")
112 .parent(&data.window)
113 .build(&mut data.message_title)?;
114
115 // Wrap-up
116 let ui = MessageBankUi {
117 inner: Rc::new(data),
118 default_handler: Default::default(),
119 };
120
121 // Events
122 let window_handles = [&ui.window.handle];
123
124 for handle in window_handles.iter() {
125 let evt_ui = Rc::downgrade(&ui.inner);
126 let handle_events = move |evt, _evt_data, handle| {
127 if let Some(evt_ui) = evt_ui.upgrade() {
128 match evt {
129 E::OnButtonClick => {
130 if &handle == &evt_ui.add_message_btn { MessageBank::add_message(&evt_ui); }
131 },
132 E::OnWindowClose => {
133 if &handle == &evt_ui.window { MessageBank::exit(&evt_ui); }
134 },
135 _ => {}
136 }
137 }
138 };
139
140 ui.default_handler.borrow_mut().push(
141 nwg::full_bind_event_handler(handle, handle_events)
142 );
143 }
144
145 // Layout
146 nwg::GridLayout::builder()
147 .parent(&ui.window)
148 .max_row(Some(6))
149 .child(0, 0, &ui.add_message_btn)
150 .child_item(nwg::GridLayoutItem::new(&ui.message_title, 1, 0, 2, 1))
151 .child_item(nwg::GridLayoutItem::new(&ui.message_content, 3, 0, 3, 1))
152 .build(&ui.layout)?;
153
154 return Ok(ui);
155 }
Additional examples can be found in:
Auto Trait Implementations§
impl<'a> Freeze for TextInputBuilder<'a>
impl<'a> RefUnwindSafe for TextInputBuilder<'a>
impl<'a> !Send for TextInputBuilder<'a>
impl<'a> !Sync for TextInputBuilder<'a>
impl<'a> Unpin for TextInputBuilder<'a>
impl<'a> UnwindSafe for TextInputBuilder<'a>
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