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 let mut style = self.style.clone();
167 crate::text::text_leafs::reset_text_child_style(&mut style, layout_direction, child_gap);
168 style.sizing = Sizing::DoubleAxis(DoubleAxisSizing { width, height });
169
170 ElementConfig {
171 id_config: ElementIdConfig::new_empty(),
172 style,
173 image: None,
174 custom: None,
175 extra_data: None,
176 }
177 }
178}
179
180impl<'frame, I, C, E> crate::preamble::TextConfigurable
181 for ElementConfig<'frame, DoubleAxisSizing, I, C, E>
182{
183 fn synthetic_text_child(
184 &self,
185 layout_direction: LayoutDirection,
186 child_gap: f32,
187 width: AxisSizing,
188 height: AxisSizing,
189 ) -> Self {
190 let mut style = self.style.clone();
191 crate::text::text_leafs::reset_text_child_style(&mut style, layout_direction, child_gap);
192 style.sizing = DoubleAxisSizing { width, height };
193
194 ElementConfig {
195 id_config: ElementIdConfig::new_empty(),
196 style,
197 image: None,
198 custom: None,
199 extra_data: None,
200 }
201 }
202}
203
204impl<'frame, I, C, E: 'frame + Sync + Send> ConfigureLeafElements<TextElementConfig<'frame>>
205 for CotisLayoutRun<'_, ElementConfig<'frame, Sizing, I, C, E>>
206{
207 fn set_leaf_config(&mut self, leaf: TextElementConfig<'frame>, _: Seal) {
208 self.apply_text_leaf(leaf);
209 }
210}
211
212impl<'frame, I, C, E: 'frame + Sync + Send> ConfigureLeafElements<TextElementConfig<'frame>>
213 for CotisLayoutRun<'_, ElementConfig<'frame, DoubleAxisSizing, I, C, E>>
214{
215 fn set_leaf_config(&mut self, leaf: TextElementConfig<'frame>, _: Seal) {
216 self.apply_text_leaf(leaf);
217 }
218}
219
220impl From<&CotisStyle<Sizing>> for LayoutElementConfig {
221 fn from(value: &CotisStyle<Sizing>) -> Self {
222 LayoutElementConfig {
223 layout: LayoutElementStyle {
224 sizing: value.sizing,
225 padding: value.layout.padding,
226 child_gap: value.layout.child_gap,
227 child_alignment: value.layout.child_alignment,
228 layout_direction: value.layout.layout_direction,
229 wrapping: ChildWrapping::None,
230 },
231 floating: FloatingElementStyle {
232 config: value.floating.map(|value| FloatingElementConfig {
233 offset: value.offset,
234 expand: value.expand,
235 attach_point: value.attach_point,
236 pointer_capture_mode: value.pointer_capture_mode,
237 }),
238 z_index: value.floating.map(|f| f.z_index).unwrap_or(0) as i32,
239 },
240 clip: ClipElement {
241 horizontal: value.clip.horizontal,
242 vertical: value.clip.vertical,
243 offset: value.clip.child_offset,
244 },
245 }
246 }
247}
248
249impl From<&CotisStyle<DoubleAxisSizing>> for LayoutElementConfig {
250 fn from(value: &CotisStyle<DoubleAxisSizing>) -> Self {
251 LayoutElementConfig {
252 layout: LayoutElementStyle {
253 sizing: Sizing::DoubleAxis(value.sizing),
254 padding: value.layout.padding,
255 child_gap: value.layout.child_gap,
256 child_alignment: value.layout.child_alignment,
257 layout_direction: value.layout.layout_direction,
258 wrapping: ChildWrapping::None,
259 },
260 floating: FloatingElementStyle {
261 config: value.floating.map(|value| FloatingElementConfig {
262 offset: value.offset,
263 expand: value.expand,
264 attach_point: value.attach_point,
265 pointer_capture_mode: value.pointer_capture_mode,
266 }),
267 z_index: value.floating.map(|f| f.z_index).unwrap_or(0) as i32,
268 },
269 clip: ClipElement {
270 horizontal: value.clip.horizontal,
271 vertical: value.clip.vertical,
272 offset: value.clip.child_offset,
273 },
274 }
275 }
276}