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