cranpose_ui/modifier/
z_index.rs1use std::hash::{Hash, Hasher};
2
3use cranpose_foundation::{
4 DelegatableNode, InvalidationKind, ModifierNode, ModifierNodeContext, ModifierNodeElement,
5 NodeCapabilities, NodeState,
6};
7
8use super::{Modifier, inspector_metadata};
9
10impl Modifier {
11 pub fn z_index(self, z_index: f32) -> Self {
21 let modifier = Self::with_element(ZIndexElement { z_index }).with_inspector_metadata(
22 inspector_metadata("zIndex", move |info| {
23 info.add_property("zIndex", z_index.to_string());
24 }),
25 );
26 self.then(modifier)
27 }
28}
29
30pub fn z_index_in_use() -> bool {
34 crate::thread_state::cells(|cells| cells.z_index_nodes.get()) > 0
35}
36
37fn count_z_index_node(attached: bool) {
38 crate::thread_state::cells(|cells| {
39 let nodes = &cells.z_index_nodes;
40 nodes.set(if attached {
41 nodes.get() + 1
42 } else {
43 nodes.get().saturating_sub(1)
44 });
45 });
46}
47
48#[derive(Debug, Clone, PartialEq)]
49pub(crate) struct ZIndexElement {
50 z_index: f32,
51}
52
53impl Hash for ZIndexElement {
54 fn hash<H: Hasher>(&self, state: &mut H) {
55 state.write_u32(self.z_index.to_bits());
56 }
57}
58
59impl ModifierNodeElement for ZIndexElement {
60 type Node = ZIndexNode;
61
62 fn create(&self) -> Self::Node {
63 ZIndexNode {
64 z_index: self.z_index,
65 owner: None,
66 state: NodeState::new(),
67 }
68 }
69
70 fn update(&self, node: &mut Self::Node) {
71 if node.z_index.to_bits() != self.z_index.to_bits() {
72 node.z_index = self.z_index;
73 node.reorder();
74 }
75 }
76
77 fn capabilities(&self) -> NodeCapabilities {
78 NodeCapabilities::DRAW
79 }
80}
81
82pub(crate) struct ZIndexNode {
85 z_index: f32,
86 owner: Option<cranpose_core::NodeId>,
88 state: NodeState,
89}
90
91impl ZIndexNode {
92 pub(crate) fn z_index(&self) -> f32 {
93 self.z_index
94 }
95
96 fn reorder(&self) {
99 if let Some(owner) = self.owner {
100 crate::schedule_z_order_change(owner);
101 }
102 }
103}
104
105impl DelegatableNode for ZIndexNode {
106 fn node_state(&self) -> &NodeState {
107 &self.state
108 }
109}
110
111impl ModifierNode for ZIndexNode {
112 fn on_attach(&mut self, context: &mut dyn ModifierNodeContext) {
113 context.invalidate(InvalidationKind::Draw);
114 count_z_index_node(true);
115 self.owner = context.node_id();
116 self.reorder();
117 }
118
119 fn on_detach(&mut self) {
120 count_z_index_node(false);
121 self.reorder();
122 }
123}