1use crate::{
2 elements::*,
3 fonts::TextStyle,
4 geometry::{rect::RectF, vector::Vector2F},
5 Action, Element, 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> Drawable<V> for KeystrokeLabel {
35 type LayoutState = Element<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, Element<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 .boxed()
53 }))
54 .boxed()
55 } else {
56 Empty::new().collapsed().boxed()
57 };
58
59 let size = element.layout(constraint, view, cx);
60 (size, element)
61 }
62
63 fn paint(
64 &mut self,
65 scene: &mut SceneBuilder,
66 bounds: RectF,
67 visible_bounds: RectF,
68 element: &mut Element<V>,
69 view: &mut V,
70 cx: &mut ViewContext<V>,
71 ) {
72 element.paint(scene, bounds.origin(), visible_bounds, view, cx);
73 }
74
75 fn rect_for_text_range(
76 &self,
77 _: Range<usize>,
78 _: RectF,
79 _: RectF,
80 _: &Self::LayoutState,
81 _: &Self::PaintState,
82 _: &V,
83 _: &ViewContext<V>,
84 ) -> Option<RectF> {
85 None
86 }
87
88 fn debug(
89 &self,
90 _: RectF,
91 element: &Element<V>,
92 _: &(),
93 view: &V,
94 cx: &ViewContext<V>,
95 ) -> serde_json::Value {
96 json!({
97 "type": "KeystrokeLabel",
98 "action": self.action.name(),
99 "child": element.debug(view, cx)
100 })
101 }
102}