A game framework written with osu! in mind.
at master 50 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using NUnit.Framework; 5using osu.Framework.Extensions.Color4Extensions; 6using osu.Framework.Graphics; 7using osu.Framework.Graphics.Containers; 8using osu.Framework.Graphics.Shapes; 9using osu.Framework.Graphics.Sprites; 10using osu.Framework.Input.Events; 11using osu.Framework.Utils; 12using osuTK; 13using osuTK.Graphics; 14 15namespace osu.Framework.Tests.Visual.Containers 16{ 17 [System.ComponentModel.Description("potentially challenging size calculations")] 18 public class TestSceneSizing : FrameworkTestScene 19 { 20 private Container testContainer; 21 22 public TestSceneSizing() 23 { 24 string[] testNames = 25 { 26 @"Multiple children", 27 @"Nested children", 28 @"AutoSize bench", 29 @"RelativeSize bench", 30 @"SpriteText 1", 31 @"SpriteText 2", 32 @"Inverted scaling", 33 @"RelativeSize", 34 @"Padding", 35 @"Margin", 36 @"Inner Margin", 37 @"Drawable Margin", 38 @"Relative Inside Autosize", 39 @"Negative sizing" 40 }; 41 42 for (int i = 0; i < testNames.Length; i++) 43 { 44 int test = i; 45 AddStep(testNames[i], delegate { loadTest(test); }); 46 } 47 } 48 49 [Test] 50 public void TestBypassAutoSizeAxes() 51 { 52 const float autosize_height = 300; 53 54 Container autoSizeContainer = null; 55 Box boxSizeReference = null; 56 57 AddStep("init", () => 58 { 59 Child = autoSizeContainer = new Container 60 { 61 Anchor = Anchor.Centre, 62 Origin = Anchor.Centre, 63 Width = 300, 64 AutoSizeAxes = Axes.Y, 65 Children = new Drawable[] 66 { 67 new Box 68 { 69 Colour = Color4.Green, 70 RelativeSizeAxes = Axes.Both 71 }, 72 boxSizeReference = new Box 73 { 74 RelativeSizeAxes = Axes.X, 75 Height = autosize_height, 76 Colour = Color4.Red.Opacity(0.2f), 77 } 78 } 79 }; 80 }); 81 AddAssert($"height = {autosize_height}", () => Precision.AlmostEquals(autosize_height, autoSizeContainer.DrawHeight)); 82 AddStep("bypass y", () => boxSizeReference.BypassAutoSizeAxes = Axes.Y); 83 AddAssert("height = 0", () => Precision.AlmostEquals(0, autoSizeContainer.DrawHeight)); 84 AddStep("bypass none", () => boxSizeReference.BypassAutoSizeAxes = Axes.None); 85 AddAssert($"height = {autosize_height}", () => Precision.AlmostEquals(autosize_height, autoSizeContainer.DrawHeight)); 86 } 87 88 [Test] 89 public void TestParentInvalidations() 90 { 91 Container child = null; 92 Vector2 initialSize = Vector2.Zero; 93 94 AddStep("add child", () => 95 { 96 Child = child = new Container 97 { 98 AutoSizeAxes = Axes.Both, 99 Child = new Container 100 { 101 // These two properties are important, as they make the parent's autosize 0 102 Anchor = Anchor.TopLeft, 103 Origin = Anchor.BottomRight, 104 AutoSizeAxes = Axes.Both, 105 Child = new Box { Size = new Vector2(100) }, 106 } 107 }; 108 109 // Should already be 0 110 initialSize = child.Size; 111 }); 112 113 // Upon LoadComplete(), one invalidation occurs which causes autosize to recompute 114 // Since nothing has changed since the previous frame, the size of the child should remain the same 115 AddAssert("size is the same after one frame", () => child.Size == initialSize); 116 } 117 118 private void addCrosshair() 119 { 120 Add(new Box 121 { 122 Colour = Color4.Black, 123 Size = new Vector2(22, 4), 124 Anchor = Anchor.Centre, 125 Origin = Anchor.Centre 126 }); 127 128 Add(new Box 129 { 130 Colour = Color4.Black, 131 Size = new Vector2(4, 22), 132 Anchor = Anchor.Centre, 133 Origin = Anchor.Centre 134 }); 135 136 Add(new Box 137 { 138 Colour = Color4.WhiteSmoke, 139 Size = new Vector2(20, 2), 140 Anchor = Anchor.Centre, 141 Origin = Anchor.Centre 142 }); 143 144 Add(new Box 145 { 146 Colour = Color4.WhiteSmoke, 147 Size = new Vector2(2, 20), 148 Anchor = Anchor.Centre, 149 Origin = Anchor.Centre 150 }); 151 } 152 153 private void loadTest(int testType) 154 { 155 Child = testContainer = new Container 156 { 157 RelativeSizeAxes = Axes.Both, 158 }; 159 addCrosshair(); 160 161 Container box; 162 163 switch (testType) 164 { 165 case 0: 166 testContainer.Add(box = new InfofulBoxAutoSize 167 { 168 Anchor = Anchor.Centre, 169 Origin = Anchor.Centre 170 }); 171 172 addCornerMarkers(box); 173 174 box.Add(new InfofulBox 175 { 176 //chameleon = true, 177 Position = new Vector2(0, 0), 178 Size = new Vector2(25, 25), 179 Origin = Anchor.Centre, 180 Anchor = Anchor.Centre, 181 Colour = Color4.Blue, 182 }); 183 184 box.Add(box = new InfofulBox 185 { 186 Size = new Vector2(250, 250), 187 Alpha = 0.5f, 188 Origin = Anchor.Centre, 189 Anchor = Anchor.Centre, 190 Colour = Color4.DarkSeaGreen, 191 }); 192 193 box.OnUpdate += delegate { box.Rotation += 0.05f; }; 194 break; 195 196 case 1: 197 testContainer.Add(box = new InfofulBoxAutoSize 198 { 199 Anchor = Anchor.Centre, 200 Origin = Anchor.Centre 201 }); 202 203 addCornerMarkers(box, 5); 204 205 box.Add(box = new InfofulBoxAutoSize 206 { 207 Colour = Color4.DarkSeaGreen, 208 Alpha = 0.5f, 209 Origin = Anchor.Centre, 210 Anchor = Anchor.Centre 211 }); 212 213 Drawable localBox = box; 214 box.OnUpdate += delegate { localBox.Rotation += 0.05f; }; 215 216 box.Add(new InfofulBox 217 { 218 //chameleon = true, 219 Size = new Vector2(100, 100), 220 Position = new Vector2(50, 50), 221 Alpha = 0.5f, 222 Origin = Anchor.Centre, 223 Anchor = Anchor.Centre, 224 Colour = Color4.Blue, 225 }); 226 break; 227 228 case 2: 229 testContainer.Add(box = new InfofulBoxAutoSize 230 { 231 Anchor = Anchor.Centre, 232 Origin = Anchor.Centre 233 }); 234 235 addCornerMarkers(box, 10, Color4.YellowGreen); 236 237 for (int i = 0; i < 40; i++) 238 { 239 box.Add(box = new InfofulBoxAutoSize 240 { 241 Colour = new Color4(253, 253, 253, 255), 242 Position = new Vector2(-3, -3), 243 Origin = Anchor.BottomRight, 244 Anchor = Anchor.BottomRight, 245 }); 246 } 247 248 addCornerMarkers(box, 2); 249 250 box.Add(new InfofulBox 251 { 252 //chameleon = true, 253 Size = new Vector2(50, 50), 254 Origin = Anchor.BottomRight, 255 Anchor = Anchor.BottomRight, 256 Colour = Color4.SeaGreen, 257 }); 258 break; 259 260 case 3: 261 testContainer.Add(box = new InfofulBox 262 { 263 Anchor = Anchor.Centre, 264 Origin = Anchor.Centre, 265 Size = new Vector2(250, 250) 266 }); 267 268 addCornerMarkers(box, 10, Color4.YellowGreen); 269 270 for (int i = 0; i < 100; i++) 271 { 272 box.Add(box = new InfofulBox 273 { 274 RelativeSizeAxes = Axes.Both, 275 Colour = new Color4(253, 253, 253, 255), 276 Origin = Anchor.BottomRight, 277 Anchor = Anchor.BottomRight, 278 Size = new Vector2(0.99f, 0.99f) 279 }); 280 } 281 282 addCornerMarkers(box, 2); 283 284 box.Add(new InfofulBox 285 { 286 //chameleon = true, 287 Size = new Vector2(50, 50), 288 Origin = Anchor.BottomRight, 289 Anchor = Anchor.BottomRight, 290 Colour = Color4.SeaGreen, 291 }); 292 break; 293 294 case 4: 295 testContainer.Add(box = new InfofulBoxAutoSize 296 { 297 Anchor = Anchor.Centre, 298 Origin = Anchor.CentreLeft 299 }); 300 301 box.Add(new InfofulBox 302 { 303 Position = new Vector2(5, 0), 304 Size = new Vector2(300, 80), 305 Origin = Anchor.TopLeft, 306 Anchor = Anchor.TopLeft, 307 Colour = Color4.OrangeRed, 308 }); 309 310 box.Add(new SpriteText 311 { 312 Position = new Vector2(5, -20), 313 Text = "Test CentreLeft line 1", 314 Origin = Anchor.CentreLeft, 315 Anchor = Anchor.CentreLeft 316 }); 317 318 box.Add(new SpriteText 319 { 320 Position = new Vector2(5, 20), 321 Text = "Test CentreLeft line 2", 322 Origin = Anchor.CentreLeft, 323 Anchor = Anchor.CentreLeft 324 }); 325 break; 326 327 case 5: 328 testContainer.Add(box = new InfofulBoxAutoSize 329 { 330 Anchor = Anchor.Centre, 331 Origin = Anchor.CentreLeft 332 }); 333 334 box.Add(new InfofulBox 335 { 336 Position = new Vector2(5, 0), 337 Size = new Vector2(300, 80), 338 Origin = Anchor.TopLeft, 339 Anchor = Anchor.TopLeft, 340 Colour = Color4.OrangeRed, 341 }); 342 343 box.Add(new SpriteText 344 { 345 Position = new Vector2(5, -20), 346 Text = "123,456,789=", 347 Origin = Anchor.CentreLeft, 348 Anchor = Anchor.CentreLeft, 349 Scale = new Vector2(2f) 350 }); 351 352 box.Add(new SpriteText 353 { 354 Position = new Vector2(5, 20), 355 Text = "123,456,789ms", 356 Origin = Anchor.CentreLeft, 357 Anchor = Anchor.CentreLeft 358 }); 359 break; 360 361 case 6: 362 testContainer.Add(box = new InfofulBoxAutoSize 363 { 364 Anchor = Anchor.Centre, 365 Origin = Anchor.Centre 366 }); 367 368 box.Add(box = new InfofulBoxAutoSize 369 { 370 Colour = Color4.OrangeRed, 371 Position = new Vector2(100, 100), 372 Origin = Anchor.Centre, 373 Anchor = Anchor.TopLeft 374 }); 375 376 box.Add(new InfofulBox 377 { 378 Position = new Vector2(100, 100), 379 Size = new Vector2(100, 100), 380 Origin = Anchor.Centre, 381 Anchor = Anchor.TopLeft, 382 Colour = Color4.OrangeRed, 383 }); 384 break; 385 386 case 7: 387 Container shrinkContainer; 388 Container<Drawable> boxes; 389 390 testContainer.Add(shrinkContainer = new Container 391 { 392 RelativeSizeAxes = Axes.Both, 393 Size = new Vector2(0.5f, 1), 394 Anchor = Anchor.TopCentre, 395 Origin = Anchor.TopCentre, 396 Children = new Drawable[] 397 { 398 new Box 399 { 400 RelativeSizeAxes = Axes.Both, 401 Colour = Color4.AliceBlue, 402 Alpha = 0.2f 403 }, 404 boxes = new FillFlowContainer 405 { 406 RelativeSizeAxes = Axes.X, 407 AutoSizeAxes = Axes.Y, 408 Direction = FillDirection.Vertical, 409 Spacing = new Vector2(0, 10), 410 } 411 } 412 }); 413 414 for (int i = 0; i < 10; i++) 415 { 416 boxes.Add(new Box 417 { 418 RelativeSizeAxes = Axes.X, 419 Anchor = Anchor.TopCentre, 420 Origin = Anchor.TopCentre, 421 Size = new Vector2(0.9f, 40), 422 Colour = Color4.AliceBlue, 423 Alpha = 0.2f 424 }); 425 } 426 427 shrinkContainer.ScaleTo(new Vector2(1.5f, 1), 1000).Then().ScaleTo(Vector2.One, 1000).Loop(); 428 break; 429 430 case 8: 431 { 432 Container box1; 433 Container box2; 434 Container box3; 435 436 testContainer.Add(new FillFlowContainer 437 { 438 RelativeSizeAxes = Axes.Both, 439 Children = new Drawable[] 440 { 441 // This first guy is used for spacing. 442 new Container 443 { 444 RelativeSizeAxes = Axes.Both, 445 Size = new Vector2(0.125f, 1), 446 }, 447 new Container 448 { 449 RelativeSizeAxes = Axes.Both, 450 Size = new Vector2(0.25f, 1), 451 Children = new[] 452 { 453 new InfofulBoxAutoSize 454 { 455 Anchor = Anchor.Centre, 456 Origin = Anchor.Centre, 457 Children = new[] 458 { 459 new Container 460 { 461 AutoSizeAxes = Axes.Both, 462 Depth = -1, 463 Padding = new MarginPadding(50), 464 Children = new Drawable[] 465 { 466 box1 = new InfofulBox 467 { 468 Anchor = Anchor.TopLeft, 469 Origin = Anchor.TopLeft, 470 Size = new Vector2(50), 471 Colour = Color4.Blue, 472 }, 473 } 474 } 475 } 476 }, 477 } 478 }, 479 new Container 480 { 481 RelativeSizeAxes = Axes.Both, 482 Size = new Vector2(0.25f, 1), 483 Children = new[] 484 { 485 new InfofulBoxAutoSize 486 { 487 Anchor = Anchor.Centre, 488 Origin = Anchor.Centre, 489 Children = new[] 490 { 491 new Container 492 { 493 AutoSizeAxes = Axes.Both, 494 Depth = -1, 495 Padding = new MarginPadding(50), 496 Children = new Drawable[] 497 { 498 box2 = new InfofulBox 499 { 500 Anchor = Anchor.Centre, 501 Origin = Anchor.Centre, 502 Size = new Vector2(50), 503 Colour = Color4.Blue, 504 }, 505 } 506 } 507 } 508 }, 509 } 510 }, 511 new Container 512 { 513 RelativeSizeAxes = Axes.Both, 514 Size = new Vector2(0.25f, 1), 515 Children = new[] 516 { 517 new InfofulBoxAutoSize 518 { 519 Anchor = Anchor.Centre, 520 Origin = Anchor.Centre, 521 Children = new[] 522 { 523 new Container 524 { 525 AutoSizeAxes = Axes.Both, 526 Depth = -1, 527 Padding = new MarginPadding(50), 528 Children = new Drawable[] 529 { 530 box3 = new InfofulBox 531 { 532 Anchor = Anchor.BottomRight, 533 Origin = Anchor.BottomRight, 534 Size = new Vector2(50), 535 Colour = Color4.Blue, 536 }, 537 } 538 } 539 } 540 }, 541 } 542 }, 543 } 544 }); 545 546 foreach (Container b in new[] { box1, box2, box3 }) 547 b.ScaleTo(new Vector2(2), 1000).Then().ScaleTo(Vector2.One, 1000).Loop(); 548 549 break; 550 } 551 552 case 9: 553 { 554 Container box1; 555 Container box2; 556 Container box3; 557 558 testContainer.Add(new FillFlowContainer 559 { 560 RelativeSizeAxes = Axes.Both, 561 Children = new Drawable[] 562 { 563 // This first guy is used for spacing. 564 new Container 565 { 566 RelativeSizeAxes = Axes.Both, 567 Size = new Vector2(0.125f, 1), 568 }, 569 new Container 570 { 571 RelativeSizeAxes = Axes.Both, 572 Size = new Vector2(0.25f, 1), 573 Children = new[] 574 { 575 new InfofulBoxAutoSize 576 { 577 Anchor = Anchor.Centre, 578 Origin = Anchor.Centre, 579 Children = new[] 580 { 581 new Container 582 { 583 AutoSizeAxes = Axes.Both, 584 Depth = -1, 585 Margin = new MarginPadding(50), 586 Children = new Drawable[] 587 { 588 box1 = new InfofulBox 589 { 590 Anchor = Anchor.TopLeft, 591 Origin = Anchor.TopLeft, 592 Size = new Vector2(50), 593 Colour = Color4.Blue, 594 }, 595 } 596 } 597 } 598 }, 599 } 600 }, 601 new Container 602 { 603 RelativeSizeAxes = Axes.Both, 604 Size = new Vector2(0.25f, 1), 605 Children = new[] 606 { 607 new InfofulBoxAutoSize 608 { 609 Anchor = Anchor.Centre, 610 Origin = Anchor.Centre, 611 Children = new[] 612 { 613 new Container 614 { 615 AutoSizeAxes = Axes.Both, 616 Depth = -1, 617 Margin = new MarginPadding(50), 618 Children = new Drawable[] 619 { 620 box2 = new InfofulBox 621 { 622 Anchor = Anchor.Centre, 623 Origin = Anchor.Centre, 624 Size = new Vector2(50), 625 Colour = Color4.Blue, 626 }, 627 } 628 } 629 } 630 }, 631 } 632 }, 633 new Container 634 { 635 RelativeSizeAxes = Axes.Both, 636 Size = new Vector2(0.25f, 1), 637 Children = new[] 638 { 639 new InfofulBoxAutoSize 640 { 641 Anchor = Anchor.Centre, 642 Origin = Anchor.Centre, 643 Children = new[] 644 { 645 new Container 646 { 647 AutoSizeAxes = Axes.Both, 648 Depth = -1, 649 Margin = new MarginPadding(50), 650 Children = new Drawable[] 651 { 652 box3 = new InfofulBox 653 { 654 Anchor = Anchor.BottomRight, 655 Origin = Anchor.BottomRight, 656 Size = new Vector2(50), 657 Colour = Color4.Blue, 658 }, 659 } 660 } 661 } 662 }, 663 } 664 }, 665 } 666 }); 667 668 foreach (Container b in new[] { box1, box2, box3 }) 669 b.ScaleTo(new Vector2(2), 1000).Then().ScaleTo(Vector2.One, 1000).Loop(); 670 671 break; 672 } 673 674 case 10: 675 { 676 Container box1; 677 Container box2; 678 Container box3; 679 680 testContainer.Add(new FillFlowContainer 681 { 682 RelativeSizeAxes = Axes.Both, 683 Children = new Drawable[] 684 { 685 // This first guy is used for spacing. 686 new Container 687 { 688 RelativeSizeAxes = Axes.Both, 689 Size = new Vector2(0.125f, 1), 690 }, 691 new Container 692 { 693 RelativeSizeAxes = Axes.Both, 694 Size = new Vector2(0.25f, 1), 695 Children = new[] 696 { 697 new InfofulBoxAutoSize 698 { 699 Anchor = Anchor.Centre, 700 Origin = Anchor.Centre, 701 Children = new[] 702 { 703 new Container 704 { 705 AutoSizeAxes = Axes.Both, 706 Depth = -1, 707 Children = new Drawable[] 708 { 709 box1 = new InfofulBox 710 { 711 Margin = new MarginPadding(50), 712 Anchor = Anchor.TopLeft, 713 Origin = Anchor.TopLeft, 714 Size = new Vector2(50), 715 Colour = Color4.Blue, 716 }, 717 } 718 } 719 } 720 }, 721 } 722 }, 723 new Container 724 { 725 RelativeSizeAxes = Axes.Both, 726 Size = new Vector2(0.25f, 1), 727 Children = new[] 728 { 729 new InfofulBoxAutoSize 730 { 731 Anchor = Anchor.Centre, 732 Origin = Anchor.Centre, 733 Children = new[] 734 { 735 new Container 736 { 737 AutoSizeAxes = Axes.Both, 738 Depth = -1, 739 Children = new Drawable[] 740 { 741 box2 = new InfofulBox 742 { 743 Margin = new MarginPadding(50), 744 Anchor = Anchor.Centre, 745 Origin = Anchor.Centre, 746 Size = new Vector2(50), 747 Colour = Color4.Blue, 748 }, 749 } 750 } 751 } 752 }, 753 } 754 }, 755 new Container 756 { 757 RelativeSizeAxes = Axes.Both, 758 Size = new Vector2(0.25f, 1), 759 Children = new[] 760 { 761 new InfofulBoxAutoSize 762 { 763 Anchor = Anchor.Centre, 764 Origin = Anchor.Centre, 765 Children = new[] 766 { 767 new Container 768 { 769 AutoSizeAxes = Axes.Both, 770 Depth = -1, 771 Children = new Drawable[] 772 { 773 box3 = new InfofulBox 774 { 775 Margin = new MarginPadding(50), 776 Anchor = Anchor.BottomRight, 777 Origin = Anchor.BottomRight, 778 Size = new Vector2(50), 779 Colour = Color4.Blue, 780 }, 781 } 782 } 783 } 784 }, 785 } 786 }, 787 } 788 }); 789 790 foreach (Container b in new[] { box1, box2, box3 }) 791 b.ScaleTo(new Vector2(2), 1000).Then().ScaleTo(Vector2.One, 1000).Loop(); 792 793 break; 794 } 795 796 case 11: 797 { 798 Drawable box1; 799 Drawable box2; 800 Drawable box3; 801 802 testContainer.Add(new FillFlowContainer 803 { 804 RelativeSizeAxes = Axes.Both, 805 Children = new Drawable[] 806 { 807 // This first guy is used for spacing. 808 new Container 809 { 810 RelativeSizeAxes = Axes.Both, 811 Size = new Vector2(0.125f, 1), 812 }, 813 new Container 814 { 815 RelativeSizeAxes = Axes.Both, 816 Size = new Vector2(0.25f, 1), 817 Children = new[] 818 { 819 new InfofulBoxAutoSize 820 { 821 Anchor = Anchor.Centre, 822 Origin = Anchor.Centre, 823 Children = new[] 824 { 825 new Container 826 { 827 AutoSizeAxes = Axes.Both, 828 Depth = -1, 829 Children = new[] 830 { 831 box1 = new Box 832 { 833 Margin = new MarginPadding(50), 834 Anchor = Anchor.TopLeft, 835 Origin = Anchor.TopLeft, 836 Size = new Vector2(50), 837 Colour = Color4.Blue, 838 }, 839 } 840 } 841 } 842 }, 843 } 844 }, 845 new Container 846 { 847 RelativeSizeAxes = Axes.Both, 848 Size = new Vector2(0.25f, 1), 849 Children = new[] 850 { 851 new InfofulBoxAutoSize 852 { 853 Anchor = Anchor.Centre, 854 Origin = Anchor.Centre, 855 Children = new[] 856 { 857 new Container 858 { 859 AutoSizeAxes = Axes.Both, 860 Depth = -1, 861 Children = new[] 862 { 863 box2 = new Box 864 { 865 Margin = new MarginPadding(50), 866 Anchor = Anchor.Centre, 867 Origin = Anchor.Centre, 868 Size = new Vector2(50), 869 Colour = Color4.Blue, 870 }, 871 } 872 } 873 } 874 }, 875 } 876 }, 877 new Container 878 { 879 RelativeSizeAxes = Axes.Both, 880 Size = new Vector2(0.25f, 1), 881 Children = new[] 882 { 883 new InfofulBoxAutoSize 884 { 885 Anchor = Anchor.Centre, 886 Origin = Anchor.Centre, 887 Children = new[] 888 { 889 new Container 890 { 891 AutoSizeAxes = Axes.Both, 892 Depth = -1, 893 Children = new[] 894 { 895 box3 = new Box 896 { 897 Margin = new MarginPadding(50), 898 Anchor = Anchor.BottomRight, 899 Origin = Anchor.BottomRight, 900 Size = new Vector2(50), 901 Colour = Color4.Blue, 902 }, 903 } 904 } 905 } 906 }, 907 } 908 }, 909 } 910 }); 911 912 foreach (Drawable b in new[] { box1, box2, box3 }) 913 b.ScaleTo(new Vector2(2), 1000).Then().ScaleTo(Vector2.One, 1000).Loop(); 914 915 break; 916 } 917 918 case 12: 919 { 920 // demonstrates how relativeaxes drawables act inside an autosize parent 921 Drawable sizedBox; 922 923 testContainer.Add(new FillFlowContainer 924 { 925 RelativeSizeAxes = Axes.Both, 926 Children = new Drawable[] 927 { 928 new Container 929 { 930 Size = new Vector2(300), 931 Anchor = Anchor.Centre, 932 Origin = Anchor.Centre, 933 Children = new Drawable[] 934 { 935 new Box { Colour = Color4.Gray, RelativeSizeAxes = Axes.Both }, 936 new Container 937 { 938 AutoSizeAxes = Axes.Both, 939 Anchor = Anchor.Centre, 940 Origin = Anchor.Centre, 941 Children = new[] 942 { 943 // defines the size of autosize 944 sizedBox = new Box 945 { 946 Colour = Color4.Red, 947 Anchor = Anchor.Centre, 948 Origin = Anchor.Centre, 949 Size = new Vector2(100f) 950 }, 951 // gets relative size based on autosize 952 new Box 953 { 954 Colour = Color4.Black, 955 RelativeSizeAxes = Axes.Both, 956 Size = new Vector2(0.5f) 957 }, 958 } 959 } 960 } 961 } 962 } 963 }); 964 965 sizedBox.ScaleTo(new Vector2(2), 1000, Easing.Out).Then().ScaleTo(Vector2.One, 1000, Easing.In).Loop(); 966 break; 967 } 968 969 case 13: 970 { 971 testContainer.Add(new FillFlowContainer 972 { 973 Anchor = Anchor.Centre, 974 Origin = Anchor.Centre, 975 RelativeSizeAxes = Axes.X, 976 AutoSizeAxes = Axes.Y, 977 Direction = FillDirection.Vertical, 978 Spacing = new Vector2(0, 20), 979 Children = new[] 980 { 981 new FillFlowContainer 982 { 983 Name = "Top row", 984 RelativeSizeAxes = Axes.X, 985 Height = 200, 986 Direction = FillDirection.Horizontal, 987 Spacing = new Vector2(100, 0), 988 Children = new[] 989 { 990 new NegativeSizingContainer(Anchor.TopLeft, true), 991 new NegativeSizingContainer(Anchor.Centre, true), 992 new NegativeSizingContainer(Anchor.BottomRight, true) 993 } 994 }, 995 new FillFlowContainer 996 { 997 Name = "Bottom row", 998 RelativeSizeAxes = Axes.X, 999 Height = 200, 1000 Direction = FillDirection.Horizontal, 1001 Spacing = new Vector2(100, 0), 1002 Children = new[] 1003 { 1004 new NegativeSizingContainer(Anchor.TopLeft, false), 1005 new NegativeSizingContainer(Anchor.Centre, false), 1006 new NegativeSizingContainer(Anchor.BottomRight, false) 1007 } 1008 } 1009 } 1010 }); 1011 1012 break; 1013 } 1014 } 1015 } 1016 1017 private void addCornerMarkers(Container box, int size = 50, Color4? colour = null) 1018 { 1019 box.Add(new InfofulBox 1020 { 1021 //chameleon = true, 1022 Size = new Vector2(size, size), 1023 Origin = Anchor.TopLeft, 1024 Anchor = Anchor.TopLeft, 1025 AllowDrag = false, 1026 Depth = -2, 1027 Colour = colour ?? Color4.Red, 1028 }); 1029 1030 box.Add(new InfofulBox 1031 { 1032 //chameleon = true, 1033 Size = new Vector2(size, size), 1034 Origin = Anchor.TopRight, 1035 Anchor = Anchor.TopRight, 1036 AllowDrag = false, 1037 Depth = -2, 1038 Colour = colour ?? Color4.Red, 1039 }); 1040 1041 box.Add(new InfofulBox 1042 { 1043 //chameleon = true, 1044 Size = new Vector2(size, size), 1045 Origin = Anchor.BottomLeft, 1046 Anchor = Anchor.BottomLeft, 1047 AllowDrag = false, 1048 Depth = -2, 1049 Colour = colour ?? Color4.Red, 1050 }); 1051 1052 box.Add(new InfofulBox 1053 { 1054 //chameleon = true, 1055 Size = new Vector2(size, size), 1056 Origin = Anchor.BottomRight, 1057 Anchor = Anchor.BottomRight, 1058 AllowDrag = false, 1059 Depth = -2, 1060 Colour = colour ?? Color4.Red, 1061 }); 1062 } 1063 1064 private class NegativeSizingContainer : Container 1065 { 1066 private const float size = 200; 1067 1068 private readonly Box box; 1069 private readonly SpriteText text; 1070 1071 private readonly bool useScale; 1072 1073 public NegativeSizingContainer(Anchor anchor, bool useScale) 1074 { 1075 this.useScale = useScale; 1076 1077 Anchor = Anchor.Centre; 1078 Origin = Anchor.Centre; 1079 AutoSizeAxes = Axes.Both; 1080 1081 Children = new Drawable[] 1082 { 1083 box = new Box 1084 { 1085 Anchor = anchor, 1086 Origin = anchor, 1087 Size = new Vector2(size) 1088 }, 1089 text = new SpriteText 1090 { 1091 Anchor = Anchor.Centre, 1092 Origin = Anchor.Centre, 1093 Colour = Color4.Red, 1094 BypassAutoSizeAxes = Axes.Both 1095 } 1096 }; 1097 } 1098 1099 protected override void LoadComplete() 1100 { 1101 base.LoadComplete(); 1102 1103 if (useScale) 1104 box.ScaleTo(new Vector2(-1), 3000, Easing.InSine).Then().ScaleTo(new Vector2(1), 3000, Easing.InSine).Loop(); 1105 else 1106 box.ResizeTo(new Vector2(-size), 3000, Easing.InSine).Then().ResizeTo(new Vector2(size), 3000, Easing.InSine).Loop(); 1107 } 1108 1109 protected override void Update() 1110 { 1111 base.Update(); 1112 1113 text.Text = useScale ? $"Scale: {box.Scale}" : $"Size: {box.Size}"; 1114 } 1115 } 1116 } 1117 1118 internal class InfofulBoxAutoSize : Container 1119 { 1120 protected override Container<Drawable> Content { get; } 1121 1122 public InfofulBoxAutoSize() 1123 { 1124 AutoSizeAxes = Axes.Both; 1125 1126 Masking = true; 1127 1128 InternalChildren = new Drawable[] 1129 { 1130 new Box 1131 { 1132 RelativeSizeAxes = Axes.Both, 1133 Depth = float.MaxValue, 1134 }, 1135 Content = new Container 1136 { 1137 AutoSizeAxes = Axes.Both, 1138 } 1139 }; 1140 } 1141 1142 public bool AllowDrag = true; 1143 1144 protected override void OnDrag(DragEvent e) 1145 { 1146 if (!AllowDrag) return; 1147 1148 Position += e.Delta; 1149 } 1150 1151 protected override bool OnDragStart(DragStartEvent e) => AllowDrag; 1152 } 1153 1154 internal class InfofulBox : Container 1155 { 1156 public bool AllowDrag = true; 1157 1158 protected override void OnDrag(DragEvent e) 1159 { 1160 if (!AllowDrag) return; 1161 1162 Position += e.Delta; 1163 } 1164 1165 protected override bool OnDragStart(DragStartEvent e) => AllowDrag; 1166 1167 public InfofulBox() 1168 { 1169 Add(new Box 1170 { 1171 RelativeSizeAxes = Axes.Both, 1172 Depth = float.MaxValue, 1173 }); 1174 } 1175 } 1176}