pub struct ScopeID<'a> { /* private fields */ }
Expand description
Represents a scope with a particular ID assigned to it. Used to generate new IDs for anything created
inside this scope, with this scope’s ID as parents, or to generate a new ScopeID
with this scope as
its parent. Includes ScopeID::iter
and ScopeID::cond
to make it easier to generate stable IDs
across control flow boundaries. It can be used in conjunction with gen_id
to generate child IDs with
source and line numbers.
§Examples
use feather_ui::layout::fixed;
use feather_ui::component::{shape, region::Region};
use feather_ui::{ScopeID, gen_id, DRect, DAbsPoint, color::sRGB, FILL_DRECT, children };
fn foobar(mut id: ScopeID<'_>) {
let rect = shape::round_rect::<DRect>(
gen_id!(id),
FILL_DRECT,
0.0,
0.0,
wide::f32x4::splat(10.0),
sRGB::new(0.2, 0.7, 0.4, 1.0),
sRGB::transparent(),
DAbsPoint::zero(),
);
let region = Region::<DRect>::new(
id.create(),
FILL_DRECT,
children![fixed::Prop, rect],
);
}
Implementations§
Source§impl<'a> ScopeID<'a>
impl<'a> ScopeID<'a>
Sourcepub fn id(&mut self) -> &Arc<SourceID>
pub fn id(&mut self) -> &Arc<SourceID>
Gets the underlying ID for this scope. This is sometimes useful when creating custom scopes that belong to a specific component.
Sourcepub fn create(&mut self) -> Arc<SourceID>
pub fn create(&mut self) -> Arc<SourceID>
Creates a new unique SourceID
using an internal counter with this scope as it’s parent.
§Examples
use feather_ui::component::shape;
use feather_ui::{ScopeID, DRect, DAbsPoint, color::sRGB, FILL_DRECT };
fn foobar(mut id: ScopeID<'_>) {
let rect = shape::round_rect::<DRect>(
id.create(),
FILL_DRECT,
0.0,
0.0,
wide::f32x4::splat(10.0),
sRGB::new(0.2, 0.7, 0.4, 1.0),
sRGB::transparent(),
DAbsPoint::zero(),
);
}
Examples found in repository?
109 fn call(
110 &mut self,
111 mut store: Self::Store,
112 args: CounterState,
113 mut scope: ScopeID<'_>,
114 ) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
115 if store.0 != args {
116 let button = {
117 let text = {
118 Text::<FixedData> {
119 id: scope.create(),
120 props: FixedData {
121 area: AbsRect::new(10.0, 15.0, 10.0, 15.0)
122 + RelRect::new(0.0, 0.0, UNSIZED_AXIS, UNSIZED_AXIS),
123 anchor: feather_ui::RelPoint::zero().into(),
124 ..Default::default()
125 }
126 .into(),
127 text: format!("Boxes: {}", args.count),
128 font_size: 40.0,
129 line_height: 56.0,
130 ..Default::default()
131 }
132 };
133
134 let rect = Shape::<DRect, { ShapeKind::RoundRect as u8 }>::new(
135 scope.create(),
136 feather_ui::FILL_DRECT,
137 0.0,
138 0.0,
139 wide::f32x4::splat(10.0),
140 sRGB::new(0.2, 0.7, 0.4, 1.0),
141 sRGB::transparent(),
142 DAbsPoint::zero(),
143 );
144
145 Button::<FixedData>::new(
146 scope.create(),
147 FixedData {
148 area: AbsRect::new(0.0, 20.0, 0.0, 0.0)
149 + RelRect::new(0.5, 0.0, UNSIZED_AXIS, UNSIZED_AXIS),
150 anchor: feather_ui::RelPoint::new(0.5, 0.0).into(),
151 zindex: 0,
152 },
153 Slot(feather_ui::APP_SOURCE_ID.into(), 0),
154 feather_ui::children![fixed::Prop, rect, text],
155 )
156 };
157
158 const NUM_COLUMNS: usize = 5;
159 let rectgrid = {
160 let mut children: im::Vector<Option<Box<ChildOf<dyn grid::Prop>>>> =
161 im::Vector::new();
162 {
163 for (i, id) in scope.iter(0..args.count) {
164 children.push_back(Some(Box::new(Shape::<
165 GridChild,
166 { ShapeKind::RoundRect as u8 },
167 >::new(
168 id,
169 GridChild {
170 area: FILL_DRECT,
171 x: i % NUM_COLUMNS,
172 y: i / NUM_COLUMNS,
173 },
174 0.0,
175 0.0,
176 wide::f32x4::splat(4.0),
177 sRGB::new(
178 (0.1 * i as f32) % 1.0,
179 (0.65 * i as f32) % 1.0,
180 (0.2 * i as f32) % 1.0,
181 1.0,
182 ),
183 sRGB::transparent(),
184 DAbsPoint::zero(),
185 ))));
186 }
187 }
188
189 GridBox::<GridData>::new(
190 scope.create(),
191 GridData {
192 area: AbsRect::new(0.0, 200.0, 0.0, 0.0)
193 + RelRect::new(0.0, 0.0, UNSIZED_AXIS, 1.0),
194
195 rlimits: feather_ui::RelLimits::new(0.0..1.0, 0.0..),
196 direction: feather_ui::RowDirection::LeftToRight,
197 rows: [40.0, 20.0, 40.0, 20.0, 40.0, 20.0, 10.0]
198 .map(DValue::from)
199 .to_vec(),
200 columns: [80.0, 40.0, 80.0, 40.0, 80.0].map(DValue::from).to_vec(),
201 spacing: AbsPoint::new(4.0, 4.0).into(),
202 padding: AbsRect::new(8.0, 8.0, 8.0, 8.0).into(),
203 },
204 children,
205 )
206 };
207
208 let region = Region::new(
209 scope.create(),
210 FixedData {
211 area: FILL_DRECT,
212 zindex: 0,
213 ..Default::default()
214 },
215 feather_ui::children![fixed::Prop, button, rectgrid],
216 );
217 let window = Window::new(
218 scope.create(),
219 winit::window::Window::default_attributes()
220 .with_title(env!("CARGO_CRATE_NAME"))
221 .with_resizable(true),
222 Box::new(region),
223 );
224
225 store.1 = im::HashMap::new();
226 store.1.insert(window.id.clone(), Some(window));
227 store.0 = args.clone();
228 }
229 let windows = store.1.clone();
230 (store, windows)
231 }
More examples
45 fn call(
46 &mut self,
47 _: Self::Store,
48 _: (),
49 mut scope: ScopeID<'_>,
50 ) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
51 let pixel = Shape::<DRect, { ShapeKind::RoundRect as u8 }>::new(
52 scope.create(),
53 PxRect::new(1.0, 1.0, 2.0, 2.0).into(),
54 0.0,
55 0.0,
56 wide::f32x4::splat(0.0),
57 sRGB::new(1.0, 1.0, 1.0, 1.0),
58 sRGB::transparent(),
59 feather_ui::DAbsPoint::zero(),
60 );
61
62 let mut children: im::Vector<Option<Box<feather_ui::component::ChildOf<dyn fixed::Prop>>>> =
63 im::Vector::new();
64 children.push_back(Some(Box::new(pixel)));
65
66 let mut genimage = |pos: AbsPoint,
67 w: Option<f32>,
68 h: Option<f32>,
69 res: &dyn feather_ui::resource::Location,
70 size: Option<AbsPoint>| {
71 Image::<DRect>::new(
72 scope.create(),
73 AbsRect::new(
74 pos.x,
75 pos.y,
76 w.map(|x| x + pos.x).unwrap_or_default(),
77 h.map(|y| y + pos.y).unwrap_or_default(),
78 ) + RelRect::new(
79 0.0,
80 0.0,
81 if w.is_none() { UNSIZED_AXIS } else { 0.0 },
82 if h.is_none() { UNSIZED_AXIS } else { 0.0 },
83 ),
84 res,
85 size.unwrap_or_default().into(),
86 false,
87 )
88 };
89
90 #[cfg(feature = "png")]
91 {
92 let testimage = PathBuf::from("./premul_test.png");
93
94 children.push_back(Some(Box::new(genimage(
95 AbsPoint::new(0.0, 0.0),
96 Some(100.0),
97 Some(100.0),
98 &testimage,
99 None,
100 ))));
101
102 children.push_back(Some(Box::new(genimage(
103 AbsPoint::new(100.0, 0.0),
104 None,
105 Some(100.0),
106 &testimage,
107 None,
108 ))));
109
110 children.push_back(Some(Box::new(genimage(
111 AbsPoint::new(0.0, 100.0),
112 None,
113 None,
114 &testimage,
115 Some(AbsPoint::new(100.0, 100.0)),
116 ))));
117
118 children.push_back(Some(Box::new(genimage(
119 AbsPoint::new(100.0, 100.0),
120 None,
121 None,
122 &testimage,
123 None,
124 ))));
125 }
126
127 #[cfg(feature = "svg")]
128 {
129 let testsvg = PathBuf::from("./FRI_logo.svg");
130
131 children.push_back(Some(Box::new(genimage(
132 AbsPoint::new(200.0, 0.0),
133 Some(100.0),
134 Some(100.0),
135 &testsvg,
136 None,
137 ))));
138
139 children.push_back(Some(Box::new(genimage(
140 AbsPoint::new(300.0, 0.0),
141 None,
142 Some(100.0),
143 &testsvg,
144 None,
145 ))));
146
147 children.push_back(Some(Box::new(genimage(
148 AbsPoint::new(200.0, 100.0),
149 None,
150 None,
151 &testsvg,
152 Some(AbsPoint::new(100.0, 100.0)),
153 ))));
154
155 children.push_back(Some(Box::new(genimage(
156 AbsPoint::new(300.0, 100.0),
157 None,
158 None,
159 &testsvg,
160 None,
161 ))));
162 }
163
164 #[cfg(feature = "png")]
165 {
166 let testimage = PathBuf::from("./test_color.png");
167
168 children.push_back(Some(Box::new(genimage(
169 AbsPoint::new(0.0, 200.0),
170 Some(100.0),
171 Some(100.0),
172 &testimage,
173 None,
174 ))));
175
176 children.push_back(Some(Box::new(genimage(
177 AbsPoint::new(100.0, 200.0),
178 Some(100.0),
179 None,
180 &testimage,
181 None,
182 ))));
183
184 children.push_back(Some(Box::new(genimage(
185 AbsPoint::new(0.0, 300.0),
186 None,
187 None,
188 &testimage,
189 Some(AbsPoint::new(100.0, 100.0)),
190 ))));
191
192 children.push_back(Some(Box::new(genimage(
193 AbsPoint::new(100.0, 300.0),
194 None,
195 None,
196 &testimage,
197 None,
198 ))));
199 }
200
201 #[cfg(feature = "jxl")]
202 {
203 let testimage = PathBuf::from("./dice.jxl");
204
205 children.push_back(Some(Box::new(genimage(
206 AbsPoint::new(200.0, 200.0),
207 Some(100.0),
208 Some(100.0),
209 &testimage,
210 None,
211 ))));
212
213 children.push_back(Some(Box::new(genimage(
214 AbsPoint::new(300.0, 200.0),
215 Some(100.0),
216 None,
217 &testimage,
218 None,
219 ))));
220
221 children.push_back(Some(Box::new(genimage(
222 AbsPoint::new(200.0, 300.0),
223 None,
224 None,
225 &testimage,
226 Some(AbsPoint::new(100.0, 100.0)),
227 ))));
228
229 children.push_back(Some(Box::new(genimage(
230 AbsPoint::new(300.0, 300.0),
231 None,
232 None,
233 &testimage,
234 None,
235 ))));
236 }
237
238 let region = Region::new(
239 gen_id!(scope),
240 FixedData {
241 area: AbsRect::new(10.0, 10.0, -10.0, -10.0) + RelRect::new(0.0, 0.0, 1.0, 1.0),
242
243 zindex: 0,
244 ..Default::default()
245 },
246 children,
247 );
248
249 #[cfg(feature = "svg")]
250 let icon = Some(
251 feather_ui::resource::load_icon(&std::path::PathBuf::from("./FRI_logo.svg")).unwrap(),
252 );
253 #[cfg(not(feature = "svg"))]
254 let icon = None;
255
256 let window = Window::new(
257 gen_id!(scope),
258 winit::window::Window::default_attributes()
259 .with_title(env!("CARGO_CRATE_NAME"))
260 .with_resizable(true)
261 .with_window_icon(icon),
262 Box::new(region),
263 );
264
265 let mut store = im::HashMap::new();
266 store.insert(window.id.clone(), Some(window));
267 let windows = store.clone();
268 (store, windows)
269 }
Sourcepub fn scope(&mut self) -> ScopeID<'_>
pub fn scope(&mut self) -> ScopeID<'_>
Creates a new scoped ID with this scope as it’s parent that can then be passed into a function.
Sourcepub fn child(&mut self, id: DataID) -> Arc<SourceID>
pub fn child(&mut self, id: DataID) -> Arc<SourceID>
Creates a new unique SourceID using the provided DataID, which bypasses the internal counter.
This can be used to either manually create a new SourceID from a custom DataID by the user, or
by calling gen_id
, which calls this function internally.
Sourcepub fn iter<U: IntoIterator>(
&mut self,
other: U,
) -> ScopeIterID<'_, U::IntoIter> ⓘ
pub fn iter<U: IntoIterator>( &mut self, other: U, ) -> ScopeIterID<'_, U::IntoIter> ⓘ
Wraps another iterator and returns a pair of both a unique ID and the result of the iterator. Required for outline functions that use a for loop when iterating through data.
§Examples
use feather_ui::component::shape;
use feather_ui::{ScopeID, DRect, DAbsPoint, color::sRGB, FILL_DRECT };
fn foobar(count: usize, mut scope: ScopeID<'_>) {
for (i, id) in scope.iter(0..count) {
let _ = shape::round_rect::<DRect>(
id,
FILL_DRECT,
i as f32,
0.0,
wide::f32x4::splat(4.0),
sRGB::transparent(),
sRGB::transparent(),
DAbsPoint::zero(),
);
}
}
Examples found in repository?
59 fn call(
60 &mut self,
61 mut store: Self::Store,
62 args: GraphState,
63 mut scope: ScopeID<'_>,
64 ) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
65 if store.0 != args {
66 let mut children: im::Vector<Option<Box<ChildOf<dyn fixed::Prop>>>> = im::Vector::new();
67 let domain: Arc<CrossReferenceDomain> = Default::default();
68
69 let mut node_ids: Vec<Arc<SourceID>> = Vec::new();
70
71 for (i, id) in scope.iter(0..args.nodes.len()) {
72 let node = args.nodes[i];
73 const BASE: sRGB = sRGB::new(0.2, 0.7, 0.4, 1.0);
74
75 let point = DomainPoint::new(id, domain.clone());
76 node_ids.push(point.id.clone());
77
78 let circle = Shape::<DRect, { ShapeKind::Circle as u8 }>::new(
79 gen_id!(point.id),
80 FILL_DRECT,
81 0.0,
82 0.0,
83 [0.0, 20.0],
84 if args.selected == Some(i) {
85 sRGB::new(0.7, 1.0, 0.8, 1.0)
86 } else {
87 BASE
88 },
89 BASE,
90 DAbsPoint::zero(),
91 );
92
93 let bag = Region::<MinimalArea>::new(
94 gen_id!(point.id),
95 MinimalArea {
96 area: AbsRect::new(
97 node.x - NODE_RADIUS,
98 node.y - NODE_RADIUS,
99 node.x + NODE_RADIUS,
100 node.y + NODE_RADIUS,
101 )
102 .into(),
103 },
104 feather_ui::children![fixed::Prop, point, circle],
105 );
106
107 children.push_back(Some(Box::new(bag)));
108 }
109
110 for ((a, b), id) in scope.iter(&args.edges) {
111 let line = DomainLine::<()> {
112 id,
113 fill: sRGB::white(),
114 domain: domain.clone(),
115 start: node_ids[*a].clone(),
116 end: node_ids[*b].clone(),
117 props: ().into(),
118 };
119
120 children.push_back(Some(Box::new(line)));
121 }
122
123 let subregion = Region::new(
124 gen_id!(scope),
125 MinimalArea {
126 area: AbsRect::new(
127 args.offset.x,
128 args.offset.y,
129 args.offset.x + 10000.0,
130 args.offset.y + 10000.0,
131 )
132 .into(),
133 },
134 children,
135 );
136
137 let mousearea: MouseArea<MinimalArea> = MouseArea::new(
138 gen_id!(scope),
139 MinimalArea { area: FILL_DRECT },
140 Some(4.0),
141 [
142 Some(Slot(feather_ui::APP_SOURCE_ID.into(), 0)),
143 Some(Slot(feather_ui::APP_SOURCE_ID.into(), 0)),
144 Some(Slot(feather_ui::APP_SOURCE_ID.into(), 0)),
145 None,
146 None,
147 None,
148 ],
149 );
150
151 let region = Region::new(
152 gen_id!(scope),
153 MinimalArea { area: FILL_DRECT },
154 feather_ui::children![fixed::Prop, subregion, mousearea],
155 );
156
157 let window = Window::new(
158 gen_id!(scope),
159 feather_ui::winit::window::Window::default_attributes()
160 .with_title(env!("CARGO_CRATE_NAME"))
161 .with_resizable(true),
162 Box::new(region),
163 );
164
165 store.1 = im::HashMap::new();
166 store.1.insert(window.id.clone(), Some(window));
167 store.0 = args.clone();
168 }
169 let windows = store.1.clone();
170 (store, windows)
171 }
More examples
109 fn call(
110 &mut self,
111 mut store: Self::Store,
112 args: CounterState,
113 mut scope: ScopeID<'_>,
114 ) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
115 if store.0 != args {
116 let button = {
117 let text = {
118 Text::<FixedData> {
119 id: scope.create(),
120 props: FixedData {
121 area: AbsRect::new(10.0, 15.0, 10.0, 15.0)
122 + RelRect::new(0.0, 0.0, UNSIZED_AXIS, UNSIZED_AXIS),
123 anchor: feather_ui::RelPoint::zero().into(),
124 ..Default::default()
125 }
126 .into(),
127 text: format!("Boxes: {}", args.count),
128 font_size: 40.0,
129 line_height: 56.0,
130 ..Default::default()
131 }
132 };
133
134 let rect = Shape::<DRect, { ShapeKind::RoundRect as u8 }>::new(
135 scope.create(),
136 feather_ui::FILL_DRECT,
137 0.0,
138 0.0,
139 wide::f32x4::splat(10.0),
140 sRGB::new(0.2, 0.7, 0.4, 1.0),
141 sRGB::transparent(),
142 DAbsPoint::zero(),
143 );
144
145 Button::<FixedData>::new(
146 scope.create(),
147 FixedData {
148 area: AbsRect::new(0.0, 20.0, 0.0, 0.0)
149 + RelRect::new(0.5, 0.0, UNSIZED_AXIS, UNSIZED_AXIS),
150 anchor: feather_ui::RelPoint::new(0.5, 0.0).into(),
151 zindex: 0,
152 },
153 Slot(feather_ui::APP_SOURCE_ID.into(), 0),
154 feather_ui::children![fixed::Prop, rect, text],
155 )
156 };
157
158 const NUM_COLUMNS: usize = 5;
159 let rectgrid = {
160 let mut children: im::Vector<Option<Box<ChildOf<dyn grid::Prop>>>> =
161 im::Vector::new();
162 {
163 for (i, id) in scope.iter(0..args.count) {
164 children.push_back(Some(Box::new(Shape::<
165 GridChild,
166 { ShapeKind::RoundRect as u8 },
167 >::new(
168 id,
169 GridChild {
170 area: FILL_DRECT,
171 x: i % NUM_COLUMNS,
172 y: i / NUM_COLUMNS,
173 },
174 0.0,
175 0.0,
176 wide::f32x4::splat(4.0),
177 sRGB::new(
178 (0.1 * i as f32) % 1.0,
179 (0.65 * i as f32) % 1.0,
180 (0.2 * i as f32) % 1.0,
181 1.0,
182 ),
183 sRGB::transparent(),
184 DAbsPoint::zero(),
185 ))));
186 }
187 }
188
189 GridBox::<GridData>::new(
190 scope.create(),
191 GridData {
192 area: AbsRect::new(0.0, 200.0, 0.0, 0.0)
193 + RelRect::new(0.0, 0.0, UNSIZED_AXIS, 1.0),
194
195 rlimits: feather_ui::RelLimits::new(0.0..1.0, 0.0..),
196 direction: feather_ui::RowDirection::LeftToRight,
197 rows: [40.0, 20.0, 40.0, 20.0, 40.0, 20.0, 10.0]
198 .map(DValue::from)
199 .to_vec(),
200 columns: [80.0, 40.0, 80.0, 40.0, 80.0].map(DValue::from).to_vec(),
201 spacing: AbsPoint::new(4.0, 4.0).into(),
202 padding: AbsRect::new(8.0, 8.0, 8.0, 8.0).into(),
203 },
204 children,
205 )
206 };
207
208 let region = Region::new(
209 scope.create(),
210 FixedData {
211 area: FILL_DRECT,
212 zindex: 0,
213 ..Default::default()
214 },
215 feather_ui::children![fixed::Prop, button, rectgrid],
216 );
217 let window = Window::new(
218 scope.create(),
219 winit::window::Window::default_attributes()
220 .with_title(env!("CARGO_CRATE_NAME"))
221 .with_resizable(true),
222 Box::new(region),
223 );
224
225 store.1 = im::HashMap::new();
226 store.1.insert(window.id.clone(), Some(window));
227 store.0 = args.clone();
228 }
229 let windows = store.1.clone();
230 (store, windows)
231 }
132 fn call(
133 &mut self,
134 mut store: Self::Store,
135 args: CounterState,
136 mut scope: ScopeID<'_>,
137 ) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
138 if store.0 != args {
139 let button = {
140 let text = Text::<FixedData> {
141 id: gen_id!(scope),
142 props: FixedData {
143 area: AbsRect::new(10.0, 15.0, 10.0, 15.0)
144 + RelRect::new(0.0, 0.0, UNSIZED_AXIS, UNSIZED_AXIS),
145
146 anchor: feather_ui::RelPoint::new(0.0, 0.0).into(),
147 ..Default::default()
148 }
149 .into(),
150 text: format!("Boxes: {}", args.count),
151 font_size: 40.0,
152 line_height: 56.0,
153 ..Default::default()
154 };
155
156 let rect = Shape::<DRect, { ShapeKind::RoundRect as u8 }>::new(
157 gen_id!(scope),
158 feather_ui::FILL_DRECT,
159 0.0,
160 0.0,
161 wide::f32x4::splat(10.0),
162 sRGB::new(0.2, 0.7, 0.4, 1.0),
163 sRGB::transparent(),
164 DAbsPoint::zero(),
165 );
166
167 Button::<FixedData>::new(
168 gen_id!(scope),
169 FixedData {
170 area: AbsRect::new(0.0, 20.0, 0.0, 0.0)
171 + RelRect::new(0.5, 0.0, UNSIZED_AXIS, UNSIZED_AXIS),
172
173 anchor: feather_ui::RelPoint::new(0.5, 0.0).into(),
174 zindex: 0,
175 },
176 Slot(feather_ui::APP_SOURCE_ID.into(), 0),
177 feather_ui::children![fixed::Prop, rect, text],
178 )
179 };
180
181 let rectlist = {
182 let mut children: im::Vector<Option<Box<ChildOf<dyn list::Prop>>>> =
183 im::Vector::new();
184
185 for (i, id) in scope.iter(0..args.count) {
186 children.push_back(Some(Box::new(Shape::<
187 ListChild,
188 { ShapeKind::RoundRect as u8 },
189 >::new(
190 id,
191 ListChild {
192 area: AbsRect::new(0.0, 0.0, 40.0, 40.0).into(),
193 margin: AbsRect::new(8.0, 8.0, 4.0, 4.0).into(),
194 },
195 0.0,
196 0.0,
197 wide::f32x4::splat(8.0),
198 sRGB::new(
199 (0.1 * i as f32) % 1.0,
200 (0.65 * i as f32) % 1.0,
201 (0.2 * i as f32) % 1.0,
202 1.0,
203 ),
204 sRGB::transparent(),
205 DAbsPoint::zero(),
206 ))));
207 }
208
209 ListBox::<ListData>::new(
210 gen_id!(scope),
211 ListData {
212 area: AbsRect::new(0.0, 200.0, 0.0, 0.0)
213 + RelRect::new(0.0, 0.0, UNSIZED_AXIS, 1.0),
214
215 rlimits: feather_ui::RelLimits::new(0.0..1.0, 0.0..),
216 direction: feather_ui::RowDirection::BottomToTop,
217 },
218 children,
219 )
220 };
221
222 let flexlist = {
223 let mut children: im::Vector<Option<Box<ChildOf<dyn flex::Prop>>>> =
224 im::Vector::new();
225
226 for (i, id) in scope.iter(0..args.count) {
227 let rect = Shape::<FlexChild, { ShapeKind::RoundRect as u8 }>::new(
228 gen_id!(id),
229 FlexChild {
230 area: AbsRect::new(0.0, 0.0, 0.0, 40.0)
231 + RelRect::new(0.0, 0.0, 1.0, 0.0),
232
233 margin: AbsRect::new(8.0, 8.0, 4.0, 4.0).into(),
234 basis: 40.0.into(),
235 grow: 0.0,
236 shrink: 0.0,
237 },
238 0.0,
239 0.0,
240 wide::f32x4::splat(8.0),
241 sRGB::new(
242 (0.1 * i as f32) % 1.0,
243 (0.65 * i as f32) % 1.0,
244 (0.2 * i as f32) % 1.0,
245 1.0,
246 ),
247 sRGB::transparent(),
248 DAbsPoint::zero(),
249 );
250
251 // We include a "useless" region around the rectangle because this catches some edge cases
252 // in the layout logic.
253 let reg = Region::<FlexChild>::new(
254 id,
255 FlexChild {
256 area: AbsRect::new(0.0, 0.0, 0.0, 40.0)
257 + RelRect::new(0.0, 0.0, 1.0, 0.0),
258
259 margin: AbsRect::new(8.0, 8.0, 4.0, 4.0).into(),
260 basis: 40.0.into(),
261 grow: 0.0,
262 shrink: 0.0,
263 },
264 feather_ui::children![fixed::Prop, rect],
265 );
266
267 children.push_back(Some(Box::new(reg)));
268 }
269
270 FlexBox::<MinimalFlex>::new(
271 gen_id!(scope),
272 MinimalFlex {
273 area: (AbsRect::new(40.0, 40.0, 0.0, 200.0)
274 + RelRect::new(0.0, 0.0, 1.0, 0.0)),
275 },
276 children,
277 )
278 };
279
280 let region = Region::new(
281 gen_id!(scope),
282 FixedData {
283 area: FILL_DRECT,
284 zindex: 0,
285 ..Default::default()
286 },
287 feather_ui::children![fixed::Prop, button, flexlist, rectlist],
288 );
289 let window = Window::new(
290 gen_id!(scope),
291 feather_ui::winit::window::Window::default_attributes()
292 .with_title(env!("CARGO_CRATE_NAME"))
293 .with_resizable(true),
294 Box::new(region),
295 );
296
297 store.1 = im::HashMap::new();
298 store.1.insert(window.id.clone(), Some(window));
299 store.0 = args.clone();
300 }
301 let windows = store.1.clone();
302 (store, windows)
303 }
Sourcepub fn cond<R>(
&mut self,
condition: bool,
tvalue: impl FnOnce(ScopeID<'_>) -> R,
fvalue: impl FnOnce(ScopeID<'_>) -> R,
) -> R
pub fn cond<R>( &mut self, condition: bool, tvalue: impl FnOnce(ScopeID<'_>) -> R, fvalue: impl FnOnce(ScopeID<'_>) -> R, ) -> R
Wraps the true and false branches of a condition, ensuring the IDs for both are maintained seperately regardless of which branch is picked.
§Examples
use feather_ui::component::{shape, ComponentWrap, text::Text};
use feather_ui::{ScopeID, DRect, DAbsPoint, color::sRGB, FILL_DRECT };
fn foobar(cond: bool, mut scope: ScopeID<'_>) {
let _ = scope.cond::<Box<dyn ComponentWrap<dyn feather_ui::layout::base::Empty>>>(
cond,
|mut id: ScopeID<'_>| Box::new(shape::round_rect::<DRect>(
id.create(),
FILL_DRECT,
0.0,
0.0,
wide::f32x4::splat(4.0),
sRGB::transparent(),
sRGB::transparent(),
DAbsPoint::zero(),
)),
|mut id: ScopeID<'_>| {
Box::new(Text::<DRect> {
id: id.create(),
props: FILL_DRECT.into(),
text: "Foobar".to_string(),
font_size: 40.0,
line_height: 56.0,
..Default::default()
})
});
}
Trait Implementations§
Auto Trait Implementations§
impl<'a> Freeze for ScopeID<'a>
impl<'a> !RefUnwindSafe for ScopeID<'a>
impl<'a> Send for ScopeID<'a>
impl<'a> Sync for ScopeID<'a>
impl<'a> Unpin for ScopeID<'a>
impl<'a> !UnwindSafe for ScopeID<'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
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>
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>
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)
&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)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more