Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add handling for iOS in editor background/audio file selection #30999

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using Foundation;
using osu.Framework.iOS;
using osu.Game.Tests;

namespace osu.Game.Rulesets.Catch.Tests.iOS
{
[Register("AppDelegate")]
public class AppDelegate : GameApplicationDelegate
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.iOS;
using osu.Game.Tests;
using UIKit;

namespace osu.Game.Rulesets.Catch.Tests.iOS
{
public static class Application
public static class Program
{
public static void Main(string[] args)
{
GameApplication.Main(new OsuTestBrowser());
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using Foundation;
using osu.Framework.iOS;
using osu.Game.Tests;

namespace osu.Game.Rulesets.Mania.Tests.iOS
{
[Register("AppDelegate")]
public class AppDelegate : GameApplicationDelegate
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.iOS;
using osu.Game.Tests;
using UIKit;

namespace osu.Game.Rulesets.Mania.Tests.iOS
{
public static class Application
public static class Program
{
public static void Main(string[] args)
{
GameApplication.Main(new OsuTestBrowser());
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using Foundation;
using osu.Framework.iOS;
using osu.Game.Tests;

namespace osu.Game.Rulesets.Osu.Tests.iOS
{
[Register("AppDelegate")]
public class AppDelegate : GameApplicationDelegate
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.iOS;
using osu.Game.Tests;
using UIKit;

namespace osu.Game.Rulesets.Osu.Tests.iOS
{
public static class Application
public static class Program
{
public static void Main(string[] args)
{
GameApplication.Main(new OsuTestBrowser());
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Taiko.Tests.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using Foundation;
using osu.Framework.iOS;
using osu.Game.Tests;

namespace osu.Game.Rulesets.Taiko.Tests.iOS
{
[Register("AppDelegate")]
public class AppDelegate : GameApplicationDelegate
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.iOS;
using osu.Game.Tests;
using UIKit;

namespace osu.Game.Rulesets.Taiko.Tests.iOS
{
public static class Application
public static class Program
{
public static void Main(string[] args)
{
GameApplication.Main(new OsuTestBrowser());
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
14 changes: 14 additions & 0 deletions osu.Game.Tests.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using Foundation;
using osu.Framework.iOS;

namespace osu.Game.Tests.iOS
{
[Register("AppDelegate")]
public class AppDelegate : GameApplicationDelegate
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.iOS;
using UIKit;

namespace osu.Game.Tests.iOS
{
public static class Application
public static class Program
{
public static void Main(string[] args)
{
GameApplication.Main(new OsuTestBrowser());
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}
112 changes: 56 additions & 56 deletions osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;

namespace osu.Game.Graphics.UserInterfaceV2
{
Expand All @@ -38,6 +37,12 @@

private readonly BindableWithCurrent<FileInfo?> current = new BindableWithCurrent<FileInfo?>();

/// <summary>
/// Directly contains the file selected from the popover.
/// This is propagated to <see cref="Current"/> through <see cref="OnFileSelected"/>.
/// </summary>
protected Bindable<FileInfo?> InternalSelection { get; } = new Bindable<FileInfo?>();

public IEnumerable<string> HandledExtensions => handledExtensions;

private readonly string[] handledExtensions;
Expand Down Expand Up @@ -82,13 +87,17 @@
[Resolved]
private OsuGameBase game { get; set; } = null!;

private ISystemFileSelector? systemFileSelector;

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Code Quality

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Code Quality

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Windows, windows-latest, SingleThread)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Windows, windows-latest, SingleThread)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Build only (iOS)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Build only (iOS)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Windows, windows-latest, MultiThreaded)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Windows, windows-latest, MultiThreaded)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Build only (Android)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Build only (Android)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Linux, ubuntu-latest, SingleThread)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Linux, ubuntu-latest, SingleThread)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Linux, ubuntu-latest, MultiThreaded)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 90 in osu.Game/Graphics/UserInterfaceV2/FormFileSelector.cs

View workflow job for this annotation

GitHub Actions / Test (Linux, ubuntu-latest, MultiThreaded)

The type or namespace name 'ISystemFileSelector' could not be found (are you missing a using directive or an assembly reference?)

protected virtual bool IsPopoverVisible => popoverState.Value == Visibility.Visible;

public FormFileSelector(params string[] handledExtensions)
{
this.handledExtensions = handledExtensions;
}

[BackgroundDependencyLoader]
private void load()
private void load(GameHost host)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Expand Down Expand Up @@ -157,63 +166,85 @@
},
},
};

systemFileSelector = host.CreateSystemFileSelector(handledExtensions);
}

protected override void LoadComplete()
{
base.LoadComplete();

popoverState.BindValueChanged(_ => updateState());
current.BindDisabledChanged(_ => updateState());
popoverState.BindValueChanged(_ => UpdateState());
current.BindDisabledChanged(_ => UpdateState());
current.BindValueChanged(_ =>
{
updateState();
onFileSelected();
UpdateState();
onCurrentChanged();
}, true);

InternalSelection.BindValueChanged(_ => OnFileSelected());

if (systemFileSelector != null)
systemFileSelector.Selected += f => Schedule(() => InternalSelection.Value = f);

FinishTransforms(true);
game.RegisterImportHandler(this);
}

private void onFileSelected()
private void onCurrentChanged()
{
if (Current.Value != null)
this.HidePopover();

initialChooserPath = Current.Value?.DirectoryName;
placeholderText.Alpha = Current.Value == null ? 1 : 0;
filenameText.Text = Current.Value?.Name ?? string.Empty;
background.FlashColour(ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Dark2), 800, Easing.OutQuint);
}

/// <summary>
/// Triggered when a file is selected from the popover. This propagates selection specified in <see cref="InternalSelection"/> to <see cref="Current"/>.
/// This can be overriden to include extra dialogs before setting <see cref="Current"/>.
/// </summary>
protected virtual void OnFileSelected()
{
if (InternalSelection.Value == null)
return;

Current.Value = InternalSelection.Value;
this.HidePopover();
}

protected override bool OnClick(ClickEvent e)
{
this.ShowPopover();
if (systemFileSelector != null)
systemFileSelector.Present();
else
this.ShowPopover();

return true;
}

protected override bool OnHover(HoverEvent e)
{
updateState();
UpdateState();
return true;
}

protected override void OnHoverLost(HoverLostEvent e)
{
base.OnHoverLost(e);
updateState();
UpdateState();
}

private void updateState()
public void UpdateState()
{
caption.Colour = Current.Disabled ? colourProvider.Foreground1 : colourProvider.Content2;
filenameText.Colour = Current.Disabled || Current.Value == null ? colourProvider.Foreground1 : colourProvider.Content1;

if (!Current.Disabled)
{
BorderThickness = IsHovered || popoverState.Value == Visibility.Visible ? 2 : 0;
BorderColour = popoverState.Value == Visibility.Visible ? colourProvider.Highlight1 : colourProvider.Light4;
BorderThickness = IsHovered || IsPopoverVisible ? 2 : 0;
BorderColour = IsPopoverVisible ? colourProvider.Highlight1 : colourProvider.Light4;

if (popoverState.Value == Visibility.Visible)
if (IsPopoverVisible)
background.Colour = ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Dark3);
else if (IsHovered)
background.Colour = ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Dark4);
Expand Down Expand Up @@ -242,11 +273,12 @@

Task ICanAcceptFiles.Import(ImportTask[] tasks, ImportParameters parameters) => throw new NotImplementedException();

protected virtual FileChooserPopover CreatePopover(string[] handledExtensions, Bindable<FileInfo?> current, string? chooserPath) => new FileChooserPopover(handledExtensions, current, chooserPath);
protected virtual FileChooserPopover CreatePopover(string[] handledExtensions, Bindable<FileInfo?> current, string? chooserPath) =>
new FileChooserPopover(handledExtensions, current, chooserPath);

public Popover GetPopover()
{
var popover = CreatePopover(handledExtensions, Current, initialChooserPath);
var popover = CreatePopover(handledExtensions, InternalSelection, initialChooserPath);
popoverState.UnbindBindings();
popoverState.BindTo(popover.State);
return popover;
Expand All @@ -257,10 +289,6 @@
protected override string PopInSampleName => "UI/overlay-big-pop-in";
protected override string PopOutSampleName => "UI/overlay-big-pop-out";

private readonly Bindable<FileInfo?> current = new Bindable<FileInfo?>();

protected OsuFileSelector FileSelector;

public FileChooserPopover(string[] handledExtensions, Bindable<FileInfo?> current, string? chooserPath)
: base(false)
{
Expand All @@ -270,48 +298,20 @@
// simplest solution to avoid underlying text to bleed through the bottom border
// https://github.com/ppy/osu/pull/30005#issuecomment-2378884430
Padding = new MarginPadding { Bottom = 1 },
Child = FileSelector = new OsuFileSelector(chooserPath, handledExtensions)
Child = new OsuFileSelector(chooserPath, handledExtensions)
{
RelativeSizeAxes = Axes.Both,
},
CurrentFile = { BindTarget = current },
}
};

this.current.BindTo(current);
}

[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
Add(new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = 2,
CornerRadius = 10,
BorderColour = colourProvider.Highlight1,
Children = new Drawable[]
{
new Box
{
Colour = Color4.Transparent,
RelativeSizeAxes = Axes.Both,
},
}
});
}

protected override void LoadComplete()
{
base.LoadComplete();

FileSelector.CurrentFile.ValueChanged += f =>
{
if (f.NewValue != null)
OnFileSelected(f.NewValue);
};
Body.BorderColour = colourProvider.Highlight1;
Body.BorderThickness = 2;
}

protected virtual void OnFileSelected(FileInfo file) => current.Value = file;
}
}
}
Loading
Loading