A game framework written with osu! in mind.
at master 548 lines 22 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 System; 5using osu.Framework.Graphics; 6using osu.Framework.Graphics.Containers; 7using osu.Framework.Graphics.Effects; 8using osu.Framework.Graphics.Shapes; 9using osu.Framework.Graphics.Sprites; 10using osu.Framework.Input.Events; 11using osuTK; 12using osuTK.Graphics; 13 14namespace osu.Framework.Tests.Visual.Containers 15{ 16 public class TestSceneMasking : FrameworkTestScene 17 { 18 protected Container TestContainer; 19 protected int CurrentTest; 20 protected float TestCornerExponent = 2f; 21 22 public TestSceneMasking() 23 { 24 Add(TestContainer = new Container 25 { 26 RelativeSizeAxes = Axes.Both, 27 }); 28 29 string[] testNames = 30 { 31 @"Round corner masking", 32 @"Round corner AABB 1", 33 @"Round corner AABB 2", 34 @"Round corner AABB 3", 35 @"Edge/border blurriness", 36 @"Nested masking", 37 @"Rounded corner input", 38 @"Offset shadow", 39 @"Negative size" 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 AddSliderStep("Corner exponent", 0.01f, 10, 2, exponent => 49 { 50 TestCornerExponent = exponent; 51 loadTest(CurrentTest); 52 }); 53 54 loadTest(0); 55 addCrosshair(); 56 } 57 58 private void addCrosshair() 59 { 60 Add(new Box 61 { 62 Colour = Color4.Black, 63 Size = new Vector2(22, 4), 64 Anchor = Anchor.Centre, 65 Origin = Anchor.Centre 66 }); 67 68 Add(new Box 69 { 70 Colour = Color4.Black, 71 Size = new Vector2(4, 22), 72 Anchor = Anchor.Centre, 73 Origin = Anchor.Centre 74 }); 75 76 Add(new Box 77 { 78 Colour = Color4.WhiteSmoke, 79 Size = new Vector2(20, 2), 80 Anchor = Anchor.Centre, 81 Origin = Anchor.Centre 82 }); 83 84 Add(new Box 85 { 86 Colour = Color4.WhiteSmoke, 87 Size = new Vector2(2, 20), 88 Anchor = Anchor.Centre, 89 Origin = Anchor.Centre 90 }); 91 } 92 93 private void loadTest(int testType) 94 { 95 TestContainer.Clear(); 96 CurrentTest = testType; 97 98 switch (testType) 99 { 100 default: 101 { 102 Container box; 103 TestContainer.Add(box = new InfofulBoxAutoSize 104 { 105 Anchor = Anchor.Centre, 106 Origin = Anchor.Centre, 107 Masking = true, 108 CornerRadius = 100, 109 CornerExponent = TestCornerExponent, 110 BorderColour = Color4.Aquamarine, 111 BorderThickness = 3, 112 EdgeEffect = new EdgeEffectParameters 113 { 114 Type = EdgeEffectType.Shadow, 115 Radius = 100, 116 Colour = new Color4(0, 50, 100, 200), 117 }, 118 }); 119 120 box.Add(box = new InfofulBox 121 { 122 Size = new Vector2(250, 250), 123 Alpha = 0.5f, 124 Origin = Anchor.Centre, 125 Anchor = Anchor.Centre, 126 Colour = Color4.DarkSeaGreen, 127 }); 128 129 box.OnUpdate += delegate { box.Rotation += 0.05f; }; 130 break; 131 } 132 133 case 1: 134 { 135 Container box; 136 TestContainer.Add(new InfofulBoxAutoSize 137 { 138 Anchor = Anchor.Centre, 139 Origin = Anchor.Centre, 140 Children = new[] 141 { 142 box = new InfofulBox 143 { 144 Masking = true, 145 CornerRadius = 100, 146 CornerExponent = TestCornerExponent, 147 Size = new Vector2(400, 400), 148 Alpha = 0.5f, 149 Origin = Anchor.Centre, 150 Anchor = Anchor.Centre, 151 Colour = Color4.DarkSeaGreen, 152 } 153 } 154 }); 155 156 box.OnUpdate += delegate 157 { 158 box.Rotation += 0.05f; 159 box.CornerRadius = 100 + 100 * MathF.Sin(box.Rotation * 0.01f); 160 }; 161 break; 162 } 163 164 case 2: 165 { 166 Container box; 167 TestContainer.Add(new InfofulBoxAutoSize 168 { 169 Anchor = Anchor.Centre, 170 Origin = Anchor.Centre, 171 Children = new[] 172 { 173 box = new InfofulBox 174 { 175 Masking = true, 176 CornerRadius = 25, 177 CornerExponent = TestCornerExponent, 178 Shear = new Vector2(0.5f, 0), 179 Size = new Vector2(150, 150), 180 Scale = new Vector2(2.5f, 1.5f), 181 Alpha = 0.5f, 182 Origin = Anchor.Centre, 183 Anchor = Anchor.Centre, 184 Colour = Color4.DarkSeaGreen, 185 } 186 } 187 }); 188 189 box.OnUpdate += delegate { box.Rotation += 0.05f; }; 190 break; 191 } 192 193 case 3: 194 { 195 Color4 glowColour = Color4.Aquamarine; 196 glowColour.A = 0.5f; 197 198 Container box1; 199 Container box2; 200 201 TestContainer.Add(new InfofulBoxAutoSize 202 { 203 Anchor = Anchor.Centre, 204 Origin = Anchor.Centre, 205 EdgeEffect = new EdgeEffectParameters 206 { 207 Type = EdgeEffectType.Glow, 208 Radius = 100, 209 Roundness = 50, 210 Colour = glowColour, 211 }, 212 BorderColour = Color4.Aquamarine, 213 BorderThickness = 3, 214 Children = new[] 215 { 216 box1 = new InfofulBoxAutoSize 217 { 218 Masking = true, 219 CornerRadius = 25, 220 CornerExponent = TestCornerExponent, 221 Shear = new Vector2(0.5f, 0), 222 Alpha = 0.5f, 223 Origin = Anchor.Centre, 224 Anchor = Anchor.Centre, 225 Colour = Color4.DarkSeaGreen, 226 Children = new[] 227 { 228 box2 = new InfofulBox 229 { 230 Masking = true, 231 CornerRadius = 25, 232 CornerExponent = TestCornerExponent, 233 Shear = new Vector2(0.25f, 0.25f), 234 Size = new Vector2(100, 200), 235 Alpha = 0.5f, 236 Origin = Anchor.Centre, 237 Anchor = Anchor.Centre, 238 Colour = Color4.Blue, 239 } 240 } 241 } 242 } 243 }); 244 245 box1.OnUpdate += delegate { box1.Rotation += 0.07f; }; 246 box2.OnUpdate += delegate { box2.Rotation -= 0.15f; }; 247 break; 248 } 249 250 case 4: 251 { 252 static Drawable createMaskingBox(float scale, float testCornerExponent) 253 { 254 float size = 200 / scale; 255 return new Container 256 { 257 Masking = true, 258 CornerRadius = 25 / scale, 259 CornerExponent = testCornerExponent, 260 BorderThickness = 12.5f / scale, 261 BorderColour = Color4.Red, 262 Size = new Vector2(size), 263 Scale = new Vector2(scale), 264 Anchor = Anchor.Centre, 265 Origin = Anchor.Centre, 266 Children = new Drawable[] 267 { 268 new Box 269 { 270 RelativeSizeAxes = Axes.Both, 271 Colour = Color4.White, 272 Anchor = Anchor.Centre, 273 Origin = Anchor.Centre, 274 }, 275 new SpriteText 276 { 277 Text = @"Size: " + size + ", Scale: " + scale, 278 Font = new FontUsage(size: 20 / scale), 279 Colour = Color4.Blue, 280 Anchor = Anchor.Centre, 281 Origin = Anchor.Centre, 282 }, 283 } 284 }; 285 } 286 287 TestContainer.Add(new FillFlowContainer 288 { 289 RelativeSizeAxes = Axes.Both, 290 Children = new[] 291 { 292 new Container 293 { 294 RelativeSizeAxes = Axes.Both, 295 Size = new Vector2(0.5f), 296 Masking = true, 297 Children = new[] { createMaskingBox(100, TestCornerExponent) } 298 }, 299 new Container 300 { 301 RelativeSizeAxes = Axes.Both, 302 Size = new Vector2(0.5f), 303 Masking = true, 304 Children = new[] { createMaskingBox(10, TestCornerExponent) } 305 }, 306 new Container 307 { 308 RelativeSizeAxes = Axes.Both, 309 Size = new Vector2(0.5f), 310 Masking = true, 311 Children = new[] { createMaskingBox(1, TestCornerExponent) } 312 }, 313 new Container 314 { 315 RelativeSizeAxes = Axes.Both, 316 Size = new Vector2(0.5f), 317 Masking = true, 318 Children = new[] { createMaskingBox(0.1f, TestCornerExponent) } 319 }, 320 } 321 }); 322 323 break; 324 } 325 326 case 5: 327 { 328 TestContainer.Add(new Container 329 { 330 Masking = true, 331 Size = new Vector2(0.5f), 332 RelativeSizeAxes = Axes.Both, 333 Children = new[] 334 { 335 new Container 336 { 337 Masking = true, 338 CornerRadius = 100f, 339 CornerExponent = TestCornerExponent, 340 BorderThickness = 50f, 341 BorderColour = Color4.Red, 342 RelativeSizeAxes = Axes.Both, 343 Size = new Vector2(1.5f), 344 Anchor = Anchor.BottomRight, 345 Origin = Anchor.Centre, 346 Children = new Drawable[] 347 { 348 new Box 349 { 350 RelativeSizeAxes = Axes.Both, 351 Colour = Color4.White, 352 }, 353 } 354 } 355 } 356 }); 357 break; 358 } 359 360 case 6: 361 { 362 TestContainer.Add(new FillFlowContainer 363 { 364 Direction = FillDirection.Vertical, 365 AutoSizeAxes = Axes.Both, 366 Spacing = new Vector2(0, 10), 367 Children = new Drawable[] 368 { 369 new SpriteText 370 { 371 Text = $"None of the folowing {nameof(CircularContainer)}s should trigger until the white part is hovered" 372 }, 373 new FillFlowContainer 374 { 375 Direction = FillDirection.Vertical, 376 AutoSizeAxes = Axes.Both, 377 Spacing = new Vector2(0, 2), 378 Children = new Drawable[] 379 { 380 new SpriteText 381 { 382 Text = "No masking" 383 }, 384 new CircularContainerWithInput 385 { 386 Size = new Vector2(200), 387 Children = new Drawable[] 388 { 389 new Box 390 { 391 RelativeSizeAxes = Axes.Both, 392 Colour = Color4.Red 393 }, 394 new CircularContainer 395 { 396 RelativeSizeAxes = Axes.Both, 397 Colour = Color4.White, 398 Masking = true, 399 Children = new[] 400 { 401 new Box 402 { 403 RelativeSizeAxes = Axes.Both 404 } 405 } 406 } 407 } 408 } 409 } 410 }, 411 new FillFlowContainer 412 { 413 Direction = FillDirection.Vertical, 414 AutoSizeAxes = Axes.Both, 415 Spacing = new Vector2(0, 2), 416 Children = new Drawable[] 417 { 418 new SpriteText 419 { 420 Text = "With masking" 421 }, 422 new CircularContainerWithInput 423 { 424 Size = new Vector2(200), 425 Masking = true, 426 Children = new Drawable[] 427 { 428 new Box 429 { 430 RelativeSizeAxes = Axes.Both, 431 Colour = Color4.Red 432 }, 433 new CircularContainer 434 { 435 RelativeSizeAxes = Axes.Both, 436 Colour = Color4.White, 437 Masking = true, 438 Children = new[] 439 { 440 new Box 441 { 442 RelativeSizeAxes = Axes.Both 443 } 444 } 445 } 446 } 447 } 448 } 449 } 450 } 451 }); 452 break; 453 } 454 455 case 7: 456 { 457 Container box; 458 TestContainer.Add(box = new InfofulBoxAutoSize 459 { 460 Anchor = Anchor.Centre, 461 Origin = Anchor.Centre, 462 Masking = true, 463 CornerRadius = 100, 464 CornerExponent = TestCornerExponent, 465 Alpha = 0.8f, 466 EdgeEffect = new EdgeEffectParameters 467 { 468 Type = EdgeEffectType.Shadow, 469 Offset = new Vector2(0, 50), 470 Hollow = true, 471 Radius = 50, 472 Roundness = 50, 473 Colour = new Color4(0, 255, 255, 255), 474 }, 475 }); 476 477 box.Add(box = new InfofulBox 478 { 479 Size = new Vector2(250, 250), 480 Origin = Anchor.Centre, 481 Anchor = Anchor.Centre, 482 Colour = Color4.DarkSeaGreen, 483 }); 484 485 box.OnUpdate += delegate { box.Rotation += 0.05f; }; 486 break; 487 } 488 489 case 8: 490 TestContainer.Add(new Container 491 { 492 Size = new Vector2(200, 200), 493 Anchor = Anchor.Centre, 494 Origin = Anchor.Centre, 495 Children = new Drawable[] 496 { 497 new Box 498 { 499 RelativeSizeAxes = Axes.Both, 500 Colour = Color4.Gray, 501 }, 502 new InfofulBox 503 { 504 RelativeSizeAxes = Axes.Both, 505 Masking = true, 506 CornerRadius = 50, 507 CornerExponent = TestCornerExponent, 508 BorderColour = Color4.Red, 509 BorderThickness = 10, 510 EdgeEffect = new EdgeEffectParameters 511 { 512 Type = EdgeEffectType.Glow, 513 Radius = 100, 514 Roundness = 50, 515 Colour = Color4.Blue, 516 }, 517 } 518 } 519 }.With(c => c.OnLoadComplete += _ => 520 { 521 c.ResizeWidthTo(-200, 1000, Easing.InOutSine).Then() 522 .ResizeHeightTo(-200, 1000, Easing.InOutSine).Then() 523 .ResizeTo(new Vector2(200, 200), 1000).Loop(); 524 })); 525 break; 526 } 527 528#if DEBUG 529 //if (toggleDebugAutosize.State) 530 // testContainer.Children.FindAll(c => c.HasAutosizeChildren).ForEach(c => c.AutoSizeDebug = true); 531#endif 532 } 533 534 private class CircularContainerWithInput : CircularContainer 535 { 536 protected override bool OnHover(HoverEvent e) 537 { 538 this.ScaleTo(1.2f, 100); 539 return true; 540 } 541 542 protected override void OnHoverLost(HoverLostEvent e) 543 { 544 this.ScaleTo(1f, 100); 545 } 546 } 547 } 548}