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 {
35 crate::thread_state::cells(|cells| cells.z_order_reasons.get()) > 0
36}
37
38pub fn z_index_modifier_in_use() -> bool {
42 crate::thread_state::cells(|cells| cells.z_index_nodes.get()) > 0
43}
44
45fn count(counter: &std::cell::Cell<usize>, added: bool) {
46 counter.set(if added {
47 counter.get() + 1
48 } else {
49 counter.get().saturating_sub(1)
50 });
51}
52
53fn count_z_index_node(attached: bool) {
54 crate::thread_state::cells(|cells| {
55 count(&cells.z_index_nodes, attached);
56 count(&cells.z_order_reasons, attached);
57 });
58}
59
60#[derive(Debug, Clone, PartialEq)]
61pub(crate) struct ZIndexElement {
62 z_index: f32,
63}
64
65impl Hash for ZIndexElement {
66 fn hash<H: Hasher>(&self, state: &mut H) {
67 state.write_u32(self.z_index.to_bits());
68 }
69}
70
71impl ModifierNodeElement for ZIndexElement {
72 type Node = ZIndexNode;
73
74 fn create(&self) -> Self::Node {
75 ZIndexNode {
76 z_index: self.z_index,
77 owner: None,
78 state: NodeState::new(),
79 }
80 }
81
82 fn update(&self, node: &mut Self::Node) {
83 if node.z_index.to_bits() != self.z_index.to_bits() {
84 node.z_index = self.z_index;
85 node.reorder();
86 }
87 }
88
89 fn capabilities(&self) -> NodeCapabilities {
90 NodeCapabilities::DRAW
91 }
92}
93
94pub(crate) struct ZIndexNode {
97 z_index: f32,
98 owner: Option<cranpose_core::NodeId>,
100 state: NodeState,
101}
102
103impl ZIndexNode {
104 pub(crate) fn z_index(&self) -> f32 {
105 self.z_index
106 }
107
108 fn reorder(&self) {
111 if let Some(owner) = self.owner {
112 crate::schedule_z_order_change(owner);
113 }
114 }
115}
116
117impl DelegatableNode for ZIndexNode {
118 fn node_state(&self) -> &NodeState {
119 &self.state
120 }
121}
122
123impl ModifierNode for ZIndexNode {
124 fn on_attach(&mut self, context: &mut dyn ModifierNodeContext) {
125 context.invalidate(InvalidationKind::Draw);
126 count_z_index_node(true);
127 self.owner = context.node_id();
128 self.reorder();
129 }
130
131 fn on_detach(&mut self) {
132 count_z_index_node(false);
133 self.reorder();
134 }
135}