1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4// Test that the correct item indices are computed when focusing
5// children of sub-components or their roots.
6
7SubComponentWithFocusableChild := Rectangle {
8 property <bool> has-focus: input.has-focus;
9
10 callback activate();
11 activate => {
12 input.focus();
13 }
14
15 input := TextInput {
16 width: 100%;
17 height: 100%;
18 }
19}
20
21SubComponentWithRootFocusable := TextInput {
22 callback activate();
23 activate => {
24 root.focus();
25 }
26}
27
28FocusInNestedSubComponent := Rectangle {
29 property <bool> has-focus: compo.has-focus;
30 callback activate();
31 activate => {
32 compo.activate();
33 }
34 compo := SubComponentWithRootFocusable {
35 }
36}
37
38
39TestCase := Rectangle {
40 width: 400phx;
41 height: 400phx;
42
43 callback focus_subcompo1();
44 focus_subcompo1 => { input1.activate(); }
45 callback focus_subcompo2();
46 focus_subcompo2 => { input2.activate(); }
47 callback focus_subcompo3();
48 focus_subcompo3 => { input3.activate(); }
49
50 input1 := SubComponentWithFocusableChild {
51 y: 0phx;
52 height: 150phx;
53 }
54
55 input2 := SubComponentWithRootFocusable {
56 y: 150phx;
57 height: 150phx;
58 }
59
60 input3 := FocusInNestedSubComponent {
61 y: 250px;
62 height: 150px;
63 }
64
65 property<bool> input1_focused: input1.has_focus;
66 property<bool> input2_focused: input2.has_focus;
67 property<bool> input3_focused: input3.has_focus;
68
69}
70
71/*
72```rust
73let instance = TestCase::new().unwrap();
74assert!(!instance.get_input1_focused());
75assert!(!instance.get_input2_focused());
76assert!(!instance.get_input3_focused());
77
78instance.invoke_focus_subcompo1();
79assert!(instance.get_input1_focused());
80assert!(!instance.get_input2_focused());
81assert!(!instance.get_input3_focused());
82
83instance.invoke_focus_subcompo2();
84assert!(!instance.get_input1_focused());
85assert!(instance.get_input2_focused());
86assert!(!instance.get_input3_focused());
87
88instance.invoke_focus_subcompo3();
89assert!(!instance.get_input1_focused());
90assert!(!instance.get_input2_focused());
91assert!(instance.get_input3_focused());
92```
93
94```cpp
95auto handle = TestCase::create();
96const TestCase &instance = *handle;
97assert(!instance.get_input1_focused());
98assert(!instance.get_input2_focused());
99assert(!instance.get_input3_focused());
100
101instance.invoke_focus_subcompo1();
102assert(instance.get_input1_focused());
103assert(!instance.get_input2_focused());
104assert(!instance.get_input3_focused());
105
106instance.invoke_focus_subcompo2();
107assert(!instance.get_input1_focused());
108assert(instance.get_input2_focused());
109assert(!instance.get_input3_focused());
110
111instance.invoke_focus_subcompo3();
112assert(!instance.get_input1_focused());
113assert(!instance.get_input2_focused());
114assert(instance.get_input3_focused());
115```
116
117```js
118var instance = new slint.TestCase();
119assert(!instance.input1_focused);
120assert(!instance.input2_focused);
121assert(!instance.input3_focused);
122
123instance.focus_subcompo1();
124assert(instance.input1_focused);
125assert(!instance.input2_focused);
126assert(!instance.input3_focused);
127
128instance.focus_subcompo2();
129assert(!instance.input1_focused);
130assert(instance.input2_focused);
131assert(!instance.input3_focused);
132
133instance.focus_subcompo3();
134assert(!instance.input1_focused);
135assert(!instance.input2_focused);
136assert(instance.input3_focused);
137```
138*/
139