diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs
index 781e85f82e..5888be2ae7 100644
--- a/osu.Game/Graphics/Containers/ScalingContainer.cs
+++ b/osu.Game/Graphics/Containers/ScalingContainer.cs
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Primitives;
using osu.Framework.Screens;
using osu.Game.Configuration;
using osu.Game.Screens;
@@ -38,22 +39,18 @@ namespace osu.Game.Graphics.Containers
private BackgroundScreenStack backgroundStack;
- private bool allowScaling = true;
+ private RectangleF? customScale;
+ private bool customScaleIsRelativePosition;
///
- /// Whether user scaling preferences should be applied. Enabled by default.
+ /// Set a custom position and scale which overrides any user specification.
///
- public bool AllowScaling
+ public void SetCustomScale(RectangleF? scale, bool relativePosition = false)
{
- get => allowScaling;
- set
- {
- if (value == allowScaling)
- return;
+ customScale = scale;
+ customScaleIsRelativePosition = relativePosition;
- allowScaling = value;
- if (IsLoaded) Scheduler.AddOnce(updateSize);
- }
+ if (IsLoaded) Scheduler.AddOnce(updateSize);
}
private const float corner_radius = 10;
@@ -164,11 +161,25 @@ namespace osu.Game.Graphics.Containers
backgroundStack?.FadeOut(fade_time);
}
- bool scaling = AllowScaling && (targetMode == null || scalingMode.Value == targetMode);
+ RectangleF targetSize = new RectangleF(Vector2.Zero, Vector2.One);
- var targetSize = scaling ? new Vector2(sizeX.Value, sizeY.Value) : Vector2.One;
- var targetPosition = scaling ? new Vector2(posX.Value, posY.Value) * (Vector2.One - targetSize) : Vector2.Zero;
- bool requiresMasking = (scaling && targetSize != Vector2.One)
+ if (customScale != null)
+ {
+ sizableContainer.RelativePositionAxes = customScaleIsRelativePosition ? Axes.Both : Axes.None;
+
+ targetSize = customScale.Value;
+ }
+ else if (targetMode == null || scalingMode.Value == targetMode)
+ {
+ sizableContainer.RelativePositionAxes = Axes.Both;
+
+ Vector2 scale = new Vector2(sizeX.Value, sizeY.Value);
+ Vector2 pos = new Vector2(posX.Value, posY.Value) * (Vector2.One - scale);
+
+ targetSize = new RectangleF(pos, scale);
+ }
+
+ bool requiresMasking = targetSize.Size != Vector2.One
// For the top level scaling container, for now we apply masking if safe areas are in use.
// In the future this can likely be removed as more of the actual UI supports overflowing into the safe areas.
|| (targetMode == ScalingMode.Everything && safeAreaPadding.Value.Total != Vector2.Zero);
@@ -176,8 +187,8 @@ namespace osu.Game.Graphics.Containers
if (requiresMasking)
sizableContainer.Masking = true;
- sizableContainer.MoveTo(targetPosition, 500, Easing.OutQuart);
- sizableContainer.ResizeTo(targetSize, 500, Easing.OutQuart).OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
+ sizableContainer.MoveTo(targetSize.Location, 500, Easing.OutQuart);
+ sizableContainer.ResizeTo(targetSize.Size, 500, Easing.OutQuart).OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
sizableContainer.TransformTo(nameof(CornerRadius), requiresMasking ? corner_radius : 0, 500, requiresMasking ? Easing.OutQuart : Easing.None);
}
diff --git a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs
index 935d2756fb..ce9afd650a 100644
--- a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs
+++ b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs
@@ -23,6 +23,8 @@ namespace osu.Game.Skinning.Editor
{
public class SkinComponentToolbox : ScrollingToolboxGroup
{
+ public const float WIDTH = 200;
+
public Action RequestPlacement;
private const float component_display_scale = 0.8f;
@@ -41,7 +43,7 @@ namespace osu.Game.Skinning.Editor
: base("Components", height)
{
RelativeSizeAxes = Axes.None;
- Width = 200;
+ Width = WIDTH;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Skinning/Editor/SkinEditorOverlay.cs b/osu.Game/Skinning/Editor/SkinEditorOverlay.cs
index 86854ab6ff..dcfe28aaea 100644
--- a/osu.Game/Skinning/Editor/SkinEditorOverlay.cs
+++ b/osu.Game/Skinning/Editor/SkinEditorOverlay.cs
@@ -5,6 +5,7 @@ using JetBrains.Annotations;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Primitives;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
@@ -100,30 +101,14 @@ namespace osu.Game.Skinning.Editor
{
if (visibility.NewValue == Visibility.Visible)
{
- updateMasking();
- target.AllowScaling = false;
- target.RelativePositionAxes = Axes.Both;
-
- target.ScaleTo(VISIBLE_TARGET_SCALE, SkinEditor.TRANSITION_DURATION, Easing.OutQuint);
- target.MoveToX(0.095f, SkinEditor.TRANSITION_DURATION, Easing.OutQuint);
+ target.SetCustomScale(new RectangleF(0.18f, 0.1f, VISIBLE_TARGET_SCALE, VISIBLE_TARGET_SCALE), true);
}
else
{
- target.AllowScaling = true;
-
- target.ScaleTo(1, SkinEditor.TRANSITION_DURATION, Easing.OutQuint).OnComplete(_ => updateMasking());
- target.MoveToX(0f, SkinEditor.TRANSITION_DURATION, Easing.OutQuint);
+ target.SetCustomScale(null);
}
}
- private void updateMasking()
- {
- if (skinEditor == null)
- return;
-
- target.Masking = skinEditor.State.Value == Visibility.Visible;
- }
-
public void OnReleased(KeyBindingReleaseEvent e)
{
}