mirror of
https://github.com/ppy/osu.git
synced 2025-01-21 06:02:56 +08:00
Simplify aspect ratio application, add window conforming and direct adjustment
This commit is contained in:
parent
43359553c1
commit
e3bed4c97d
@ -1,12 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input.Handlers.Tablet;
|
using osu.Framework.Input.Handlers.Tablet;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Threading;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Input
|
namespace osu.Game.Overlays.Settings.Sections.Input
|
||||||
{
|
{
|
||||||
@ -21,18 +23,28 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
private readonly BindableNumber<int> offsetX = new BindableNumber<int> { MinValue = 0 };
|
private readonly BindableNumber<int> offsetX = new BindableNumber<int> { MinValue = 0 };
|
||||||
private readonly BindableNumber<int> offsetY = new BindableNumber<int> { MinValue = 0 };
|
private readonly BindableNumber<int> offsetY = new BindableNumber<int> { MinValue = 0 };
|
||||||
|
|
||||||
private readonly BindableNumber<int> sizeX = new BindableNumber<int> { MinValue = 0 };
|
private readonly BindableNumber<int> sizeX = new BindableNumber<int> { MinValue = 10 };
|
||||||
private readonly BindableNumber<int> sizeY = new BindableNumber<int> { MinValue = 0 };
|
private readonly BindableNumber<int> sizeY = new BindableNumber<int> { MinValue = 10 };
|
||||||
|
|
||||||
private SettingsButton aspectResetButton;
|
[Resolved]
|
||||||
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Based on the longest available smartphone.
|
||||||
|
/// </summary>
|
||||||
|
private const float largest_feasible_aspect_ratio = 20f / 9;
|
||||||
|
|
||||||
private readonly BindableNumber<float> aspectRatio = new BindableFloat(1)
|
private readonly BindableNumber<float> aspectRatio = new BindableFloat(1)
|
||||||
{
|
{
|
||||||
MinValue = 0.5f,
|
MinValue = 1 / largest_feasible_aspect_ratio,
|
||||||
MaxValue = 2,
|
MaxValue = largest_feasible_aspect_ratio,
|
||||||
Precision = 0.01f,
|
Precision = 0.01f,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private readonly BindableBool aspectLock = new BindableBool();
|
||||||
|
|
||||||
|
private ScheduledDelegate aspectRatioApplication;
|
||||||
|
|
||||||
protected override string Header => "Tablet";
|
protected override string Header => "Tablet";
|
||||||
|
|
||||||
public TabletSettings(ITabletHandler tabletHandler)
|
public TabletSettings(ITabletHandler tabletHandler)
|
||||||
@ -59,37 +71,18 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
sizeX.Value = val.NewValue.Width;
|
sizeX.Value = val.NewValue.Width;
|
||||||
sizeY.Value = val.NewValue.Height;
|
sizeY.Value = val.NewValue.Height;
|
||||||
|
|
||||||
float proposedAspectRatio = (float)sizeX.Value / sizeY.Value;
|
aspectRatioApplication?.Cancel();
|
||||||
|
aspectRatioApplication = Schedule(() => applyAspectRatio(val));
|
||||||
aspectRatio.Value = proposedAspectRatio;
|
|
||||||
|
|
||||||
if (proposedAspectRatio < aspectRatio.MinValue || proposedAspectRatio > aspectRatio.MaxValue)
|
|
||||||
{
|
|
||||||
// apply aspect ratio restrictions to keep things in a usable state.
|
|
||||||
|
|
||||||
// correction is always going to be below 1.
|
|
||||||
float correction = proposedAspectRatio > aspectRatio.Value
|
|
||||||
? aspectRatio.Value / proposedAspectRatio
|
|
||||||
: proposedAspectRatio / aspectRatio.Value;
|
|
||||||
|
|
||||||
if (val.NewValue.Width != val.OldValue.Width)
|
|
||||||
{
|
|
||||||
if (val.NewValue.Width > val.OldValue.Width)
|
|
||||||
correction = 1 / correction;
|
|
||||||
areaSize.Value = new Size(areaSize.Value.Width, (int)(val.NewValue.Height * correction));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (val.NewValue.Height > val.OldValue.Height)
|
|
||||||
correction = 1 / correction;
|
|
||||||
areaSize.Value = new Size((int)(val.NewValue.Width * correction), areaSize.Value.Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
sizeX.BindValueChanged(val => areaSize.Value = new Size(val.NewValue, areaSize.Value.Height));
|
sizeX.BindValueChanged(val => areaSize.Value = new Size(val.NewValue, areaSize.Value.Height));
|
||||||
sizeY.BindValueChanged(val => areaSize.Value = new Size(areaSize.Value.Width, val.NewValue));
|
sizeY.BindValueChanged(val => areaSize.Value = new Size(areaSize.Value.Width, val.NewValue));
|
||||||
|
|
||||||
|
aspectRatio.BindValueChanged(aspect =>
|
||||||
|
{
|
||||||
|
forceAspectRatio(aspect.NewValue);
|
||||||
|
});
|
||||||
|
|
||||||
((IBindable<Size>)tabletSize).BindTo(tabletHandler.TabletSize);
|
((IBindable<Size>)tabletSize).BindTo(tabletHandler.TabletSize);
|
||||||
tabletSize.BindValueChanged(val =>
|
tabletSize.BindValueChanged(val =>
|
||||||
{
|
{
|
||||||
@ -109,6 +102,33 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyAspectRatio(ValueChangedEvent<Size> sizeChanged)
|
||||||
|
{
|
||||||
|
float proposedAspectRatio = (float)sizeX.Value / sizeY.Value;
|
||||||
|
|
||||||
|
if (!aspectLock.Value)
|
||||||
|
{
|
||||||
|
aspectRatio.Value = proposedAspectRatio;
|
||||||
|
|
||||||
|
// aspect ratio was in a valid range.
|
||||||
|
if (proposedAspectRatio >= aspectRatio.MinValue && proposedAspectRatio <= aspectRatio.MaxValue)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeChanged.NewValue.Width != sizeChanged.OldValue.Width)
|
||||||
|
{
|
||||||
|
areaSize.Value = new Size(areaSize.Value.Width, (int)(areaSize.Value.Width / aspectRatio.Value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
areaSize.Value = new Size((int)(areaSize.Value.Height * aspectRatio.Value), areaSize.Value.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel any event which may have fired while updating variables as a result of aspect ratio limitations.
|
||||||
|
// this avoids a potential feedback loop.
|
||||||
|
aspectRatioApplication?.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateDisplay()
|
private void updateDisplay()
|
||||||
{
|
{
|
||||||
if (Children.Count > 0)
|
if (Children.Count > 0)
|
||||||
@ -121,22 +141,24 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 300,
|
Height = 300,
|
||||||
},
|
},
|
||||||
new SettingsButton
|
new DangerousSettingsButton
|
||||||
{
|
{
|
||||||
Text = "Reset to full area",
|
Text = "Reset to full area",
|
||||||
Action = () =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
|
aspectLock.Value = false;
|
||||||
|
|
||||||
areaOffset.SetDefault();
|
areaOffset.SetDefault();
|
||||||
areaSize.SetDefault();
|
areaSize.SetDefault();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsButton
|
||||||
{
|
{
|
||||||
LabelText = "Lock aspect ratio",
|
Text = "Conform to current game aspect ratio",
|
||||||
},
|
Action = () =>
|
||||||
aspectResetButton = new SettingsButton
|
{
|
||||||
{
|
forceAspectRatio((float)host.Window.ClientSize.Width / host.Window.ClientSize.Height);
|
||||||
Text = "Take aspect ratio from screen size",
|
}
|
||||||
},
|
},
|
||||||
new SettingsSlider<float>
|
new SettingsSlider<float>
|
||||||
{
|
{
|
||||||
@ -153,6 +175,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
LabelText = "Y Offset",
|
LabelText = "Y Offset",
|
||||||
Current = offsetY
|
Current = offsetY
|
||||||
},
|
},
|
||||||
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Lock aspect ratio",
|
||||||
|
Current = aspectLock
|
||||||
|
},
|
||||||
new SettingsSlider<int>
|
new SettingsSlider<int>
|
||||||
{
|
{
|
||||||
LabelText = "Width",
|
LabelText = "Width",
|
||||||
@ -165,5 +192,20 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void forceAspectRatio(float aspectRatio)
|
||||||
|
{
|
||||||
|
aspectLock.Value = false;
|
||||||
|
|
||||||
|
int proposedHeight = (int)(sizeX.Value / aspectRatio);
|
||||||
|
|
||||||
|
if (proposedHeight < sizeY.MaxValue)
|
||||||
|
sizeY.Value = proposedHeight;
|
||||||
|
else
|
||||||
|
sizeX.Value = (int)(sizeY.Value * aspectRatio);
|
||||||
|
|
||||||
|
aspectRatioApplication?.Cancel();
|
||||||
|
aspectLock.Value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user