use crate::layout_management::{CotisLayoutManager, CotisLayoutRun};
use crate::layout_struct::RenderCommandOutput;
use crate::layout_struct::info_types::{ClipElement, FloatingElementConfig, FloatingElementStyle};
use crate::layout_struct::layout_states::{ChildWrapping, LayoutElementConfig, LayoutElementStyle};
use crate::layout_traits::CotisLayoutCompatible;
use cotis::element_configuring::{
ConfigureElements, ConfigureLeafElements, ConfiguredParentElement, Seal,
};
use cotis::layout::{LayoutFrameManager, LayoutManager, LayoutManagerCompatible};
use cotis::utils::{ElementId, ElementIdConfig};
use cotis::utils::{OwnedOrRef, OwnedOrRefMut};
use cotis_defaults::element_configs::ElementConfig;
use cotis_defaults::element_configs::style::CotisStyle;
use cotis_defaults::element_configs::style::sizing::{AxisSizing, DoubleAxisSizing, Sizing};
use cotis_defaults::element_configs::style::types::LayoutDirection;
use cotis_defaults::element_configs::text_config::{TextConfig, TextElementConfig};
use cotis_utils::text::{LayoutTextMeasuring, RendererTextMeasuringProvider};
use cotis_utils::traits::CotisWindowContext;
use std::sync::Arc;
pub mod secondary_traits;
impl<Renderer: CotisWindowContext + RendererTextMeasuringProvider<TextConfig>>
LayoutManagerCompatible<Renderer> for CotisLayoutManager
{
fn init(&mut self, renderer: &mut Renderer) {
self.set_text_measuring_function(renderer.provide_measurer());
}
fn prepare(&mut self, render: &Renderer) {
self.set_dimensions(render.window_dimensions());
}
}
impl<'frame, T> LayoutManager<'frame, T, RenderCommandOutput<T>> for CotisLayoutManager
where
T: CotisLayoutCompatible<'frame> + 'frame,
{
type ElementConfigurer<'layout>
= CotisLayoutRun<'layout, T>
where
Self: 'layout;
fn begin_frame<'layout>(
&'layout mut self,
) -> impl LayoutFrameManager<'frame, T, RenderCommandOutput<T>, Self::ElementConfigurer<'layout>>
where
T: 'frame,
RenderCommandOutput<T>: 'frame,
Self: 'layout,
{
CotisLayoutRun::new(self)
}
}
impl<'frame, T> LayoutFrameManager<'frame, T, RenderCommandOutput<T>, Self>
for CotisLayoutRun<'_, T>
where
T: CotisLayoutCompatible<'frame> + 'frame,
{
fn begin(&'_ mut self) -> ConfiguredParentElement<'_, Self, T> {
ConfiguredParentElement::new(OwnedOrRefMut::Ref(self))
}
fn end(mut self) -> impl Iterator<Item = RenderCommandOutput<T>> {
self.finalize_layouts().into_iter()
}
}
impl<'frame, I, C, E> CotisLayoutCompatible<'frame>
for ElementConfig<'frame, DoubleAxisSizing, I, C, E>
{
fn get_style(&self) -> LayoutElementConfig {
(&self.style).into()
}
fn get_id(&self) -> ElementId {
self.id_config.get_handle()
}
fn try_get_name(&self) -> Option<OwnedOrRef<'frame, str>> {
self.id_config
.get_id_name()
.map(|name| OwnedOrRef::AsOwnedRef(Arc::new(name.to_string())))
}
}
impl<'frame, I, C, E> CotisLayoutCompatible<'frame> for ElementConfig<'frame, Sizing, I, C, E> {
fn get_style(&self) -> LayoutElementConfig {
(&self.style).into()
}
fn get_id(&self) -> ElementId {
self.id_config.get_handle()
}
fn try_get_name(&self) -> Option<OwnedOrRef<'frame, str>> {
self.id_config
.get_id_name()
.map(|name| OwnedOrRef::AsOwnedRef(Arc::new(name.to_string())))
}
}
impl<'name, T> ConfigureElements<T> for CotisLayoutRun<'_, T>
where
T: CotisLayoutCompatible<'name>,
{
fn open_new_element(&mut self, _: Seal) {
self.new_child_element();
}
fn set_config(&mut self, config: T, _: Seal) {
let style = config.get_style();
let id = config.get_id();
let name = config.try_get_name();
self.set_open_element_config(style, id, name, config);
}
fn close_element(&mut self, _: Seal) {
self.close_open_element();
}
}
impl<'frame, I, C, E> crate::preamble::TextConfigurable for ElementConfig<'frame, Sizing, I, C, E> {
fn synthetic_text_child(
&self,
layout_direction: LayoutDirection,
child_gap: f32,
width: AxisSizing,
height: AxisSizing,
) -> Self {
#[allow(clippy::clone_on_copy)] let mut style = self.style.clone();
crate::text::text_leafs::reset_text_child_style(&mut style, layout_direction, child_gap);
style.sizing = Sizing::DoubleAxis(DoubleAxisSizing { width, height });
ElementConfig {
id_config: ElementIdConfig::new_empty(),
style,
image: None,
custom: None,
extra_data: None,
}
}
}
impl<'frame, I, C, E> crate::preamble::TextConfigurable
for ElementConfig<'frame, DoubleAxisSizing, I, C, E>
{
fn synthetic_text_child(
&self,
layout_direction: LayoutDirection,
child_gap: f32,
width: AxisSizing,
height: AxisSizing,
) -> Self {
#[allow(clippy::clone_on_copy)] let mut style = self.style.clone();
crate::text::text_leafs::reset_text_child_style(&mut style, layout_direction, child_gap);
style.sizing = DoubleAxisSizing { width, height };
ElementConfig {
id_config: ElementIdConfig::new_empty(),
style,
image: None,
custom: None,
extra_data: None,
}
}
}
impl<'frame, I, C, E: 'frame + Sync + Send> ConfigureLeafElements<TextElementConfig<'frame>>
for CotisLayoutRun<'_, ElementConfig<'frame, Sizing, I, C, E>>
{
fn set_leaf_config(&mut self, leaf: TextElementConfig<'frame>, _: Seal) {
self.apply_text_leaf(leaf);
}
}
impl<'frame, I, C, E: 'frame + Sync + Send> ConfigureLeafElements<TextElementConfig<'frame>>
for CotisLayoutRun<'_, ElementConfig<'frame, DoubleAxisSizing, I, C, E>>
{
fn set_leaf_config(&mut self, leaf: TextElementConfig<'frame>, _: Seal) {
self.apply_text_leaf(leaf);
}
}
impl From<&CotisStyle<Sizing>> for LayoutElementConfig {
fn from(value: &CotisStyle<Sizing>) -> Self {
LayoutElementConfig {
layout: LayoutElementStyle {
sizing: value.sizing,
padding: value.layout.padding,
child_gap: value.layout.child_gap,
child_alignment: value.layout.child_alignment,
layout_direction: value.layout.layout_direction,
wrapping: ChildWrapping::None,
},
floating: FloatingElementStyle {
config: value.floating.map(|value| FloatingElementConfig {
offset: value.offset,
expand: value.expand,
attach_point: value.attach_point,
pointer_capture_mode: value.pointer_capture_mode,
}),
z_index: value.floating.map(|f| f.z_index).unwrap_or(0) as i32,
},
clip: ClipElement {
horizontal: value.clip.horizontal,
vertical: value.clip.vertical,
offset: value.clip.child_offset,
},
}
}
}
impl From<&CotisStyle<DoubleAxisSizing>> for LayoutElementConfig {
fn from(value: &CotisStyle<DoubleAxisSizing>) -> Self {
LayoutElementConfig {
layout: LayoutElementStyle {
sizing: Sizing::DoubleAxis(value.sizing),
padding: value.layout.padding,
child_gap: value.layout.child_gap,
child_alignment: value.layout.child_alignment,
layout_direction: value.layout.layout_direction,
wrapping: ChildWrapping::None,
},
floating: FloatingElementStyle {
config: value.floating.map(|value| FloatingElementConfig {
offset: value.offset,
expand: value.expand,
attach_point: value.attach_point,
pointer_capture_mode: value.pointer_capture_mode,
}),
z_index: value.floating.map(|f| f.z_index).unwrap_or(0) as i32,
},
clip: ClipElement {
horizontal: value.clip.horizontal,
vertical: value.clip.vertical,
offset: value.clip.child_offset,
},
}
}
}