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: View> 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 LayoutContext<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 scene: &mut SceneBuilder,
65 bounds: RectF,
66 visible_bounds: RectF,
67 element: &mut AnyElement<V>,
68 view: &mut V,
69 cx: &mut PaintContext<V>,
70 ) {
71 element.paint(scene, bounds.origin(), visible_bounds, view, cx);
72 }
73
74 fn rect_for_text_range(
75 &self,
76 _: Range<usize>,
77 _: RectF,
78 _: RectF,
79 _: &Self::LayoutState,
80 _: &Self::PaintState,
81 _: &V,
82 _: &ViewContext<V>,
83 ) -> Option<RectF> {
84 None
85 }
86
87 fn debug(
88 &self,
89 _: RectF,
90 element: &AnyElement<V>,
91 _: &(),
92 view: &V,
93 cx: &ViewContext<V>,
94 ) -> serde_json::Value {
95 json!({
96 "type": "KeystrokeLabel",
97 "action": self.action.name(),
98 "child": element.debug(view, cx)
99 })
100 }
101}