A game framework written with osu! in mind.
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 osuTK;
5using System;
6using System.Collections.Generic;
7using osu.Framework.Extensions.EnumExtensions;
8
9namespace osu.Framework.Graphics.Containers
10{
11 /// <summary>
12 /// Holds extension methods for <see cref="Container{T}"/>.
13 /// </summary>
14 public static class ContainerExtensions
15 {
16 /// <summary>
17 /// Wraps the given <paramref name="drawable"/> with the given <paramref name="container"/>
18 /// such that the <paramref name="container"/> can be used instead of the <paramref name="drawable"/>
19 /// without affecting the layout. The <paramref name="container"/> must not contain any children before wrapping.
20 /// </summary>
21 /// <typeparam name="TContainer">The type of the <paramref name="container"/>.</typeparam>
22 /// <typeparam name="TChild">The type of the children of <paramref name="container"/>.</typeparam>
23 /// <param name="container">The <paramref name="container"/> that should wrap the given <paramref name="drawable"/>.</param>
24 /// <param name="drawable">The <paramref name="drawable"/> that should be wrapped by the given <paramref name="container"/>.</param>
25 /// <returns>The given <paramref name="container"/>.</returns>
26 public static TContainer Wrap<TContainer, TChild>(this TContainer container, TChild drawable)
27 where TContainer : Container<TChild>
28 where TChild : Drawable
29 {
30 if (container.Children.Count != 0)
31 throw new InvalidOperationException($"You may not wrap a {nameof(Container<TChild>)} that has children.");
32
33 container.RelativeSizeAxes = drawable.RelativeSizeAxes;
34 container.AutoSizeAxes = Axes.Both & ~drawable.RelativeSizeAxes;
35 container.Anchor = drawable.Anchor;
36 container.Origin = drawable.Origin;
37 container.Position = drawable.Position;
38 container.Rotation = drawable.Rotation;
39
40 drawable.Position = Vector2.Zero;
41 drawable.Rotation = 0;
42
43 // For anchor/origin positioning to be preserved correctly,
44 // relatively sized axes must be lifted to the wrapping container.
45 if (container.RelativeSizeAxes.HasFlagFast(Axes.X))
46 {
47 container.Width = drawable.Width;
48 drawable.Width = 1;
49 }
50
51 if (container.RelativeSizeAxes.HasFlagFast(Axes.Y))
52 {
53 container.Height = drawable.Height;
54 drawable.Height = 1;
55 }
56
57 container.Add(drawable);
58
59 return container;
60 }
61
62 /// <summary>
63 /// Set a specified <paramref name="child"/> on <paramref name="container"/>.
64 /// </summary>
65 /// <typeparam name="TContainer">The container type.</typeparam>
66 /// <typeparam name="TChild">The type of children contained by <paramref name="container"/>.</typeparam>
67 /// <param name="container">The <paramref name="container"/> that will have a child set.</param>
68 /// <param name="child">The <paramref name="child"/> that should be set to the <paramref name="container"/>.</param>
69 /// <returns>The given <paramref name="container"/>.</returns>
70 public static TContainer WithChild<TContainer, TChild>(this TContainer container, TChild child)
71 where TContainer : IContainerCollection<TChild>
72 where TChild : Drawable
73 {
74 container.Child = child;
75
76 return container;
77 }
78
79 /// <summary>
80 /// Set specified <paramref name="children"/> on <paramref name="container"/>.
81 /// </summary>
82 /// <typeparam name="TContainer">The container type.</typeparam>
83 /// <typeparam name="TChild">The type of children contained by <paramref name="container"/>.</typeparam>
84 /// <param name="container">The <paramref name="container"/> that will have children set.</param>
85 /// <param name="children">The <paramref name="children"/> that should be set to the <paramref name="container"/>.</param>
86 /// <returns>The given <paramref name="container"/>.</returns>
87 public static TContainer WithChildren<TContainer, TChild>(this TContainer container, IEnumerable<TChild> children)
88 where TContainer : IContainerCollection<TChild>
89 where TChild : Drawable
90 {
91 container.ChildrenEnumerable = children;
92
93 return container;
94 }
95 }
96}