Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/scene/test_control.h
10277 views
1
/**************************************************************************/
2
/* test_control.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "scene/2d/node_2d.h"
34
#include "scene/gui/control.h"
35
36
#include "tests/test_macros.h"
37
38
namespace TestControl {
39
40
TEST_CASE("[SceneTree][Control] Transforms") {
41
SUBCASE("[Control][Global Transform] Global Transform should be accessible while not in SceneTree.") { // GH-79453
42
Control *test_node = memnew(Control);
43
Control *test_child = memnew(Control);
44
test_node->add_child(test_child);
45
46
test_node->set_global_position(Point2(1, 1));
47
CHECK_EQ(test_node->get_global_position(), Point2(1, 1));
48
CHECK_EQ(test_child->get_global_position(), Point2(1, 1));
49
test_node->set_global_position(Point2(2, 2));
50
CHECK_EQ(test_node->get_global_position(), Point2(2, 2));
51
test_node->set_scale(Vector2(4, 4));
52
CHECK_EQ(test_node->get_global_transform(), Transform2D(0, Size2(4, 4), 0, Vector2(2, 2)));
53
test_node->set_scale(Vector2(1, 1));
54
test_node->set_rotation_degrees(90);
55
CHECK_EQ(test_node->get_global_transform(), Transform2D(Math::PI / 2, Vector2(2, 2)));
56
test_node->set_pivot_offset(Vector2(1, 0));
57
CHECK_EQ(test_node->get_global_transform(), Transform2D(Math::PI / 2, Vector2(3, 1)));
58
59
memdelete(test_child);
60
memdelete(test_node);
61
}
62
}
63
64
TEST_CASE("[SceneTree][Control] Focus") {
65
Control *ctrl = memnew(Control);
66
SceneTree::get_singleton()->get_root()->add_child(ctrl);
67
68
SUBCASE("[SceneTree][Control] Default focus") {
69
CHECK_UNARY_FALSE(ctrl->has_focus());
70
}
71
72
SUBCASE("[SceneTree][Control] Can't grab focus with default focus mode") {
73
ERR_PRINT_OFF
74
ctrl->grab_focus();
75
ERR_PRINT_ON
76
77
CHECK_UNARY_FALSE(ctrl->has_focus());
78
}
79
80
SUBCASE("[SceneTree][Control] Can grab focus") {
81
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
82
ctrl->grab_focus();
83
84
CHECK_UNARY(ctrl->has_focus());
85
}
86
87
SUBCASE("[SceneTree][Control] Can release focus") {
88
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
89
ctrl->grab_focus();
90
CHECK_UNARY(ctrl->has_focus());
91
92
ctrl->release_focus();
93
CHECK_UNARY_FALSE(ctrl->has_focus());
94
}
95
96
SUBCASE("[SceneTree][Control] Only one can grab focus at the same time") {
97
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
98
ctrl->grab_focus();
99
CHECK_UNARY(ctrl->has_focus());
100
101
Control *other_ctrl = memnew(Control);
102
SceneTree::get_singleton()->get_root()->add_child(other_ctrl);
103
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
104
other_ctrl->grab_focus();
105
106
CHECK_UNARY(other_ctrl->has_focus());
107
CHECK_UNARY_FALSE(ctrl->has_focus());
108
109
memdelete(other_ctrl);
110
}
111
112
SUBCASE("[SceneTree][Control] Hide control will cause the focus to be released") {
113
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
114
ctrl->grab_focus();
115
CHECK_UNARY(ctrl->has_focus());
116
117
ctrl->hide();
118
CHECK_UNARY_FALSE(ctrl->has_focus());
119
120
ctrl->show();
121
CHECK_UNARY_FALSE(ctrl->has_focus());
122
}
123
124
SUBCASE("[SceneTree][Control] The parent node is hidden causing the focus to be released") {
125
Control *child_ctrl = memnew(Control);
126
ctrl->add_child(child_ctrl);
127
128
child_ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
129
child_ctrl->grab_focus();
130
CHECK_UNARY(child_ctrl->has_focus());
131
132
ctrl->hide();
133
CHECK_UNARY_FALSE(child_ctrl->has_focus());
134
135
ctrl->show();
136
CHECK_UNARY_FALSE(child_ctrl->has_focus());
137
138
memdelete(child_ctrl);
139
}
140
141
SUBCASE("[SceneTree][Control] Grab focus with focus behavior recursive") {
142
CHECK_UNARY_FALSE(ctrl->has_focus());
143
144
// Cannot grab focus if focus behavior is disabled.
145
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
146
ctrl->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_DISABLED);
147
148
ERR_PRINT_OFF
149
ctrl->grab_focus();
150
ERR_PRINT_ON
151
CHECK_UNARY_FALSE(ctrl->has_focus());
152
153
// Cannot grab focus if focus behavior is enabled but focus mode is none.
154
ctrl->set_focus_mode(Control::FocusMode::FOCUS_NONE);
155
ctrl->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_ENABLED);
156
157
ERR_PRINT_OFF
158
ctrl->grab_focus();
159
ERR_PRINT_ON
160
CHECK_UNARY_FALSE(ctrl->has_focus());
161
162
// Can grab focus if focus behavior is enabled and focus mode is all.
163
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
164
ctrl->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_ENABLED);
165
166
ctrl->grab_focus();
167
CHECK_UNARY(ctrl->has_focus());
168
}
169
170
SUBCASE("[SceneTree][Control] Children focus with focus behavior recursive") {
171
Control *child_control = memnew(Control);
172
ctrl->add_child(child_control);
173
174
// Can grab focus on child if parent focus behavior is inherit.
175
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
176
ctrl->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_INHERITED);
177
child_control->set_focus_mode(Control::FocusMode::FOCUS_ALL);
178
child_control->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_INHERITED);
179
180
child_control->grab_focus();
181
CHECK_UNARY(child_control->has_focus());
182
183
// Cannot grab focus on child if parent focus behavior is disabled.
184
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
185
ctrl->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_DISABLED);
186
child_control->set_focus_mode(Control::FocusMode::FOCUS_ALL);
187
child_control->set_focus_behavior_recursive(Control::FOCUS_BEHAVIOR_INHERITED);
188
189
ERR_PRINT_OFF
190
child_control->grab_focus();
191
ERR_PRINT_ON
192
CHECK_UNARY_FALSE(child_control->has_focus());
193
194
memdelete(child_control);
195
}
196
197
memdelete(ctrl);
198
}
199
200
TEST_CASE("[SceneTree][Control] Find next/prev valid focus") {
201
Node *intermediate = memnew(Node);
202
Control *ctrl = memnew(Control);
203
intermediate->add_child(ctrl);
204
SceneTree::get_singleton()->get_root()->add_child(intermediate);
205
206
SUBCASE("[SceneTree][Control] In FOCUS_CLICK mode") {
207
ctrl->set_focus_mode(Control::FocusMode::FOCUS_CLICK);
208
ctrl->grab_focus();
209
REQUIRE_UNARY(ctrl->has_focus());
210
211
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
212
SEND_GUI_ACTION("ui_focus_next");
213
CHECK_UNARY(ctrl->has_focus());
214
}
215
216
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
217
SEND_GUI_ACTION("ui_focus_prev");
218
CHECK_UNARY(ctrl->has_focus());
219
}
220
221
SUBCASE("[SceneTree][Control] Has a sibling control and the parent is a window") {
222
Control *ctrl1 = memnew(Control);
223
Control *ctrl2 = memnew(Control);
224
Control *ctrl3 = memnew(Control);
225
Window *win = SceneTree::get_singleton()->get_root();
226
227
ctrl1->set_focus_mode(Control::FocusMode::FOCUS_ALL);
228
ctrl2->set_focus_mode(Control::FocusMode::FOCUS_ALL);
229
ctrl3->set_focus_mode(Control::FocusMode::FOCUS_ALL);
230
231
ctrl2->add_child(ctrl3);
232
win->add_child(ctrl1);
233
win->add_child(ctrl2);
234
235
SUBCASE("[SceneTree][Control] Focus Next") {
236
ctrl1->grab_focus();
237
CHECK_UNARY(ctrl1->has_focus());
238
239
SEND_GUI_ACTION("ui_focus_next");
240
CHECK_UNARY(ctrl2->has_focus());
241
242
SEND_GUI_ACTION("ui_focus_next");
243
CHECK_UNARY(ctrl3->has_focus());
244
245
SEND_GUI_ACTION("ui_focus_next");
246
CHECK_UNARY(ctrl1->has_focus());
247
}
248
249
SUBCASE("[SceneTree][Control] Focus Prev") {
250
ctrl1->grab_focus();
251
CHECK_UNARY(ctrl1->has_focus());
252
253
SEND_GUI_ACTION("ui_focus_prev");
254
CHECK_UNARY(ctrl3->has_focus());
255
256
SEND_GUI_ACTION("ui_focus_prev");
257
CHECK_UNARY(ctrl2->has_focus());
258
259
SEND_GUI_ACTION("ui_focus_prev");
260
CHECK_UNARY(ctrl1->has_focus());
261
}
262
263
memdelete(ctrl3);
264
memdelete(ctrl1);
265
memdelete(ctrl2);
266
}
267
268
SUBCASE("[SceneTree][Control] Has a sibling control but the parent node is not a control or window") {
269
Control *other_ctrl = memnew(Control);
270
intermediate->add_child(other_ctrl);
271
272
SUBCASE("[SceneTree][Control] Has a sibling control with FOCUS_ALL") {
273
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
274
REQUIRE_EQ(other_ctrl->get_focus_mode(), Control::FocusMode::FOCUS_ALL);
275
276
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
277
SEND_GUI_ACTION("ui_focus_next");
278
CHECK_UNARY(ctrl->has_focus());
279
CHECK_UNARY_FALSE(other_ctrl->has_focus());
280
}
281
282
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
283
SEND_GUI_ACTION("ui_focus_prev");
284
CHECK_UNARY(ctrl->has_focus());
285
CHECK_UNARY_FALSE(other_ctrl->has_focus());
286
}
287
288
SUBCASE("[SceneTree][Control] Manually specify focus next") {
289
ctrl->set_focus_next(ctrl->get_path_to(other_ctrl));
290
291
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
292
SEND_GUI_ACTION("ui_focus_next");
293
CHECK_UNARY_FALSE(ctrl->has_focus());
294
CHECK_UNARY(other_ctrl->has_focus());
295
}
296
297
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
298
SEND_GUI_ACTION("ui_focus_prev");
299
CHECK_UNARY(ctrl->has_focus());
300
CHECK_UNARY_FALSE(other_ctrl->has_focus());
301
}
302
303
SUBCASE("[SceneTree][Control] Manually specified focus next is hidden") {
304
other_ctrl->hide();
305
REQUIRE_UNARY_FALSE(other_ctrl->is_visible());
306
307
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
308
SEND_GUI_ACTION("ui_focus_next");
309
CHECK_UNARY(ctrl->has_focus());
310
CHECK_UNARY_FALSE(other_ctrl->has_focus());
311
}
312
313
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
314
SEND_GUI_ACTION("ui_focus_prev");
315
CHECK_UNARY(ctrl->has_focus());
316
CHECK_UNARY_FALSE(other_ctrl->has_focus());
317
}
318
}
319
}
320
321
SUBCASE("[SceneTree][Control] Manually specify focus prev") {
322
ctrl->set_focus_previous(ctrl->get_path_to(other_ctrl));
323
324
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
325
SEND_GUI_ACTION("ui_focus_next");
326
CHECK_UNARY(ctrl->has_focus());
327
CHECK_UNARY_FALSE(other_ctrl->has_focus());
328
}
329
330
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
331
SEND_GUI_ACTION("ui_focus_prev");
332
CHECK_UNARY_FALSE(ctrl->has_focus());
333
CHECK_UNARY(other_ctrl->has_focus());
334
}
335
336
SUBCASE("[SceneTree][Control] Manually specified focus next is hidden") {
337
other_ctrl->hide();
338
REQUIRE_UNARY_FALSE(other_ctrl->is_visible());
339
340
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
341
SEND_GUI_ACTION("ui_focus_next");
342
CHECK_UNARY(ctrl->has_focus());
343
CHECK_UNARY_FALSE(other_ctrl->has_focus());
344
}
345
346
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
347
SEND_GUI_ACTION("ui_focus_prev");
348
CHECK_UNARY(ctrl->has_focus());
349
CHECK_UNARY_FALSE(other_ctrl->has_focus());
350
}
351
}
352
}
353
}
354
355
SUBCASE("[SceneTree][Control] Has a sibling control with FOCUS_CLICK") {
356
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_CLICK);
357
REQUIRE_EQ(other_ctrl->get_focus_mode(), Control::FocusMode::FOCUS_CLICK);
358
359
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
360
SEND_GUI_ACTION("ui_focus_next");
361
CHECK_UNARY(ctrl->has_focus());
362
CHECK_UNARY_FALSE(other_ctrl->has_focus());
363
}
364
365
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
366
SEND_GUI_ACTION("ui_focus_prev");
367
CHECK_UNARY(ctrl->has_focus());
368
CHECK_UNARY_FALSE(other_ctrl->has_focus());
369
}
370
371
SUBCASE("[SceneTree][Control] Manually specify focus next") {
372
ctrl->set_focus_next(ctrl->get_path_to(other_ctrl));
373
374
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
375
SEND_GUI_ACTION("ui_focus_next");
376
CHECK_UNARY_FALSE(ctrl->has_focus());
377
CHECK_UNARY(other_ctrl->has_focus());
378
}
379
380
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
381
SEND_GUI_ACTION("ui_focus_prev");
382
CHECK_UNARY(ctrl->has_focus());
383
CHECK_UNARY_FALSE(other_ctrl->has_focus());
384
}
385
}
386
387
SUBCASE("[SceneTree][Control] Manually specify focus prev") {
388
ctrl->set_focus_previous(ctrl->get_path_to(other_ctrl));
389
390
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
391
SEND_GUI_ACTION("ui_focus_next");
392
CHECK_UNARY(ctrl->has_focus());
393
CHECK_UNARY_FALSE(other_ctrl->has_focus());
394
}
395
396
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
397
SEND_GUI_ACTION("ui_focus_prev");
398
CHECK_UNARY_FALSE(ctrl->has_focus());
399
CHECK_UNARY(other_ctrl->has_focus());
400
}
401
}
402
}
403
404
SUBCASE("[SceneTree][Control] Has a sibling control with FOCUS_NONE") {
405
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_NONE);
406
REQUIRE_EQ(other_ctrl->get_focus_mode(), Control::FocusMode::FOCUS_NONE);
407
408
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
409
SEND_GUI_ACTION("ui_focus_next");
410
CHECK_UNARY(ctrl->has_focus());
411
CHECK_UNARY_FALSE(other_ctrl->has_focus());
412
}
413
414
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
415
SEND_GUI_ACTION("ui_focus_prev");
416
CHECK_UNARY(ctrl->has_focus());
417
CHECK_UNARY_FALSE(other_ctrl->has_focus());
418
}
419
420
SUBCASE("[SceneTree][Control] Manually specify focus next") {
421
ctrl->set_focus_next(ctrl->get_path_to(other_ctrl));
422
423
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
424
SEND_GUI_ACTION("ui_focus_next");
425
CHECK_UNARY(ctrl->has_focus());
426
CHECK_UNARY_FALSE(other_ctrl->has_focus());
427
}
428
429
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
430
SEND_GUI_ACTION("ui_focus_prev");
431
CHECK_UNARY(ctrl->has_focus());
432
CHECK_UNARY_FALSE(other_ctrl->has_focus());
433
}
434
}
435
436
SUBCASE("[SceneTree][Control] Manually specify focus prev") {
437
ctrl->set_focus_previous(ctrl->get_path_to(other_ctrl));
438
439
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
440
SEND_GUI_ACTION("ui_focus_next");
441
CHECK_UNARY(ctrl->has_focus());
442
CHECK_UNARY_FALSE(other_ctrl->has_focus());
443
}
444
445
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
446
SEND_GUI_ACTION("ui_focus_prev");
447
CHECK_UNARY(ctrl->has_focus());
448
CHECK_UNARY_FALSE(other_ctrl->has_focus());
449
}
450
}
451
}
452
453
memdelete(other_ctrl);
454
}
455
}
456
457
SUBCASE("[SceneTree][Control] In FOCUS_ALL mode") {
458
ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
459
REQUIRE_EQ(ctrl->get_focus_mode(), Control::FocusMode::FOCUS_ALL);
460
461
ctrl->grab_focus();
462
REQUIRE_UNARY(ctrl->has_focus());
463
464
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
465
SEND_GUI_ACTION("ui_focus_next");
466
CHECK_UNARY(ctrl->has_focus());
467
}
468
469
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
470
SEND_GUI_ACTION("ui_focus_prev");
471
CHECK_UNARY(ctrl->has_focus());
472
}
473
474
SUBCASE("[SceneTree][Control] Has a sibling control but the parent node is not a control") {
475
Control *other_ctrl = memnew(Control);
476
SceneTree::get_singleton()->get_root()->add_child(other_ctrl);
477
478
SUBCASE("[SceneTree][Control] Has a sibling control with FOCUS_ALL") {
479
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_ALL);
480
REQUIRE_EQ(other_ctrl->get_focus_mode(), Control::FocusMode::FOCUS_ALL);
481
482
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
483
SEND_GUI_ACTION("ui_focus_next");
484
CHECK_UNARY(ctrl->has_focus());
485
CHECK_UNARY_FALSE(other_ctrl->has_focus());
486
}
487
488
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
489
SEND_GUI_ACTION("ui_focus_prev");
490
CHECK_UNARY(ctrl->has_focus());
491
CHECK_UNARY_FALSE(other_ctrl->has_focus());
492
}
493
494
SUBCASE("[SceneTree][Control] Manually specify focus next") {
495
ctrl->set_focus_next(ctrl->get_path_to(other_ctrl));
496
497
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
498
SEND_GUI_ACTION("ui_focus_next");
499
CHECK_UNARY_FALSE(ctrl->has_focus());
500
CHECK_UNARY(other_ctrl->has_focus());
501
}
502
503
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
504
SEND_GUI_ACTION("ui_focus_prev");
505
CHECK_UNARY(ctrl->has_focus());
506
CHECK_UNARY_FALSE(other_ctrl->has_focus());
507
}
508
509
SUBCASE("[SceneTree][Control] Manually specified focus next is hidden") {
510
other_ctrl->hide();
511
REQUIRE_UNARY_FALSE(other_ctrl->is_visible());
512
513
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
514
SEND_GUI_ACTION("ui_focus_next");
515
CHECK_UNARY(ctrl->has_focus());
516
CHECK_UNARY_FALSE(other_ctrl->has_focus());
517
}
518
519
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
520
SEND_GUI_ACTION("ui_focus_prev");
521
CHECK_UNARY(ctrl->has_focus());
522
CHECK_UNARY_FALSE(other_ctrl->has_focus());
523
}
524
}
525
}
526
527
SUBCASE("[SceneTree][Control] Manually specify focus prev") {
528
ctrl->set_focus_previous(ctrl->get_path_to(other_ctrl));
529
530
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
531
SEND_GUI_ACTION("ui_focus_next");
532
CHECK_UNARY(ctrl->has_focus());
533
CHECK_UNARY_FALSE(other_ctrl->has_focus());
534
}
535
536
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
537
SEND_GUI_ACTION("ui_focus_prev");
538
CHECK_UNARY_FALSE(ctrl->has_focus());
539
CHECK_UNARY(other_ctrl->has_focus());
540
}
541
542
SUBCASE("[SceneTree][Control] Manually specified focus next is hidden") {
543
other_ctrl->hide();
544
REQUIRE_UNARY_FALSE(other_ctrl->is_visible());
545
546
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
547
SEND_GUI_ACTION("ui_focus_next");
548
CHECK_UNARY(ctrl->has_focus());
549
CHECK_UNARY_FALSE(other_ctrl->has_focus());
550
}
551
552
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
553
SEND_GUI_ACTION("ui_focus_prev");
554
CHECK_UNARY(ctrl->has_focus());
555
CHECK_UNARY_FALSE(other_ctrl->has_focus());
556
}
557
}
558
}
559
}
560
561
SUBCASE("[SceneTree][Control] Has a sibling control with FOCUS_CLICK") {
562
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_CLICK);
563
REQUIRE_EQ(other_ctrl->get_focus_mode(), Control::FocusMode::FOCUS_CLICK);
564
565
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
566
SEND_GUI_ACTION("ui_focus_next");
567
CHECK_UNARY(ctrl->has_focus());
568
CHECK_UNARY_FALSE(other_ctrl->has_focus());
569
}
570
571
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
572
SEND_GUI_ACTION("ui_focus_prev");
573
CHECK_UNARY(ctrl->has_focus());
574
CHECK_UNARY_FALSE(other_ctrl->has_focus());
575
}
576
577
SUBCASE("[SceneTree][Control] Manually specify focus next") {
578
ctrl->set_focus_next(ctrl->get_path_to(other_ctrl));
579
580
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
581
SEND_GUI_ACTION("ui_focus_next");
582
CHECK_UNARY_FALSE(ctrl->has_focus());
583
CHECK_UNARY(other_ctrl->has_focus());
584
}
585
586
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
587
SEND_GUI_ACTION("ui_focus_prev");
588
CHECK_UNARY(ctrl->has_focus());
589
CHECK_UNARY_FALSE(other_ctrl->has_focus());
590
}
591
}
592
593
SUBCASE("[SceneTree][Control] Manually specify focus prev") {
594
ctrl->set_focus_previous(ctrl->get_path_to(other_ctrl));
595
596
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
597
SEND_GUI_ACTION("ui_focus_next");
598
CHECK_UNARY(ctrl->has_focus());
599
CHECK_UNARY_FALSE(other_ctrl->has_focus());
600
}
601
602
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
603
SEND_GUI_ACTION("ui_focus_prev");
604
CHECK_UNARY_FALSE(ctrl->has_focus());
605
CHECK_UNARY(other_ctrl->has_focus());
606
}
607
}
608
}
609
610
SUBCASE("[SceneTree][Control] Has a sibling control with FOCUS_NONE") {
611
other_ctrl->set_focus_mode(Control::FocusMode::FOCUS_NONE);
612
REQUIRE_EQ(other_ctrl->get_focus_mode(), Control::FocusMode::FOCUS_NONE);
613
614
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
615
SEND_GUI_ACTION("ui_focus_next");
616
CHECK_UNARY(ctrl->has_focus());
617
CHECK_UNARY_FALSE(other_ctrl->has_focus());
618
}
619
620
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
621
SEND_GUI_ACTION("ui_focus_prev");
622
CHECK_UNARY(ctrl->has_focus());
623
CHECK_UNARY_FALSE(other_ctrl->has_focus());
624
}
625
626
SUBCASE("[SceneTree][Control] Manually specify focus next") {
627
ctrl->set_focus_next(ctrl->get_path_to(other_ctrl));
628
629
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
630
SEND_GUI_ACTION("ui_focus_next");
631
CHECK_UNARY(ctrl->has_focus());
632
CHECK_UNARY_FALSE(other_ctrl->has_focus());
633
}
634
635
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
636
SEND_GUI_ACTION("ui_focus_prev");
637
CHECK_UNARY(ctrl->has_focus());
638
CHECK_UNARY_FALSE(other_ctrl->has_focus());
639
}
640
}
641
642
SUBCASE("[SceneTree][Control] Manually specify focus prev") {
643
ctrl->set_focus_previous(ctrl->get_path_to(other_ctrl));
644
645
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
646
SEND_GUI_ACTION("ui_focus_next");
647
CHECK_UNARY(ctrl->has_focus());
648
CHECK_UNARY_FALSE(other_ctrl->has_focus());
649
}
650
651
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
652
SEND_GUI_ACTION("ui_focus_prev");
653
CHECK_UNARY(ctrl->has_focus());
654
CHECK_UNARY_FALSE(other_ctrl->has_focus());
655
}
656
}
657
}
658
659
memdelete(other_ctrl);
660
}
661
662
SUBCASE("[SceneTree][Control] Simple control tree") {
663
Control *ctrl_0 = memnew(Control);
664
Control *ctrl_1 = memnew(Control);
665
Node2D *node_2d_2 = memnew(Node2D);
666
667
ctrl->add_child(ctrl_0);
668
ctrl->add_child(ctrl_1);
669
ctrl->add_child(node_2d_2);
670
671
ctrl_0->set_focus_mode(Control::FocusMode::FOCUS_ALL);
672
ctrl_1->set_focus_mode(Control::FocusMode::FOCUS_ALL);
673
REQUIRE_EQ(ctrl_0->get_focus_mode(), Control::FocusMode::FOCUS_ALL);
674
REQUIRE_EQ(ctrl_1->get_focus_mode(), Control::FocusMode::FOCUS_ALL);
675
676
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
677
SEND_GUI_ACTION("ui_focus_next");
678
CHECK_UNARY(ctrl_0->has_focus());
679
680
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
681
SEND_GUI_ACTION("ui_focus_next");
682
CHECK_UNARY(ctrl_1->has_focus());
683
684
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
685
SEND_GUI_ACTION("ui_focus_next");
686
CHECK_UNARY(ctrl->has_focus());
687
}
688
}
689
}
690
691
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
692
SEND_GUI_ACTION("ui_focus_prev");
693
CHECK_UNARY(ctrl_1->has_focus());
694
695
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
696
SEND_GUI_ACTION("ui_focus_prev");
697
CHECK_UNARY(ctrl_0->has_focus());
698
699
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
700
SEND_GUI_ACTION("ui_focus_prev");
701
CHECK_UNARY(ctrl->has_focus());
702
}
703
}
704
}
705
706
SUBCASE("[SceneTree][Control] Skip next hidden control") {
707
ctrl_0->hide();
708
REQUIRE_UNARY_FALSE(ctrl_0->is_visible());
709
SEND_GUI_ACTION("ui_focus_next");
710
CHECK_UNARY_FALSE(ctrl_0->has_focus());
711
CHECK_UNARY(ctrl_1->has_focus());
712
}
713
714
SUBCASE("[SceneTree][Control] Skip next control with FOCUS_NONE") {
715
ctrl_0->set_focus_mode(Control::FocusMode::FOCUS_NONE);
716
REQUIRE_EQ(ctrl_0->get_focus_mode(), Control::FocusMode::FOCUS_NONE);
717
SEND_GUI_ACTION("ui_focus_next");
718
CHECK_UNARY_FALSE(ctrl_0->has_focus());
719
CHECK_UNARY(ctrl_1->has_focus());
720
}
721
722
SUBCASE("[SceneTree][Control] Skip next control with FOCUS_CLICK") {
723
ctrl_0->set_focus_mode(Control::FocusMode::FOCUS_CLICK);
724
REQUIRE_EQ(ctrl_0->get_focus_mode(), Control::FocusMode::FOCUS_CLICK);
725
SEND_GUI_ACTION("ui_focus_next");
726
CHECK_UNARY_FALSE(ctrl_0->has_focus());
727
CHECK_UNARY(ctrl_1->has_focus());
728
}
729
730
SUBCASE("[SceneTree][Control] Skip next top level control") {
731
ctrl_0->set_as_top_level(true);
732
REQUIRE_UNARY(ctrl_0->is_set_as_top_level());
733
SEND_GUI_ACTION("ui_focus_next");
734
CHECK_UNARY_FALSE(ctrl_0->has_focus());
735
CHECK_UNARY(ctrl_1->has_focus());
736
}
737
738
SUBCASE("[SceneTree][Control] Skip prev hidden control") {
739
ctrl_1->hide();
740
REQUIRE_UNARY_FALSE(ctrl_1->is_visible());
741
SEND_GUI_ACTION("ui_focus_prev");
742
CHECK_UNARY_FALSE(ctrl_1->has_focus());
743
CHECK_UNARY(ctrl_0->has_focus());
744
}
745
746
SUBCASE("[SceneTree][Control] Skip prev control with FOCUS_NONE") {
747
ctrl_1->set_focus_mode(Control::FocusMode::FOCUS_NONE);
748
REQUIRE_EQ(ctrl_1->get_focus_mode(), Control::FocusMode::FOCUS_NONE);
749
SEND_GUI_ACTION("ui_focus_prev");
750
CHECK_UNARY_FALSE(ctrl_1->has_focus());
751
CHECK_UNARY(ctrl_0->has_focus());
752
}
753
754
SUBCASE("[SceneTree][Control] Skip prev control with FOCUS_CLICK") {
755
ctrl_1->set_focus_mode(Control::FocusMode::FOCUS_CLICK);
756
REQUIRE_EQ(ctrl_1->get_focus_mode(), Control::FocusMode::FOCUS_CLICK);
757
SEND_GUI_ACTION("ui_focus_prev");
758
CHECK_UNARY_FALSE(ctrl_1->has_focus());
759
CHECK_UNARY(ctrl_0->has_focus());
760
}
761
762
SUBCASE("[SceneTree][Control] Skip prev top level control") {
763
ctrl_1->set_as_top_level(true);
764
REQUIRE_UNARY(ctrl_1->is_set_as_top_level());
765
SEND_GUI_ACTION("ui_focus_prev");
766
CHECK_UNARY_FALSE(ctrl_1->has_focus());
767
CHECK_UNARY(ctrl_0->has_focus());
768
}
769
770
SUBCASE("[SceneTree][Control] Add more node controls") {
771
Control *ctrl_0_0 = memnew(Control);
772
Control *ctrl_0_1 = memnew(Control);
773
Control *ctrl_0_2 = memnew(Control);
774
ctrl_0->add_child(ctrl_0_0);
775
ctrl_0->add_child(ctrl_0_1);
776
ctrl_0->add_child(ctrl_0_2);
777
ctrl_0_0->set_focus_mode(Control::FocusMode::FOCUS_ALL);
778
ctrl_0_1->set_focus_mode(Control::FocusMode::FOCUS_ALL);
779
ctrl_0_2->set_focus_mode(Control::FocusMode::FOCUS_ALL);
780
781
Control *ctrl_1_0 = memnew(Control);
782
Control *ctrl_1_1 = memnew(Control);
783
Control *ctrl_1_2 = memnew(Control);
784
ctrl_1->add_child(ctrl_1_0);
785
ctrl_1->add_child(ctrl_1_1);
786
ctrl_1->add_child(ctrl_1_2);
787
ctrl_1_0->set_focus_mode(Control::FocusMode::FOCUS_ALL);
788
ctrl_1_1->set_focus_mode(Control::FocusMode::FOCUS_ALL);
789
ctrl_1_2->set_focus_mode(Control::FocusMode::FOCUS_ALL);
790
791
Control *ctrl_2_0 = memnew(Control);
792
Control *ctrl_2_1 = memnew(Control);
793
Control *ctrl_2_2 = memnew(Control);
794
node_2d_2->add_child(ctrl_2_0);
795
node_2d_2->add_child(ctrl_2_1);
796
node_2d_2->add_child(ctrl_2_2);
797
ctrl_2_0->set_focus_mode(Control::FocusMode::FOCUS_ALL);
798
ctrl_2_1->set_focus_mode(Control::FocusMode::FOCUS_ALL);
799
ctrl_2_2->set_focus_mode(Control::FocusMode::FOCUS_ALL);
800
801
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
802
SEND_GUI_ACTION("ui_focus_next");
803
CHECK_UNARY(ctrl_0->has_focus());
804
805
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
806
SEND_GUI_ACTION("ui_focus_next");
807
CHECK_UNARY(ctrl_0_0->has_focus());
808
}
809
810
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
811
SEND_GUI_ACTION("ui_focus_prev");
812
CHECK_UNARY(ctrl->has_focus());
813
}
814
}
815
816
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
817
SEND_GUI_ACTION("ui_focus_prev");
818
CHECK_UNARY(ctrl_1_2->has_focus());
819
}
820
821
SUBCASE("[SceneTree][Control] Exist top level tree") {
822
ctrl_0->set_as_top_level(true);
823
REQUIRE_UNARY(ctrl_0->is_set_as_top_level());
824
825
SUBCASE("[SceneTree][Control] Outside top level tree") {
826
ctrl->grab_focus();
827
REQUIRE_UNARY(ctrl->has_focus());
828
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
829
SEND_GUI_ACTION("ui_focus_next");
830
CHECK_UNARY(ctrl_1->has_focus());
831
832
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
833
SEND_GUI_ACTION("ui_focus_prev");
834
CHECK_UNARY(ctrl->has_focus());
835
}
836
}
837
}
838
839
SUBCASE("[SceneTree][Control] Inside top level tree") {
840
ctrl_0->grab_focus();
841
REQUIRE_UNARY(ctrl_0->has_focus());
842
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
843
SEND_GUI_ACTION("ui_focus_next");
844
CHECK_UNARY(ctrl_0_0->has_focus());
845
846
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
847
SEND_GUI_ACTION("ui_focus_prev");
848
CHECK_UNARY(ctrl_0->has_focus());
849
}
850
}
851
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
852
SEND_GUI_ACTION("ui_focus_prev");
853
CHECK_UNARY(ctrl_0_2->has_focus());
854
855
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
856
SEND_GUI_ACTION("ui_focus_next");
857
CHECK_UNARY(ctrl_0->has_focus());
858
}
859
}
860
}
861
862
SUBCASE("[SceneTree][Control] Manually specified focus next") {
863
ctrl->set_focus_next(ctrl->get_path_to(ctrl_2_1));
864
ctrl_2_1->set_focus_next(ctrl_2_1->get_path_to(ctrl_1_0));
865
ctrl_1_0->set_focus_next(ctrl_1_0->get_path_to(ctrl_0));
866
ctrl_0->set_focus_next(ctrl_0->get_path_to(ctrl));
867
868
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
869
SEND_GUI_ACTION("ui_focus_next");
870
CHECK_UNARY(ctrl_2_1->has_focus());
871
872
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
873
SEND_GUI_ACTION("ui_focus_next");
874
CHECK_UNARY(ctrl_1_0->has_focus());
875
876
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
877
SEND_GUI_ACTION("ui_focus_next");
878
CHECK_UNARY(ctrl_0->has_focus());
879
880
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
881
SEND_GUI_ACTION("ui_focus_next");
882
CHECK_UNARY(ctrl->has_focus());
883
}
884
885
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
886
SEND_GUI_ACTION("ui_focus_prev");
887
CHECK_UNARY(ctrl_0_2->has_focus());
888
}
889
}
890
891
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
892
SEND_GUI_ACTION("ui_focus_prev");
893
CHECK_UNARY(ctrl_1->has_focus());
894
}
895
}
896
897
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
898
SEND_GUI_ACTION("ui_focus_prev");
899
CHECK_UNARY(ctrl_2_1->has_focus());
900
}
901
}
902
903
SUBCASE("[SceneTree][Control] The parent node is not visible") {
904
node_2d_2->hide();
905
REQUIRE_UNARY(ctrl_2_1->is_visible());
906
REQUIRE_UNARY_FALSE(ctrl_2_1->is_visible_in_tree());
907
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
908
SEND_GUI_ACTION("ui_focus_next");
909
CHECK_UNARY_FALSE(ctrl->has_focus());
910
CHECK_UNARY_FALSE(ctrl_2_1->has_focus());
911
CHECK_UNARY_FALSE(ctrl_0->has_focus());
912
CHECK_UNARY(ctrl_1->has_focus());
913
}
914
}
915
}
916
917
SUBCASE("[SceneTree][Control] Manually specified focus prev") {
918
ctrl->set_focus_previous(ctrl->get_path_to(ctrl_0_2));
919
ctrl_0_2->set_focus_previous(ctrl_0_2->get_path_to(ctrl_1_1));
920
ctrl_1_1->set_focus_previous(ctrl_1_1->get_path_to(ctrl_2_0));
921
ctrl_2_0->set_focus_previous(ctrl_2_0->get_path_to(ctrl));
922
923
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
924
SEND_GUI_ACTION("ui_focus_prev");
925
CHECK_UNARY(ctrl_0_2->has_focus());
926
927
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
928
SEND_GUI_ACTION("ui_focus_prev");
929
CHECK_UNARY(ctrl_1_1->has_focus());
930
931
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
932
SEND_GUI_ACTION("ui_focus_prev");
933
CHECK_UNARY(ctrl_2_0->has_focus());
934
935
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
936
SEND_GUI_ACTION("ui_focus_prev");
937
CHECK_UNARY(ctrl->has_focus());
938
}
939
940
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
941
SEND_GUI_ACTION("ui_focus_next");
942
CHECK_UNARY(ctrl_2_0->has_focus());
943
}
944
}
945
946
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
947
SEND_GUI_ACTION("ui_focus_next");
948
CHECK_UNARY(ctrl_1_2->has_focus());
949
}
950
}
951
952
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
953
SEND_GUI_ACTION("ui_focus_next");
954
CHECK_UNARY(ctrl_0->has_focus());
955
}
956
}
957
958
SUBCASE("[SceneTree][Control] The parent node is not visible") {
959
ctrl_0->hide();
960
REQUIRE_UNARY(ctrl_0_2->is_visible());
961
REQUIRE_UNARY_FALSE(ctrl_0_2->is_visible_in_tree());
962
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
963
SEND_GUI_ACTION("ui_focus_prev");
964
CHECK_UNARY_FALSE(ctrl->has_focus());
965
CHECK_UNARY_FALSE(ctrl_0_2->has_focus());
966
CHECK_UNARY(ctrl_1_2->has_focus());
967
}
968
}
969
}
970
}
971
972
SUBCASE("[SceneTree][Control] Exist hidden control tree") {
973
ctrl_0->hide();
974
REQUIRE_UNARY_FALSE(ctrl_0->is_visible());
975
976
SUBCASE("[SceneTree][Control] Simulate ui_focus_next action") {
977
SEND_GUI_ACTION("ui_focus_next");
978
CHECK_UNARY(ctrl_1->has_focus());
979
980
SUBCASE("[SceneTree][Control] Simulate ui_focus_prev action") {
981
SEND_GUI_ACTION("ui_focus_prev");
982
CHECK_UNARY(ctrl->has_focus());
983
}
984
}
985
}
986
987
memdelete(ctrl_2_2);
988
memdelete(ctrl_2_1);
989
memdelete(ctrl_2_0);
990
memdelete(ctrl_1_2);
991
memdelete(ctrl_1_1);
992
memdelete(ctrl_1_0);
993
memdelete(ctrl_0_2);
994
memdelete(ctrl_0_1);
995
memdelete(ctrl_0_0);
996
}
997
998
memdelete(node_2d_2);
999
memdelete(ctrl_1);
1000
memdelete(ctrl_0);
1001
}
1002
}
1003
1004
memdelete(ctrl);
1005
memdelete(intermediate);
1006
}
1007
1008
TEST_CASE("[SceneTree][Control] Anchoring") {
1009
Control *test_control = memnew(Control);
1010
Control *test_child = memnew(Control);
1011
test_control->add_child(test_child);
1012
test_control->set_size(Size2(2, 2));
1013
Window *root = SceneTree::get_singleton()->get_root();
1014
root->add_child(test_control);
1015
1016
SUBCASE("Anchoring without offsets") {
1017
test_child->set_anchor(SIDE_RIGHT, 0.75);
1018
test_child->set_anchor(SIDE_BOTTOM, 0.1);
1019
CHECK_MESSAGE(
1020
test_child->get_size().is_equal_approx(Vector2(1.5, 0.2)),
1021
"With no LEFT or TOP anchors, positive RIGHT and BOTTOM anchors should be proportional to the size.");
1022
CHECK_MESSAGE(
1023
test_child->get_position().is_equal_approx(Vector2(0, 0)),
1024
"With positive RIGHT and BOTTOM anchors set and no LEFT or TOP anchors, the position should not change.");
1025
1026
test_child->set_anchor(SIDE_LEFT, 0.5);
1027
test_child->set_anchor(SIDE_TOP, 0.01);
1028
CHECK_MESSAGE(
1029
test_child->get_size().is_equal_approx(Vector2(0.5, 0.18)),
1030
"With all anchors set, the size should fit between all four anchors.");
1031
CHECK_MESSAGE(
1032
test_child->get_position().is_equal_approx(Vector2(1, 0.02)),
1033
"With all anchors set, the LEFT and TOP anchors should proportional to the position.");
1034
}
1035
1036
SUBCASE("Anchoring with offsets") {
1037
test_child->set_offset(SIDE_RIGHT, 0.33);
1038
test_child->set_offset(SIDE_BOTTOM, 0.2);
1039
CHECK_MESSAGE(
1040
test_child->get_size().is_equal_approx(Vector2(0.33, 0.2)),
1041
"With no anchors or LEFT or TOP offsets set, the RIGHT and BOTTOM offsets should be equal to size.");
1042
CHECK_MESSAGE(
1043
test_child->get_position().is_equal_approx(Vector2(0, 0)),
1044
"With only positive RIGHT and BOTTOM offsets set, the position should not change.");
1045
1046
test_child->set_offset(SIDE_LEFT, 0.1);
1047
test_child->set_offset(SIDE_TOP, 0.05);
1048
CHECK_MESSAGE(
1049
test_child->get_size().is_equal_approx(Vector2(0.23, 0.15)),
1050
"With no anchors set, the size should fit between all four offsets.");
1051
CHECK_MESSAGE(
1052
test_child->get_position().is_equal_approx(Vector2(0.1, 0.05)),
1053
"With no anchors set, the LEFT and TOP offsets should be equal to the position.");
1054
1055
test_child->set_anchor(SIDE_RIGHT, 0.5);
1056
test_child->set_anchor(SIDE_BOTTOM, 0.3);
1057
test_child->set_anchor(SIDE_LEFT, 0.2);
1058
test_child->set_anchor(SIDE_TOP, 0.1);
1059
CHECK_MESSAGE(
1060
test_child->get_size().is_equal_approx(Vector2(0.83, 0.55)),
1061
"Anchors adjust size first then it is affected by offsets.");
1062
CHECK_MESSAGE(
1063
test_child->get_position().is_equal_approx(Vector2(0.5, 0.25)),
1064
"Anchors adjust positions first then it is affected by offsets.");
1065
1066
test_child->set_offset(SIDE_RIGHT, -0.1);
1067
test_child->set_offset(SIDE_BOTTOM, -0.01);
1068
test_child->set_offset(SIDE_LEFT, -0.33);
1069
test_child->set_offset(SIDE_TOP, -0.16);
1070
CHECK_MESSAGE(
1071
test_child->get_size().is_equal_approx(Vector2(0.83, 0.55)),
1072
"Keeping offset distance equal when changing offsets, keeps size equal.");
1073
CHECK_MESSAGE(
1074
test_child->get_position().is_equal_approx(Vector2(0.07, 0.04)),
1075
"Negative offsets move position in top left direction.");
1076
}
1077
1078
SUBCASE("Anchoring is preserved on parent size changed") {
1079
test_child->set_offset(SIDE_RIGHT, -0.05);
1080
test_child->set_offset(SIDE_BOTTOM, 0.1);
1081
test_child->set_offset(SIDE_LEFT, 0.05);
1082
test_child->set_offset(SIDE_TOP, 0.1);
1083
test_child->set_anchor(SIDE_RIGHT, 0.3);
1084
test_child->set_anchor(SIDE_BOTTOM, 0.85);
1085
test_child->set_anchor(SIDE_LEFT, 0.2);
1086
test_child->set_anchor(SIDE_TOP, 0.55);
1087
CHECK(test_child->get_rect().is_equal_approx(
1088
Rect2(Vector2(0.45, 1.2), Size2(0.1, 0.6))));
1089
1090
test_control->set_size(Size2(4, 1));
1091
CHECK(test_child->get_rect().is_equal_approx(
1092
Rect2(Vector2(0.85, 0.65), Size2(0.3, 0.3))));
1093
}
1094
1095
memdelete(test_child);
1096
memdelete(test_control);
1097
}
1098
1099
TEST_CASE("[SceneTree][Control] Custom minimum size") {
1100
Control *test_control = memnew(Control);
1101
test_control->set_custom_minimum_size(Size2(4, 2));
1102
Window *root = SceneTree::get_singleton()->get_root();
1103
root->add_child(test_control);
1104
CHECK_MESSAGE(
1105
test_control->get_size().is_equal_approx(Vector2(4, 2)),
1106
"Size increases to match custom minimum size.");
1107
1108
test_control->set_size(Size2(5, 4));
1109
CHECK_MESSAGE(
1110
test_control->get_size().is_equal_approx(Vector2(5, 4)),
1111
"Size does not change if above custom minimum size.");
1112
1113
test_control->set_size(Size2(1, 1));
1114
CHECK_MESSAGE(
1115
test_control->get_size().is_equal_approx(Vector2(4, 2)),
1116
"Size matches minimum size if set below custom minimum size.");
1117
1118
test_control->set_size(Size2(3, 3));
1119
CHECK_MESSAGE(
1120
test_control->get_size().is_equal_approx(Vector2(4, 3)),
1121
"Adjusts only x axis size if x is below custom minimum size.");
1122
1123
test_control->set_size(Size2(10, 0.1));
1124
CHECK_MESSAGE(
1125
test_control->get_size().is_equal_approx(Vector2(10, 2)),
1126
"Adjusts only y axis size if y is below custom minimum size.");
1127
1128
memdelete(test_control);
1129
}
1130
1131
TEST_CASE("[SceneTree][Control] Grow direction") {
1132
Control *test_control = memnew(Control);
1133
test_control->set_size(Size2(1, 1));
1134
Window *root = SceneTree::get_singleton()->get_root();
1135
root->add_child(test_control);
1136
1137
SUBCASE("Defaults") {
1138
CHECK(test_control->get_h_grow_direction() == Control::GROW_DIRECTION_END);
1139
CHECK(test_control->get_v_grow_direction() == Control::GROW_DIRECTION_END);
1140
}
1141
1142
SIGNAL_WATCH(test_control, SNAME("minimum_size_changed"))
1143
Array signal_args = { {} };
1144
1145
SUBCASE("Horizontal grow direction begin") {
1146
test_control->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
1147
test_control->set_custom_minimum_size(Size2(2, 2));
1148
SceneTree::get_singleton()->process(0);
1149
SIGNAL_CHECK("minimum_size_changed", signal_args)
1150
CHECK_MESSAGE(
1151
test_control->get_rect().is_equal_approx(
1152
Rect2(Vector2(-1, 0), Size2(2, 2))),
1153
"Expand leftwards.");
1154
}
1155
1156
SUBCASE("Vertical grow direction begin") {
1157
test_control->set_v_grow_direction(Control::GROW_DIRECTION_BEGIN);
1158
test_control->set_custom_minimum_size(Size2(4, 3));
1159
SceneTree::get_singleton()->process(0);
1160
SIGNAL_CHECK("minimum_size_changed", signal_args);
1161
CHECK_MESSAGE(
1162
test_control->get_rect().is_equal_approx(
1163
Rect2(Vector2(0, -2), Size2(4, 3))),
1164
"Expand upwards.");
1165
}
1166
1167
SUBCASE("Horizontal grow direction end") {
1168
test_control->set_h_grow_direction(Control::GROW_DIRECTION_END);
1169
test_control->set_custom_minimum_size(Size2(5, 3));
1170
SceneTree::get_singleton()->process(0);
1171
SIGNAL_CHECK("minimum_size_changed", signal_args);
1172
CHECK_MESSAGE(
1173
test_control->get_rect().is_equal_approx(
1174
Rect2(Vector2(0, 0), Size2(5, 3))),
1175
"Expand rightwards.");
1176
}
1177
1178
SUBCASE("Vertical grow direction end") {
1179
test_control->set_v_grow_direction(Control::GROW_DIRECTION_END);
1180
test_control->set_custom_minimum_size(Size2(4, 4));
1181
SceneTree::get_singleton()->process(0);
1182
SIGNAL_CHECK("minimum_size_changed", signal_args);
1183
CHECK_MESSAGE(
1184
test_control->get_rect().is_equal_approx(
1185
Rect2(Vector2(0, 0), Size2(4, 4))),
1186
"Expand downwards.");
1187
;
1188
}
1189
1190
SUBCASE("Horizontal grow direction both") {
1191
test_control->set_h_grow_direction(Control::GROW_DIRECTION_BOTH);
1192
test_control->set_custom_minimum_size(Size2(2, 4));
1193
SceneTree::get_singleton()->process(0);
1194
SIGNAL_CHECK("minimum_size_changed", signal_args);
1195
CHECK_MESSAGE(
1196
test_control->get_rect().is_equal_approx(
1197
Rect2(Vector2(-0.5, 0), Size2(2, 4))),
1198
"Expand equally leftwards and rightwards.");
1199
}
1200
1201
SUBCASE("Vertical grow direction both") {
1202
test_control->set_v_grow_direction(Control::GROW_DIRECTION_BOTH);
1203
test_control->set_custom_minimum_size(Size2(6, 3));
1204
SceneTree::get_singleton()->process(0);
1205
SIGNAL_CHECK("minimum_size_changed", signal_args);
1206
CHECK_MESSAGE(
1207
test_control->get_rect().is_equal_approx(
1208
Rect2(Vector2(0, -1), Size2(6, 3))),
1209
"Expand equally upwards and downwards.");
1210
}
1211
1212
memdelete(test_control);
1213
}
1214
1215
} // namespace TestControl
1216
1217