1use feather_ui::color::sRGB;
5use feather_ui::layout::{fixed, leaf};
6use feather_ui::text::{EditBuffer, EditView};
7use feather_ui::{DAbsRect, ScopeID, gen_id};
8
9use feather_ui::component::region::Region;
10use feather_ui::component::textbox;
11use feather_ui::component::textbox::TextBox;
12use feather_ui::component::window::Window;
13use feather_ui::layout::base;
14use feather_ui::persist::{FnPersist2, FnPersistStore};
15use feather_ui::{AbsRect, App, DRect, FILL_DRECT, RelRect, SourceID, cosmic_text};
16use std::sync::Arc;
17
18#[derive(PartialEq, Clone, Debug, Default)]
19struct TextState {
20 text: EditView,
21}
22
23struct BasicApp {}
24
25#[derive(Default, Clone, feather_macro::Empty, feather_macro::Area)]
26struct MinimalArea {
27 area: DRect,
28}
29
30impl base::ZIndex for MinimalArea {}
31impl base::Anchor for MinimalArea {}
32impl base::Limits for MinimalArea {}
33impl fixed::Prop for MinimalArea {}
34
35#[derive(
36 Clone,
37 feather_macro::Empty,
38 feather_macro::Area,
39 feather_macro::TextEdit,
40 feather_macro::Padding,
41)]
42struct MinimalText {
43 area: DRect,
44 padding: DAbsRect,
45 textedit: EditView,
46}
47impl base::Direction for MinimalText {}
48impl base::ZIndex for MinimalText {}
49impl base::Limits for MinimalText {}
50impl base::RLimits for MinimalText {}
51impl base::Anchor for MinimalText {}
52impl leaf::Padded for MinimalText {}
53impl leaf::Prop for MinimalText {}
54impl fixed::Child for MinimalText {}
55impl textbox::Prop for MinimalText {}
56
57impl FnPersistStore for BasicApp {
58 type Store = (TextState, im::HashMap<Arc<SourceID>, Option<Window>>);
59}
60
61impl FnPersist2<TextState, ScopeID<'_>, im::HashMap<Arc<SourceID>, Option<Window>>> for BasicApp {
62 fn init(&self) -> Self::Store {
63 (
64 TextState {
65 ..Default::default()
66 },
67 im::HashMap::new(),
68 )
69 }
70 fn call(
71 &mut self,
72 mut store: Self::Store,
73 args: TextState,
74 mut scope: ScopeID<'_>,
75 ) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
76 if store.0 != args {
77 let textbox = TextBox::new(
78 gen_id!(scope),
79 MinimalText {
80 area: FILL_DRECT,
81 padding: AbsRect::splat(12.0).into(),
82 textedit: args.text.clone(), },
84 40.0,
85 56.0,
86 cosmic_text::FamilyOwned::SansSerif,
87 sRGB::white(),
88 Default::default(),
89 Default::default(),
90 cosmic_text::Wrap::Word,
91 Some(cosmic_text::Align::Right),
92 );
93
94 let region = Region::new(
95 gen_id!(scope),
96 MinimalArea {
97 area: AbsRect::new(90.0, 0.0, -90.0, -180.0) + RelRect::new(0.0, 0.0, 1.0, 1.0),
98 },
99 feather_ui::children![fixed::Prop, textbox],
100 );
101 let window = Window::new(
102 gen_id!(scope),
103 winit::window::Window::default_attributes()
104 .with_title(env!("CARGO_CRATE_NAME"))
105 .with_inner_size(winit::dpi::PhysicalSize::new(600, 400))
106 .with_resizable(true),
107 Box::new(region),
108 );
109
110 store.1 = im::HashMap::new();
111 store.1.insert(window.id.clone(), Some(window));
112 store.0 = args.clone();
113 }
114 let windows = store.1.clone();
115 (store, windows)
116 }
117}
118
119fn main() {
120 let (mut app, event_loop, _, _) = App::<TextState, BasicApp>::new::<()>(
121 TextState {
122 text: EditBuffer::new("new text", (0, 0)).into(),
123 },
124 vec![],
125 BasicApp {},
126 |_| (),
127 )
128 .unwrap();
129
130 event_loop.run_app(&mut app).unwrap();
131}