mirror of
https://github.com/ppy/osu.git
synced 2025-01-18 11:02:57 +08:00
Allow locking orientation on iOS in certain circumstances
This commit is contained in:
parent
62e536baf6
commit
7563a18c7f
@ -174,6 +174,16 @@ namespace osu.Game
|
||||
/// </summary>
|
||||
public readonly IBindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
|
||||
|
||||
/// <summary>
|
||||
/// On mobile devices, this specifies whether the device should be set and locked to portrait orientation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Implementations can be viewed in mobile projects.
|
||||
/// </remarks>
|
||||
public IBindable<bool> RequiresPortraitOrientation => requiresPortraitOrientation;
|
||||
|
||||
private readonly Bindable<bool> requiresPortraitOrientation = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the back button is currently displayed.
|
||||
/// </summary>
|
||||
@ -1623,6 +1633,8 @@ namespace osu.Game
|
||||
|
||||
GlobalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = newOsuScreen.HideMenuCursorOnNonMouseInput;
|
||||
|
||||
requiresPortraitOrientation.Value = newOsuScreen.RequiresPortraitOrientation;
|
||||
|
||||
if (newOsuScreen.HideOverlaysOnEnter)
|
||||
CloseAllOverlays();
|
||||
else
|
||||
|
@ -577,6 +577,11 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public virtual bool AllowGameplayOverlays => true;
|
||||
|
||||
/// <summary>
|
||||
/// On mobile devices, this specifies whether this ruleset requires the device to be in portrait orientation.
|
||||
/// </summary>
|
||||
public virtual bool RequiresPortraitOrientation => false;
|
||||
|
||||
/// <summary>
|
||||
/// Sets a replay to be used, overriding local input.
|
||||
/// </summary>
|
||||
|
@ -61,6 +61,16 @@ namespace osu.Game.Screens
|
||||
/// </summary>
|
||||
bool HideMenuCursorOnNonMouseInput { get; }
|
||||
|
||||
/// <summary>
|
||||
/// On mobile devices, this specifies whether this <see cref="OsuScreen"/> requires the device to be in portrait orientation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, all screens in the game display in landscape orientation.
|
||||
/// Setting this to <c>true</c> will display this screen in portrait orientation instead,
|
||||
/// and switch back to landscape when transitioning back to a regular non-portrait screen.
|
||||
/// </remarks>
|
||||
bool RequiresPortraitOrientation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether overlays should be able to be opened when this screen is current.
|
||||
/// </summary>
|
||||
|
@ -47,6 +47,8 @@ namespace osu.Game.Screens
|
||||
|
||||
public virtual bool HideMenuCursorOnNonMouseInput => false;
|
||||
|
||||
public virtual bool RequiresPortraitOrientation => false;
|
||||
|
||||
/// <summary>
|
||||
/// The initial overlay activation mode to use when this screen is entered for the first time.
|
||||
/// </summary>
|
||||
|
@ -68,6 +68,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public override bool HideMenuCursorOnNonMouseInput => true;
|
||||
|
||||
public override bool RequiresPortraitOrientation => DrawableRuleset.RequiresPortraitOrientation;
|
||||
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered;
|
||||
|
||||
// We are managing our own adjustments (see OnEntering/OnExiting).
|
||||
|
@ -1,14 +1,61 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameApplicationDelegate
|
||||
{
|
||||
protected override Framework.Game CreateGame() => new OsuGameIOS();
|
||||
private UIInterfaceOrientationMask? defaultOrientationsMask;
|
||||
private UIInterfaceOrientationMask? orientations;
|
||||
|
||||
/// <summary>
|
||||
/// The current orientation the game is displayed in.
|
||||
/// </summary>
|
||||
public UIInterfaceOrientation CurrentOrientation => Host.Window.UIWindow.WindowScene!.InterfaceOrientation;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the orientations allowed for the device to rotate to, overriding the default allowed orientations.
|
||||
/// </summary>
|
||||
public UIInterfaceOrientationMask? Orientations
|
||||
{
|
||||
get => orientations;
|
||||
set
|
||||
{
|
||||
if (orientations == value)
|
||||
return;
|
||||
|
||||
orientations = value;
|
||||
|
||||
if (OperatingSystem.IsIOSVersionAtLeast(16))
|
||||
Host.Window.ViewController.SetNeedsUpdateOfSupportedInterfaceOrientations();
|
||||
else
|
||||
UIViewController.AttemptRotationToDeviceOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
protected override Framework.Game CreateGame() => new OsuGameIOS(this);
|
||||
|
||||
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
|
||||
{
|
||||
if (orientations != null)
|
||||
return orientations.Value;
|
||||
|
||||
if (defaultOrientationsMask == null)
|
||||
{
|
||||
defaultOrientationsMask = 0;
|
||||
var defaultOrientations = (NSArray)NSBundle.MainBundle.ObjectForInfoDictionary("UISupportedInterfaceOrientations");
|
||||
|
||||
foreach (var value in defaultOrientations.ToArray<NSString>())
|
||||
defaultOrientationsMask |= Enum.Parse<UIInterfaceOrientationMask>(value.ToString().Replace("UIInterfaceOrientation", string.Empty));
|
||||
}
|
||||
|
||||
return defaultOrientationsMask.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
76
osu.iOS/IOSOrientationHandler.cs
Normal file
76
osu.iOS/IOSOrientationHandler.cs
Normal file
@ -0,0 +1,76 @@
|
||||
// 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.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game;
|
||||
using osu.Game.Screens.Play;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.iOS
|
||||
{
|
||||
public partial class IOSOrientationHandler : Component
|
||||
{
|
||||
private readonly AppDelegate appDelegate;
|
||||
|
||||
[Resolved]
|
||||
private OsuGame game { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private ILocalUserPlayInfo localUserPlayInfo { get; set; } = null!;
|
||||
|
||||
private IBindable<bool> requiresPortraitOrientation = null!;
|
||||
private IBindable<LocalUserPlayingState> localUserPlaying = null!;
|
||||
|
||||
public IOSOrientationHandler(AppDelegate appDelegate)
|
||||
{
|
||||
this.appDelegate = appDelegate;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
requiresPortraitOrientation = game.RequiresPortraitOrientation.GetBoundCopy();
|
||||
requiresPortraitOrientation.BindValueChanged(_ => updateOrientations());
|
||||
|
||||
localUserPlaying = localUserPlayInfo.PlayingState.GetBoundCopy();
|
||||
localUserPlaying.BindValueChanged(_ => updateOrientations());
|
||||
|
||||
updateOrientations();
|
||||
}
|
||||
|
||||
private void updateOrientations()
|
||||
{
|
||||
UIInterfaceOrientation currentOrientation = appDelegate.CurrentOrientation;
|
||||
bool lockCurrentOrientation = localUserPlaying.Value == LocalUserPlayingState.Playing;
|
||||
bool lockToPortrait = requiresPortraitOrientation.Value;
|
||||
bool isPhone = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone;
|
||||
|
||||
if (lockCurrentOrientation)
|
||||
{
|
||||
if (lockToPortrait && !currentOrientation.IsPortrait())
|
||||
currentOrientation = UIInterfaceOrientation.Portrait;
|
||||
else if (!lockToPortrait && currentOrientation.IsPortrait() && isPhone)
|
||||
currentOrientation = UIInterfaceOrientation.LandscapeRight;
|
||||
|
||||
appDelegate.Orientations = (UIInterfaceOrientationMask)(1 << (int)currentOrientation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lockToPortrait)
|
||||
{
|
||||
UIInterfaceOrientationMask portraitOrientations = UIInterfaceOrientationMask.Portrait;
|
||||
|
||||
if (!isPhone)
|
||||
portraitOrientations |= UIInterfaceOrientationMask.PortraitUpsideDown;
|
||||
|
||||
appDelegate.Orientations = portraitOrientations;
|
||||
return;
|
||||
}
|
||||
|
||||
appDelegate.Orientations = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,10 +15,22 @@ namespace osu.iOS
|
||||
{
|
||||
public partial class OsuGameIOS : OsuGame
|
||||
{
|
||||
private readonly AppDelegate appDelegate;
|
||||
public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString());
|
||||
|
||||
public override bool HideUnlicensedContent => true;
|
||||
|
||||
public OsuGameIOS(AppDelegate appDelegate)
|
||||
{
|
||||
this.appDelegate = appDelegate;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
Add(new IOSOrientationHandler(appDelegate));
|
||||
}
|
||||
|
||||
protected override UpdateManager CreateUpdateManager() => new MobileUpdateNotifier();
|
||||
|
||||
protected override BatteryInfo CreateBatteryInfo() => new IOSBatteryInfo();
|
||||
|
Loading…
Reference in New Issue
Block a user