1use crate::{
2 elements::*,
3 fonts::TextStyle,
4 geometry::{rect::RectF, vector::Vector2F},
5 Action, ElementBox, Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
6};
7use serde_json::json;
8
9use super::ContainerStyle;
10
11pub struct KeystrokeLabel {
12 action: Box<dyn Action>,
13 container_style: ContainerStyle,
14 text_style: TextStyle,
15}
16
17impl KeystrokeLabel {
18 pub fn new(
19 action: Box<dyn Action>,
20 container_style: ContainerStyle,
21 text_style: TextStyle,
22 ) -> Self {
23 Self {
24 action,
25 container_style,
26 text_style,
27 }
28 }
29}
30
31impl Element for KeystrokeLabel {
32 type LayoutState = ElementBox;
33 type PaintState = ();
34
35 fn layout(
36 &mut self,
37 constraint: SizeConstraint,
38 cx: &mut LayoutContext,
39 ) -> (Vector2F, ElementBox) {
40 let mut element = if let Some(keystrokes) = cx.keystrokes_for_action(self.action.as_ref()) {
41 Flex::row()
42 .with_children(keystrokes.iter().map(|keystroke| {
43 Label::new(keystroke.to_string(), self.text_style.clone())
44 .contained()
45 .with_style(self.container_style)
46 .boxed()
47 }))
48 .boxed()
49 } else {
50 Empty::new().collapsed().boxed()
51 };
52
53 let size = element.layout(constraint, cx);
54 (size, element)
55 }
56
57 fn paint(
58 &mut self,
59 bounds: RectF,
60 visible_bounds: RectF,
61 element: &mut ElementBox,
62 cx: &mut PaintContext,
63 ) {
64 element.paint(bounds.origin(), visible_bounds, cx);
65 }
66
67 fn dispatch_event(
68 &mut self,
69 event: &Event,
70 _: RectF,
71 _: RectF,
72 element: &mut ElementBox,
73 _: &mut (),
74 cx: &mut EventContext,
75 ) -> bool {
76 element.dispatch_event(event, cx)
77 }
78
79 fn rect_for_text_range(
80 &self,
81 _: Range<usize>,
82 _: RectF,
83 _: RectF,
84 _: &Self::LayoutState,
85 _: &Self::PaintState,
86 _: &MeasurementContext,
87 ) -> Option<RectF> {
88 None
89 }
90
91 fn debug(
92 &self,
93 _: RectF,
94 element: &ElementBox,
95 _: &(),
96 cx: &crate::DebugContext,
97 ) -> serde_json::Value {
98 json!({
99 "type": "KeystrokeLabel",
100 "action": self.action.name(),
101 "child": element.debug(cx)
102 })
103 }
104}