1use gpui::{
2 actions, div, prelude::*, Div, FocusHandle, Focusable, KeyBinding, Render, Stateful,
3 Subscription, View, WindowContext,
4};
5use ui::prelude::*;
6
7actions!(focus, [ActionA, ActionB, ActionC]);
8
9pub struct FocusStory {
10 parent_focus: FocusHandle,
11 child_1_focus: FocusHandle,
12 child_2_focus: FocusHandle,
13 _focus_subscriptions: Vec<Subscription>,
14}
15
16impl FocusStory {
17 pub fn view(cx: &mut WindowContext) -> View<Self> {
18 cx.bind_keys([
19 KeyBinding::new("cmd-a", ActionA, Some("parent")),
20 KeyBinding::new("cmd-a", ActionB, Some("child-1")),
21 KeyBinding::new("cmd-c", ActionC, None),
22 ]);
23
24 cx.build_view(move |cx| {
25 let parent_focus = cx.focus_handle();
26 let child_1_focus = cx.focus_handle();
27 let child_2_focus = cx.focus_handle();
28 let _focus_subscriptions = vec![
29 cx.on_focus(&parent_focus, |_, _| {
30 println!("Parent focused");
31 }),
32 cx.on_blur(&parent_focus, |_, _| {
33 println!("Parent blurred");
34 }),
35 cx.on_focus(&child_1_focus, |_, _| {
36 println!("Child 1 focused");
37 }),
38 cx.on_blur(&child_1_focus, |_, _| {
39 println!("Child 1 blurred");
40 }),
41 cx.on_focus(&child_2_focus, |_, _| {
42 println!("Child 2 focused");
43 }),
44 cx.on_blur(&child_2_focus, |_, _| {
45 println!("Child 2 blurred");
46 }),
47 ];
48
49 Self {
50 parent_focus,
51 child_1_focus,
52 child_2_focus,
53 _focus_subscriptions,
54 }
55 })
56 }
57}
58
59impl Render for FocusStory {
60 type Element = Focusable<Stateful<Div>>;
61
62 fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element {
63 let theme = cx.theme();
64 let color_1 = theme.status().created;
65 let color_2 = theme.status().modified;
66 let color_4 = theme.status().conflict;
67 let color_5 = theme.status().ignored;
68 let color_6 = theme.status().renamed;
69 let color_7 = theme.status().hint;
70
71 div()
72 .id("parent")
73 .active(|style| style.bg(color_7))
74 .track_focus(&self.parent_focus)
75 .key_context("parent")
76 .on_action(cx.listener(|_, _action: &ActionA, _cx| {
77 println!("Action A dispatched on parent");
78 }))
79 .on_action(cx.listener(|_, _action: &ActionB, _cx| {
80 println!("Action B dispatched on parent");
81 }))
82 .on_key_down(cx.listener(|_, event, _| println!("Key down on parent {:?}", event)))
83 .on_key_up(cx.listener(|_, event, _| println!("Key up on parent {:?}", event)))
84 .size_full()
85 .bg(color_1)
86 .focus(|style| style.bg(color_2))
87 .child(
88 div()
89 .track_focus(&self.child_1_focus)
90 .key_context("child-1")
91 .on_action(cx.listener(|_, _action: &ActionB, _cx| {
92 println!("Action B dispatched on child 1 during");
93 }))
94 .w_full()
95 .h_6()
96 .bg(color_4)
97 .focus(|style| style.bg(color_5))
98 .in_focus(|style| style.bg(color_6))
99 .on_key_down(
100 cx.listener(|_, event, _| println!("Key down on child 1 {:?}", event)),
101 )
102 .on_key_up(cx.listener(|_, event, _| println!("Key up on child 1 {:?}", event)))
103 .child("Child 1"),
104 )
105 .child(
106 div()
107 .track_focus(&self.child_2_focus)
108 .key_context("child-2")
109 .on_action(cx.listener(|_, _action: &ActionC, _cx| {
110 println!("Action C dispatched on child 2");
111 }))
112 .w_full()
113 .h_6()
114 .bg(color_4)
115 .on_key_down(
116 cx.listener(|_, event, _| println!("Key down on child 2 {:?}", event)),
117 )
118 .on_key_up(cx.listener(|_, event, _| println!("Key up on child 2 {:?}", event)))
119 .child("Child 2"),
120 )
121 }
122}