Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-core/src/elements/stack/positioned.rs
StratoSDK / crates / strato-ui-core / src / elements / stack / positioned.rs
1use pathfinder_geometry::rect::RectF;
2use pathfinder_geometry::vector::Vector2F;
3use std::any::Any;
4 
5use super::OffsetPositioning;
6use crate::elements::Selection;
7use crate::{
8 elements::{Point, SelectableElement, SelectionFragment},
9 event::DispatchedEvent,
10 text::{word_boundaries::WordBoundariesPolicy, IsRect, SelectionDirection, SelectionType},
11 AfterLayoutContext, AppContext, Element, EventContext, LayoutContext, PaintContext,
12 SizeConstraint,
13};
14 
15pub(super) struct Positioned {
16 child: Box<dyn Element>,
17 parent_data: OffsetPositioning,
18}
19 
20impl Positioned {
21 pub(super) fn new(child: Box<dyn Element>) -> Self {
22 Self {
23 child,
24 parent_data: OffsetPositioning::default(),
25 }
26 }
27 
28 pub(super) fn with_offset(mut self, positioning: OffsetPositioning) -> Self {
29 self.parent_data = positioning;
30 self
31 }
32}
33 
34impl Element for Positioned {
35 fn layout(
36 &mut self,
37 constraint: SizeConstraint,
38 ctx: &mut LayoutContext,
39 app: &AppContext,
40 ) -> Vector2F {
41 self.child.layout(constraint, ctx, app)
42 }
43 
44 fn after_layout(&mut self, ctx: &mut AfterLayoutContext, app: &AppContext) {
45 self.child.after_layout(ctx, app);
46 }
47 
48 fn paint(&mut self, origin: Vector2F, ctx: &mut PaintContext, app: &AppContext) {
49 self.child.paint(origin, ctx, app);
50 }
51 
52 fn dispatch_event(
53 &mut self,
54 event: &DispatchedEvent,
55 ctx: &mut EventContext,
56 app: &AppContext,
57 ) -> bool {
58 self.child.dispatch_event(event, ctx, app)
59 }
60 
61 fn size(&self) -> Option<Vector2F> {
62 self.child.size()
63 }
64 
65 fn parent_data(&self) -> Option<&dyn Any> {
66 Some(&self.parent_data)
67 }
68 
69 fn origin(&self) -> Option<Point> {
70 self.child.origin()
71 }
72 
73 fn as_selectable_element(&self) -> Option<&dyn SelectableElement> {
74 Some(self as &dyn SelectableElement)
75 }
76}
77 
78impl SelectableElement for Positioned {
79 fn get_selection(
80 &self,
81 selection_start: Vector2F,
82 selection_end: Vector2F,
83 is_rect: IsRect,
84 ) -> Option<Vec<SelectionFragment>> {
85 self.child
86 .as_selectable_element()
87 .and_then(|selectable_child| {
88 selectable_child.get_selection(selection_start, selection_end, is_rect)
89 })
90 }
91 
92 fn expand_selection(
93 &self,
94 point: Vector2F,
95 direction: SelectionDirection,
96 unit: SelectionType,
97 word_boundaries_policy: &WordBoundariesPolicy,
98 ) -> Option<Vector2F> {
99 self.child
100 .as_selectable_element()
101 .and_then(|selectable_child| {
102 selectable_child.expand_selection(point, direction, unit, word_boundaries_policy)
103 })
104 }
105 
106 fn is_point_semantically_before(
107 &self,
108 absolute_point: Vector2F,
109 absolute_point_other: Vector2F,
110 ) -> Option<bool> {
111 self.child
112 .as_selectable_element()
113 .and_then(|selectable_child| {
114 selectable_child.is_point_semantically_before(absolute_point, absolute_point_other)
115 })
116 }
117 
118 fn smart_select(
119 &self,
120 absolute_point: Vector2F,
121 smart_select_fn: crate::elements::SmartSelectFn,
122 ) -> Option<(Vector2F, Vector2F)> {
123 self.child
124 .as_selectable_element()
125 .and_then(|selectable_child| {
126 selectable_child.smart_select(absolute_point, smart_select_fn)
127 })
128 }
129 
130 fn calculate_clickable_bounds(&self, current_selection: Option<Selection>) -> Vec<RectF> {
131 self.child
132 .as_selectable_element()
133 .map(|selectable_child| selectable_child.calculate_clickable_bounds(current_selection))
134 .unwrap_or_default()
135 }
136}
137