multiple_windows/
multiple_windows.rs1#![windows_subsystem = "windows"]
8
9use std::collections::{BTreeMap, HashMap};
10
11use winit::error::EventLoopError;
12use xilem::view::{flex_col, label, text_button, text_input};
13use xilem::{AppState, EventLoop, EventLoopBuilder, WindowId, WindowView, Xilem, window};
14
15struct State {
16 new_counter_name: String,
17 counters: HashMap<WindowId, Counter>,
18 running: bool,
19 main_window_id: WindowId,
20}
21
22struct Counter {
23 name: String,
24 value: isize,
25}
26
27impl AppState for State {
28 fn keep_running(&self) -> bool {
29 self.running
30 }
31}
32
33fn app_logic(state: &mut State) -> impl Iterator<Item = WindowView<State>> + use<> {
34 std::iter::once(
35 window(
36 state.main_window_id,
37 "Multiple windows",
38 flex_col((
39 label(format!(
40 "{:#?}",
41 state
42 .counters
43 .values()
44 .map(|counter| (&counter.name, counter.value))
45 .collect::<BTreeMap<_, _>>()
46 )),
47 text_input(
48 state.new_counter_name.clone(),
49 |state: &mut State, new_name| {
50 state.new_counter_name = new_name;
51 },
52 ),
53 text_button("Add".to_string(), |state: &mut State| {
54 if state
55 .counters
56 .values()
57 .any(|counter| counter.name == state.new_counter_name)
58 {
59 return;
61 }
62 let name = std::mem::take(&mut state.new_counter_name);
63 state
64 .counters
65 .insert(WindowId::next(), Counter { name, value: 0 });
66 }),
67 )),
68 )
69 .with_options(|o| o.on_close(|state: &mut State| state.running = false)),
70 )
71 .chain(
72 state
73 .counters
74 .iter()
75 .map(|(window_id, Counter { name, value })| {
76 let window_id = *window_id;
77 window(
78 window_id,
79 name,
80 flex_col((
81 label(format!("count: {value}")),
82 text_button("+".to_string(), move |state: &mut State| {
83 state.counters.get_mut(&window_id).unwrap().value += 1;
84 }),
85 text_button("-".to_string(), move |state: &mut State| {
86 state.counters.get_mut(&window_id).unwrap().value -= 1;
87 }),
88 )),
89 )
90 .with_options(|o| {
91 o.on_close(move |state: &mut State| {
92 state.counters.remove(&window_id);
93 })
94 })
95 }),
96 )
97 .collect::<Vec<_>>()
98 .into_iter()
99}
100
101fn run(event_loop: EventLoopBuilder) -> Result<(), EventLoopError> {
102 let data = State {
103 new_counter_name: String::new(),
104 counters: HashMap::new(),
105 running: true,
106 main_window_id: WindowId::next(),
107 };
108 let app = Xilem::new(data, app_logic);
109 app.run_in(event_loop)
110}
111
112fn main() -> Result<(), EventLoopError> {
113 run(EventLoop::with_user_event())
114}