1use crate::layout_management::{CotisLayoutManager, CotisLayoutRun};
37use crate::layout_struct::RenderCommandOutput;
38use crate::layout_struct::info_types::{ClipElement, FloatingElementConfig, FloatingElementStyle};
39use crate::layout_struct::layout_states::{ChildWrapping, LayoutElementConfig, LayoutElementStyle};
40use crate::layout_traits::CotisLayoutCompatible;
41use cotis::element_configuring::{
42 ConfigureElements, ConfigureLeafElements, ConfiguredParentElement, Seal,
43};
44use cotis::layout::{LayoutFrameManager, LayoutManager, LayoutManagerCompatible};
45use cotis::utils::{ElementId, ElementIdConfig};
46use cotis::utils::{OwnedOrRef, OwnedOrRefMut};
47use cotis_defaults::element_configs::ElementConfig;
48use cotis_defaults::element_configs::style::CotisStyle;
49use cotis_defaults::element_configs::style::sizing::{AxisSizing, DoubleAxisSizing, Sizing};
50use cotis_defaults::element_configs::style::types::LayoutDirection;
51use cotis_defaults::element_configs::text_config::{TextConfig, TextElementConfig};
52use cotis_utils::text::{LayoutTextMeasuring, RendererTextMeasuringProvider};
53use cotis_utils::traits::CotisWindowContext;
54use std::sync::Arc;
55
56pub mod secondary_traits;
57
58impl<Renderer: CotisWindowContext + RendererTextMeasuringProvider<TextConfig>>
59 LayoutManagerCompatible<Renderer> for CotisLayoutManager
60{
61 fn init(&mut self, renderer: &mut Renderer) {
62 self.set_text_measuring_function(renderer.provide_measurer());
63 }
64 fn prepare(&mut self, render: &Renderer) {
65 self.set_dimensions(render.window_dimensions());
66 }
67}
68
69impl<'frame, T> LayoutManager<'frame, T, RenderCommandOutput<T>> for CotisLayoutManager
70where
71 T: CotisLayoutCompatible<'frame> + 'frame,
72{
73 type ElementConfigurer<'layout>
74 = CotisLayoutRun<'layout, T>
75 where
76 Self: 'layout;
77
78 fn begin_frame<'layout>(
79 &'layout mut self,
80 ) -> impl LayoutFrameManager<'frame, T, RenderCommandOutput<T>, Self::ElementConfigurer<'layout>>
81 where
82 T: 'frame,
83 RenderCommandOutput<T>: 'frame,
84 Self: 'layout,
85 {
86 CotisLayoutRun::new(self)
87 }
88}
89
90impl<'frame, T> LayoutFrameManager<'frame, T, RenderCommandOutput<T>, Self>
91 for CotisLayoutRun<'_, T>
92where
93 T: CotisLayoutCompatible<'frame> + 'frame,
94{
95 fn begin(&'_ mut self) -> ConfiguredParentElement<'_, Self, T> {
96 ConfiguredParentElement::new(OwnedOrRefMut::Ref(self))
97 }
98
99 fn end(mut self) -> impl Iterator<Item = RenderCommandOutput<T>> {
100 self.finalize_layouts().into_iter()
101 }
102}
103
104impl<'frame, I, C, E> CotisLayoutCompatible<'frame>
105 for ElementConfig<'frame, DoubleAxisSizing, I, C, E>
106{
107 fn get_style(&self) -> LayoutElementConfig {
108 (&self.style).into()
109 }
110
111 fn get_id(&self) -> ElementId {
112 self.id_config.get_handle()
113 }
114
115 fn try_get_name(&self) -> Option<OwnedOrRef<'frame, str>> {
116 self.id_config
117 .get_id_name()
118 .map(|name| OwnedOrRef::AsOwnedRef(Arc::new(name.to_string())))
119 }
120}
121
122impl<'frame, I, C, E> CotisLayoutCompatible<'frame> for ElementConfig<'frame, Sizing, I, C, E> {
123 fn get_style(&self) -> LayoutElementConfig {
124 (&self.style).into()
125 }
126
127 fn get_id(&self) -> ElementId {
128 self.id_config.get_handle()
129 }
130
131 fn try_get_name(&self) -> Option<OwnedOrRef<'frame, str>> {
132 self.id_config
133 .get_id_name()
134 .map(|name| OwnedOrRef::AsOwnedRef(Arc::new(name.to_string())))
135 }
136}
137
138impl<'name, T> ConfigureElements<T> for CotisLayoutRun<'_, T>
139where
140 T: CotisLayoutCompatible<'name>,
141{
142 fn open_new_element(&mut self, _: Seal) {
143 self.new_child_element();
144 }
145
146 fn set_config(&mut self, config: T, _: Seal) {
147 let style = config.get_style();
148 let id = config.get_id();
149 let name = config.try_get_name();
150 self.set_open_element_config(style, id, name, config);
151 }
152
153 fn close_element(&mut self, _: Seal) {
154 self.close_open_element();
155 }
156}
157
158impl<'frame, I, C, E> crate::preamble::TextConfigurable for ElementConfig<'frame, Sizing, I, C, E> {
159 fn synthetic_text_child(
160 &self,
161 layout_direction: LayoutDirection,
162 child_gap: f32,
163 width: AxisSizing,
164 height: AxisSizing,
165 ) -> Self {
166 #[allow(clippy::clone_on_copy)] let mut style = self.style.clone();
168 crate::text::text_leafs::reset_text_child_style(&mut style, layout_direction, child_gap);
169 style.sizing = Sizing::DoubleAxis(DoubleAxisSizing { width, height });
170
171 ElementConfig {
172 id_config: ElementIdConfig::new_empty(),
173 style,
174 image: None,
175 custom: None,
176 extra_data: None,
177 }
178 }
179}
180
181impl<'frame, I, C, E> crate::preamble::TextConfigurable
182 for ElementConfig<'frame, DoubleAxisSizing, I, C, E>
183{
184 fn synthetic_text_child(
185 &self,
186 layout_direction: LayoutDirection,
187 child_gap: f32,
188 width: AxisSizing,
189 height: AxisSizing,
190 ) -> Self {
191 #[allow(clippy::clone_on_copy)] let mut style = self.style.clone();
193 crate::text::text_leafs::reset_text_child_style(&mut style, layout_direction, child_gap);
194 style.sizing = DoubleAxisSizing { width, height };
195
196 ElementConfig {
197 id_config: ElementIdConfig::new_empty(),
198 style,
199 image: None,
200 custom: None,
201 extra_data: None,
202 }
203 }
204}
205
206impl<'frame, I, C, E: 'frame + Sync + Send> ConfigureLeafElements<TextElementConfig<'frame>>
207 for CotisLayoutRun<'_, ElementConfig<'frame, Sizing, I, C, E>>
208{
209 fn set_leaf_config(&mut self, leaf: TextElementConfig<'frame>, _: Seal) {
210 self.apply_text_leaf(leaf);
211 }
212}
213
214impl<'frame, I, C, E: 'frame + Sync + Send> ConfigureLeafElements<TextElementConfig<'frame>>
215 for CotisLayoutRun<'_, ElementConfig<'frame, DoubleAxisSizing, I, C, E>>
216{
217 fn set_leaf_config(&mut self, leaf: TextElementConfig<'frame>, _: Seal) {
218 self.apply_text_leaf(leaf);
219 }
220}
221
222impl From<&CotisStyle<Sizing>> for LayoutElementConfig {
223 fn from(value: &CotisStyle<Sizing>) -> Self {
224 LayoutElementConfig {
225 layout: LayoutElementStyle {
226 sizing: value.sizing,
227 padding: value.layout.padding,
228 child_gap: value.layout.child_gap,
229 child_alignment: value.layout.child_alignment,
230 layout_direction: value.layout.layout_direction,
231 wrapping: ChildWrapping::None,
232 },
233 floating: FloatingElementStyle {
234 config: value.floating.map(|value| FloatingElementConfig {
235 offset: value.offset,
236 expand: value.expand,
237 attach_point: value.attach_point,
238 pointer_capture_mode: value.pointer_capture_mode,
239 }),
240 z_index: value.floating.map(|f| f.z_index).unwrap_or(0) as i32,
241 },
242 clip: ClipElement {
243 horizontal: value.clip.horizontal,
244 vertical: value.clip.vertical,
245 offset: value.clip.child_offset,
246 },
247 }
248 }
249}
250
251impl From<&CotisStyle<DoubleAxisSizing>> for LayoutElementConfig {
252 fn from(value: &CotisStyle<DoubleAxisSizing>) -> Self {
253 LayoutElementConfig {
254 layout: LayoutElementStyle {
255 sizing: Sizing::DoubleAxis(value.sizing),
256 padding: value.layout.padding,
257 child_gap: value.layout.child_gap,
258 child_alignment: value.layout.child_alignment,
259 layout_direction: value.layout.layout_direction,
260 wrapping: ChildWrapping::None,
261 },
262 floating: FloatingElementStyle {
263 config: value.floating.map(|value| FloatingElementConfig {
264 offset: value.offset,
265 expand: value.expand,
266 attach_point: value.attach_point,
267 pointer_capture_mode: value.pointer_capture_mode,
268 }),
269 z_index: value.floating.map(|f| f.z_index).unwrap_or(0) as i32,
270 },
271 clip: ClipElement {
272 horizontal: value.clip.horizontal,
273 vertical: value.clip.vertical,
274 offset: value.clip.child_offset,
275 },
276 }
277 }
278}