Skip to main content

repose_core/
indication.rs

1use crate::{InteractionSource, Rect, Scene};
2
3/// Marker trait for indication implementations.
4pub trait Indication: std::fmt::Debug {}
5
6/// Factory that creates a drawable indication node bound to an interaction source.
7pub trait IndicationNodeFactory: Indication {
8    fn create(&self, interaction_source: &InteractionSource) -> Box<dyn IndicationDrawNode>;
9}
10
11/// A drawable indication node. The layout engine calls `draw()` during the paint
12/// pass to emit scene nodes for visual feedback (ripple, overlay, focus ring).
13pub trait IndicationDrawNode {
14    /// Draw the indication into `scene` at the given `rect` (in physical pixels).
15    /// `radius` is the component's corner radii (px) for shape-matched overlays.
16    /// `alpha` is the accumulated compositing alpha from ancestor modifiers.
17    fn draw(&self, scene: &mut Scene, rect: Rect, radius: [f32; 4], alpha: f32);
18}
19
20/// A debug indication that draws colored overlays for hover/press/focus.
21#[deprecated]
22#[derive(Clone, Debug)]
23pub struct DebugIndication {
24    pub press_color: crate::Color,
25    pub hover_color: crate::Color,
26    pub focus_color: crate::Color,
27}
28
29impl Default for DebugIndication {
30    fn default() -> Self {
31        Self {
32            press_color: crate::Color(0, 0, 255, 40),
33            hover_color: crate::Color::TRANSPARENT,
34            focus_color: crate::Color::TRANSPARENT,
35        }
36    }
37}
38
39impl Indication for DebugIndication {}
40
41impl IndicationNodeFactory for DebugIndication {
42    fn create(&self, interaction_source: &InteractionSource) -> Box<dyn IndicationDrawNode> {
43        Box::new(DebugIndicationDrawNode {
44            interaction_source: interaction_source.clone(),
45            press_color: self.press_color,
46            hover_color: self.hover_color,
47            focus_color: self.focus_color,
48        })
49    }
50}
51
52struct DebugIndicationDrawNode {
53    interaction_source: InteractionSource,
54    press_color: crate::Color,
55    hover_color: crate::Color,
56    focus_color: crate::Color,
57}
58
59impl IndicationDrawNode for DebugIndicationDrawNode {
60    fn draw(&self, scene: &mut Scene, rect: Rect, radius: [f32; 4], alpha: f32) {
61        let pressed = self.interaction_source.collect_is_pressed();
62        let hovered = self.interaction_source.collect_is_hovered();
63        let focused = self.interaction_source.collect_is_focused();
64
65        // Draw focus overlay
66        if focused && !pressed && self.focus_color.3 > 0 {
67            scene.nodes.push(crate::SceneNode::Rect {
68                rect,
69                brush: self
70                    .focus_color
71                    .with_alpha_f32(self.focus_color.3 as f32 / 255.0 * alpha)
72                    .into(),
73                radius,
74            });
75        }
76        // Draw press overlay
77        if pressed {
78            scene.nodes.push(crate::SceneNode::Rect {
79                rect,
80                brush: self
81                    .press_color
82                    .with_alpha_f32(self.press_color.3 as f32 / 255.0 * alpha)
83                    .into(),
84                radius,
85            });
86        }
87        // Draw hover overlay
88        if hovered && !pressed {
89            scene.nodes.push(crate::SceneNode::Rect {
90                rect,
91                brush: self
92                    .hover_color
93                    .with_alpha_f32(self.hover_color.3 as f32 / 255.0 * alpha)
94                    .into(),
95                radius,
96            });
97        }
98    }
99}