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
4export global Glob {
5 in-out property <int> v: 55;
6 in-out property <string> r;
7 changed v => {
8 r += "|" + v;
9 }
10}
11
12
13component Chaining {
14
15 public function do-change() {
16 chain-a +=1;
17 chain-f +=1;
18 chain-i +=1;
19 }
20
21 property <int> chain-a;
22 out property <int> chain-a-count;
23 changed chain-a => { chain-a-count += 1; }
24 property <int> chain-b;
25 changed chain-b => { chain-a += 1; }
26 property <int> chain-c;
27 changed chain-c => { chain-b += 1; }
28 property <int> chain-d;
29 changed chain-d => { chain-c += 1; }
30 property <int> chain-e;
31 changed chain-e => { chain-d += 1; }
32 property <int> chain-f;
33 changed chain-f => { chain-e += 1; }
34 property <int> chain-g;
35 changed chain-g => { chain-f += 1; }
36 property <int> chain-h;
37 changed chain-h => { chain-g += 1; }
38 property <int> chain-i;
39 changed chain-i => { chain-h += 1; }
40}
41
42component SubCompo {
43 in-out property <int> v: 456;
44 in-out property <string> result;
45 changed v => {
46 result += "sub("+v+")";
47 }
48}
49
50component SubCompoInline {
51 in-out property <int> v: 456;
52 in-out property <string> result;
53 changed v => {
54 result += "sub2("+v+")";
55 }
56 @children
57}
58
59component WithAliasToNative {
60 out property has-focus <=> ti.has_focus;
61 out property text <=> ti.text;
62 ti := TextInput {}
63}
64
65
66export component TestCase inherits Window {
67 in-out property <string> result;
68 in property <int> value: 56;
69 changed value => {
70 if false { return; }
71 result += "value(" + value + ")";
72 }
73 property <int> other: clamp(value + 1, 50, 100);
74 changed other => {
75 result += "other(" + other + ")";
76 debug("Other changed");
77 }
78
79 out property<int> count;
80 changed result => {
81 count += 1;
82 }
83
84 WithAliasToNative {
85 // just make sure this compiles despite has_focus being unused otherwise
86 changed has_focus => { debug(self.text); }
87 }
88
89 chaining := Chaining {}
90 public function chaining-do-change() { chaining.do-change(); }
91 out property chaining-a-count <=> chaining.chain-a-count;
92
93 sub2 := SubCompoInline {
94 v: 123;
95 changed v => {
96 self.result += "root2("+self.v+")";
97 }
98 result <=> sub.result;
99 sub := SubCompo {
100 v: 789;
101 changed v => {
102 self.result += "root("+self.v+")";
103 }
104 }
105 }
106 public function sub-do-change() { sub.v += 1; sub2.v += 1; }
107 out property sub-result <=> sub.result;
108 changed sub-result => {
109 result += "||" + sub-result;
110 }
111
112 Rectangle {
113 probably-optimized := Rectangle {
114 property <int> foo: other;
115 changed foo => {
116 result += "foo,";
117 }
118 }
119 }
120}
121
122
123/*
124
125
126```rust
127let instance = TestCase::new().unwrap();
128slint_testing::mock_elapsed_time(1000);
129assert_eq!(instance.get_result(), "");
130instance.set_value(56);
131slint_testing::mock_elapsed_time(1000);
132assert_eq!(instance.get_result(), ""); // so far, nothing have changed
133assert_eq!(instance.get_count(), 0);
134instance.set_value(142);
135assert_eq!(instance.get_result(), "");
136assert_eq!(instance.get_count(), 0);
137slint_testing::mock_elapsed_time(1);
138assert_eq!(instance.get_result(), "other(100)foo,value(142)");
139assert_eq!(instance.get_count(), 1);
140instance.set_value(8); // this one is going to be merged in the other
141instance.set_value(141);
142slint_testing::mock_elapsed_time(1);
143assert_eq!(instance.get_result(), "other(100)foo,value(142)value(141)");
144assert_eq!(instance.get_count(), 2);
145
146// Changing a value and back doesn't have effect
147instance.set_value(85);
148instance.set_value(141);
149slint_testing::mock_elapsed_time(1);
150assert_eq!(instance.get_result(), "other(100)foo,value(142)value(141)");
151assert_eq!(instance.get_count(), 2);
152
153instance.set_result("".into());
154instance.invoke_chaining_do_change();
155slint_testing::mock_elapsed_time(1);
156assert_eq!(instance.get_chaining_a_count(), 3);
157
158assert_eq!(instance.get_sub_result(), "");
159instance.invoke_sub_do_change();
160slint_testing::mock_elapsed_time(100);
161assert_eq!(instance.get_sub_result(), "sub2(124)root2(124)sub(790)root(790)");
162assert_eq!(instance.get_result(), "||sub2(124)root2(124)sub(790)root(790)");
163
164// Global
165instance.global::<Glob<'_>>().set_v(88);
166assert_eq!(instance.global::<Glob<'_>>().get_r(), "");
167slint_testing::mock_elapsed_time(100);
168assert_eq!(instance.global::<Glob<'_>>().get_r(), "|88");
169```
170
171```cpp
172auto handle = TestCase::create();
173const TestCase &instance = *handle;
174slint_testing::mock_elapsed_time(1000);
175assert_eq(instance.get_result(), "");
176instance.set_value(56);
177slint_testing::mock_elapsed_time(1000);
178assert_eq(instance.get_result(), ""); // so far, nothing have changed
179assert_eq(instance.get_count(), 0);
180instance.set_value(142);
181assert_eq(instance.get_result(), "");
182assert_eq(instance.get_count(), 0);
183slint_testing::mock_elapsed_time(1);
184assert_eq(instance.get_result(), "other(100)foo,value(142)");
185assert_eq(instance.get_count(), 1);
186instance.set_value(8); // this one is going to be merged in the other
187instance.set_value(141);
188slint_testing::mock_elapsed_time(1);
189assert_eq(instance.get_result(), "other(100)foo,value(142)value(141)");
190assert_eq(instance.get_count(), 2);
191
192// Changing a value and back doesn't have effect
193instance.set_value(85);
194instance.set_value(141);
195slint_testing::mock_elapsed_time(1);
196assert_eq(instance.get_result(), "other(100)foo,value(142)value(141)");
197assert_eq(instance.get_count(), 2);
198
199instance.set_result("");
200instance.invoke_chaining_do_change();
201slint_testing::mock_elapsed_time(1);
202assert_eq(instance.get_chaining_a_count(), 3);
203
204assert_eq(instance.get_sub_result(), "");
205instance.invoke_sub_do_change();
206slint_testing::mock_elapsed_time(100);
207assert_eq(instance.get_sub_result(), "sub2(124)root2(124)sub(790)root(790)");
208assert_eq(instance.get_result(), "||sub2(124)root2(124)sub(790)root(790)");
209
210// Global
211instance.global<Glob>().set_v(88);
212assert_eq(instance.global<Glob>().get_r(), "");
213slint_testing::mock_elapsed_time(100);
214assert_eq(instance.global<Glob>().get_r(), "|88");
215```
216
217```js
218var instance = new slint.TestCase({});
219slintlib.private_api.mock_elapsed_time(1000);
220assert.equal(instance.result, "");
221instance.value = 56;
222slintlib.private_api.mock_elapsed_time(1000);
223assert.equal(instance.result, ""); // so far, nothing have changed
224instance.value = 142;
225assert.equal(instance.result, "");
226slintlib.private_api.mock_elapsed_time(1);
227assert.equal(instance.result, "other(100)foo,value(142)");
228instance.value = 8; // this one is going to be merged in the other
229instance.value = 141;
230slintlib.private_api.mock_elapsed_time(1);
231assert.equal(instance.result, "other(100)foo,value(142)value(141)");
232
233// Changing a value and back doesn't have effect
234instance.value = 85;
235instance.value = 141;
236slintlib.private_api.mock_elapsed_time(1);
237assert.equal(instance.result, "other(100)foo,value(142)value(141)");
238
239instance.result = "";
240instance.chaining_do_change();
241slintlib.private_api.mock_elapsed_time(1);
242assert.equal(instance.chaining_a_count, 3);
243
244assert.equal(instance.sub_result, "");
245instance.sub_do_change();
246slintlib.private_api.mock_elapsed_time(100);
247assert.equal(instance.sub_result, "sub2(124)root2(124)sub(790)root(790)");
248assert.equal(instance.result, "||sub2(124)root2(124)sub(790)root(790)");
249
250// Global
251instance.Glob.v = 88;
252assert.equal(instance.Glob.r, "");
253slintlib.private_api.mock_elapsed_time(100);
254assert.equal(instance.Glob.r, "|88");
255```
256
257*/
258