mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 15:16:38 +09:00
Merge remote-tracking branch 'upstream/master' into selector-hiding
This commit is contained in:
83
osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs
Normal file
83
osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs
Normal file
@ -0,0 +1,83 @@
|
||||
// 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.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
public class BeatmapAvailability : Container
|
||||
{
|
||||
private BeatmapSetInfo beatmapSet;
|
||||
|
||||
private bool downloadDisabled => BeatmapSet?.OnlineInfo.Availability?.DownloadDisabled ?? false;
|
||||
private bool hasExternalLink => !string.IsNullOrEmpty(BeatmapSet?.OnlineInfo.Availability?.ExternalLink);
|
||||
|
||||
private readonly LinkFlowContainer textContainer;
|
||||
|
||||
public BeatmapAvailability()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Padding = new MarginPadding { Top = 10, Right = 20 };
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black.Opacity(0.6f),
|
||||
},
|
||||
textContainer = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 14))
|
||||
{
|
||||
Direction = FillDirection.Full,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(10),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public BeatmapSetInfo BeatmapSet
|
||||
{
|
||||
get => beatmapSet;
|
||||
|
||||
set
|
||||
{
|
||||
if (value == beatmapSet)
|
||||
return;
|
||||
|
||||
beatmapSet = value;
|
||||
|
||||
if (downloadDisabled || hasExternalLink)
|
||||
{
|
||||
Show();
|
||||
updateText();
|
||||
}
|
||||
else
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateText()
|
||||
{
|
||||
textContainer.Clear();
|
||||
textContainer.AddParagraph(downloadDisabled
|
||||
? "This beatmap is currently not available for download."
|
||||
: "Portions of this beatmap have been removed at the request of the creator or a third-party rights holder.", t => t.Colour = Color4.Orange);
|
||||
|
||||
if (hasExternalLink)
|
||||
{
|
||||
textContainer.NewParagraph();
|
||||
textContainer.NewParagraph();
|
||||
textContainer.AddLink("Check here for more information.", BeatmapSet.OnlineInfo.Availability.ExternalLink, creationParameters: t => t.Font = OsuFont.GetFont(size: 10));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.Direct;
|
||||
using osu.Game.Users;
|
||||
@ -19,7 +20,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet.Buttons
|
||||
{
|
||||
public class DownloadButton : DownloadTrackingComposite, IHasTooltip
|
||||
public class DownloadButton : BeatmapDownloadTrackingComposite, IHasTooltip
|
||||
{
|
||||
private readonly bool noVideo;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -12,6 +13,7 @@ using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online;
|
||||
using osu.Game.Overlays.BeatmapSet.Buttons;
|
||||
using osu.Game.Overlays.Direct;
|
||||
using osuTK;
|
||||
@ -20,7 +22,7 @@ using DownloadButton = osu.Game.Overlays.BeatmapSet.Buttons.DownloadButton;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
public class Header : DownloadTrackingComposite
|
||||
public class Header : BeatmapDownloadTrackingComposite
|
||||
{
|
||||
private const float transition_duration = 200;
|
||||
private const float tabs_height = 50;
|
||||
@ -32,9 +34,12 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
private readonly OsuSpriteText title, artist;
|
||||
private readonly AuthorInfo author;
|
||||
private readonly FillFlowContainer downloadButtonsContainer;
|
||||
private readonly BeatmapAvailability beatmapAvailability;
|
||||
private readonly BeatmapSetOnlineStatusPill onlineStatusPill;
|
||||
public Details Details;
|
||||
|
||||
public bool DownloadButtonsVisible => downloadButtonsContainer.Any();
|
||||
|
||||
public readonly BeatmapPicker Picker;
|
||||
|
||||
private readonly FavouriteButton favouriteButton;
|
||||
@ -99,7 +104,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Top = 20,
|
||||
@ -148,6 +154,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
Margin = new MarginPadding { Top = 20 },
|
||||
Child = author = new AuthorInfo(),
|
||||
},
|
||||
beatmapAvailability = new BeatmapAvailability(),
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -166,13 +173,14 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
},
|
||||
},
|
||||
},
|
||||
loading = new LoadingAnimation
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
}
|
||||
},
|
||||
loading = new LoadingAnimation
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(1.5f),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
@ -213,7 +221,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
|
||||
BeatmapSet.BindValueChanged(setInfo =>
|
||||
{
|
||||
Picker.BeatmapSet = author.BeatmapSet = Details.BeatmapSet = setInfo.NewValue;
|
||||
Picker.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = setInfo.NewValue;
|
||||
cover.BeatmapSet = setInfo.NewValue;
|
||||
|
||||
if (setInfo.NewValue == null)
|
||||
@ -250,11 +258,17 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
if (BeatmapSet.Value == null) return;
|
||||
|
||||
if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false)
|
||||
{
|
||||
downloadButtonsContainer.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (State.Value)
|
||||
{
|
||||
case DownloadState.LocallyAvailable:
|
||||
// temporary for UX until new design is implemented.
|
||||
downloadButtonsContainer.Child = new osu.Game.Overlays.Direct.DownloadButton(BeatmapSet.Value)
|
||||
downloadButtonsContainer.Child = new Direct.DownloadButton(BeatmapSet.Value)
|
||||
{
|
||||
Width = 50,
|
||||
RelativeSizeAxes = Axes.Y
|
||||
|
@ -27,12 +27,10 @@ namespace osu.Game.Overlays
|
||||
public const float TOP_PADDING = 25;
|
||||
public const float RIGHT_WIDTH = 275;
|
||||
|
||||
private readonly Header header;
|
||||
protected readonly Header Header;
|
||||
|
||||
private RulesetStore rulesets;
|
||||
|
||||
private readonly OsuScrollContainer scroll;
|
||||
|
||||
private readonly Bindable<BeatmapSetInfo> beatmapSet = new Bindable<BeatmapSetInfo>();
|
||||
|
||||
// receive input outside our bounds so we can trigger a close event on ourselves.
|
||||
@ -40,6 +38,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
public BeatmapSetOverlay()
|
||||
{
|
||||
OsuScrollContainer scroll;
|
||||
Info info;
|
||||
ScoresContainer scores;
|
||||
|
||||
@ -61,7 +60,7 @@ namespace osu.Game.Overlays
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
header = new Header(),
|
||||
Header = new Header(),
|
||||
info = new Info(),
|
||||
scores = new ScoresContainer(),
|
||||
},
|
||||
@ -69,13 +68,15 @@ namespace osu.Game.Overlays
|
||||
},
|
||||
};
|
||||
|
||||
header.BeatmapSet.BindTo(beatmapSet);
|
||||
Header.BeatmapSet.BindTo(beatmapSet);
|
||||
info.BeatmapSet.BindTo(beatmapSet);
|
||||
|
||||
header.Picker.Beatmap.ValueChanged += b =>
|
||||
Header.Picker.Beatmap.ValueChanged += b =>
|
||||
{
|
||||
info.Beatmap = b.NewValue;
|
||||
scores.Beatmap = b.NewValue;
|
||||
|
||||
scroll.ScrollToStart();
|
||||
};
|
||||
}
|
||||
|
||||
@ -104,7 +105,7 @@ namespace osu.Game.Overlays
|
||||
req.Success += res =>
|
||||
{
|
||||
beatmapSet.Value = res.ToBeatmapSet(rulesets);
|
||||
header.Picker.Beatmap.Value = header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
|
||||
Header.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
|
||||
};
|
||||
API.Queue(req);
|
||||
Show();
|
||||
@ -119,11 +120,14 @@ namespace osu.Game.Overlays
|
||||
Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show an already fully-populated beatmap set.
|
||||
/// </summary>
|
||||
/// <param name="set">The set to show.</param>
|
||||
public void ShowBeatmapSet(BeatmapSetInfo set)
|
||||
{
|
||||
beatmapSet.Value = set;
|
||||
Show();
|
||||
scroll.ScrollTo(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
19
osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs
Normal file
19
osu.Game/Overlays/Direct/BeatmapDownloadTrackingComposite.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// 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.Bindables;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
public abstract class BeatmapDownloadTrackingComposite : DownloadTrackingComposite<BeatmapSetInfo, BeatmapManager>
|
||||
{
|
||||
public Bindable<BeatmapSetInfo> BeatmapSet => Model;
|
||||
|
||||
protected BeatmapDownloadTrackingComposite(BeatmapSetInfo set = null)
|
||||
: base(set)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ namespace osu.Game.Overlays.Direct
|
||||
private const float height = 70;
|
||||
|
||||
private FillFlowContainer statusContainer;
|
||||
protected DownloadButton DownloadButton;
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
|
||||
@ -149,7 +150,7 @@ namespace osu.Game.Overlays.Direct
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Child = new DownloadButton(SetInfo)
|
||||
Child = DownloadButton = new DownloadButton(SetInfo)
|
||||
{
|
||||
Size = new Vector2(height - vertical_padding * 3),
|
||||
Margin = new MarginPadding { Left = vertical_padding * 2, Right = vertical_padding },
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@ -34,6 +35,7 @@ namespace osu.Game.Overlays.Direct
|
||||
|
||||
public PreviewTrack Preview => PlayButton.Preview;
|
||||
public Bindable<bool> PreviewPlaying => PlayButton.Playing;
|
||||
|
||||
protected abstract PlayButton PlayButton { get; }
|
||||
protected abstract Box PreviewBar { get; }
|
||||
|
||||
@ -43,6 +45,8 @@ namespace osu.Game.Overlays.Direct
|
||||
|
||||
protected DirectPanel(BeatmapSetInfo setInfo)
|
||||
{
|
||||
Debug.Assert(setInfo.OnlineBeatmapSetID != null);
|
||||
|
||||
SetInfo = setInfo;
|
||||
}
|
||||
|
||||
@ -117,12 +121,11 @@ namespace osu.Game.Overlays.Direct
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
ShowInformation();
|
||||
Debug.Assert(SetInfo.OnlineBeatmapSetID != null);
|
||||
beatmapSetOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void ShowInformation() => beatmapSetOverlay?.ShowBeatmapSet(SetInfo);
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
@ -9,21 +9,22 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
public class DownloadButton : DownloadTrackingComposite
|
||||
public class DownloadButton : BeatmapDownloadTrackingComposite
|
||||
{
|
||||
protected bool DownloadEnabled => button.Enabled.Value;
|
||||
|
||||
private readonly bool noVideo;
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly SpriteIcon checkmark;
|
||||
private readonly Box background;
|
||||
|
||||
private OsuColour colours;
|
||||
|
||||
private readonly ShakeContainer shakeContainer;
|
||||
|
||||
private readonly OsuAnimatedButton button;
|
||||
|
||||
public DownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false)
|
||||
@ -72,11 +73,18 @@ namespace osu.Game.Overlays.Direct
|
||||
FinishTransforms(true);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(permitNulls: true)]
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colours, OsuGame game, BeatmapManager beatmaps)
|
||||
{
|
||||
this.colours = colours;
|
||||
|
||||
if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false)
|
||||
{
|
||||
button.Enabled.Value = false;
|
||||
button.TooltipText = "This beatmap is currently not available for download.";
|
||||
return;
|
||||
}
|
||||
|
||||
button.Action = () =>
|
||||
{
|
||||
switch (State.Value)
|
||||
|
@ -7,11 +7,12 @@ using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
public class DownloadProgressBar : DownloadTrackingComposite
|
||||
public class DownloadProgressBar : BeatmapDownloadTrackingComposite
|
||||
{
|
||||
private readonly ProgressBar progressBar;
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
// 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.
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
public enum DownloadState
|
||||
{
|
||||
NotDownloaded,
|
||||
Downloading,
|
||||
Downloaded,
|
||||
LocallyAvailable
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
// 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 System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API.Requests;
|
||||
|
||||
namespace osu.Game.Overlays.Direct
|
||||
{
|
||||
/// <summary>
|
||||
/// A component which tracks a beatmap through potential download/import/deletion.
|
||||
/// </summary>
|
||||
public abstract class DownloadTrackingComposite : CompositeDrawable
|
||||
{
|
||||
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
|
||||
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded.
|
||||
/// </summary>
|
||||
protected readonly Bindable<DownloadState> State = new Bindable<DownloadState>();
|
||||
|
||||
protected readonly Bindable<double> Progress = new Bindable<double>();
|
||||
|
||||
protected DownloadTrackingComposite(BeatmapSetInfo beatmapSet = null)
|
||||
{
|
||||
BeatmapSet.Value = beatmapSet;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(BeatmapManager beatmaps)
|
||||
{
|
||||
this.beatmaps = beatmaps;
|
||||
|
||||
BeatmapSet.BindValueChanged(setInfo =>
|
||||
{
|
||||
if (setInfo.NewValue == null)
|
||||
attachDownload(null);
|
||||
else if (beatmaps.GetAllUsableBeatmapSetsEnumerable().Any(s => s.OnlineBeatmapSetID == setInfo.NewValue.OnlineBeatmapSetID))
|
||||
State.Value = DownloadState.LocallyAvailable;
|
||||
else
|
||||
attachDownload(beatmaps.GetExistingDownload(setInfo.NewValue));
|
||||
}, true);
|
||||
|
||||
beatmaps.BeatmapDownloadBegan += download =>
|
||||
{
|
||||
if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID)
|
||||
attachDownload(download);
|
||||
};
|
||||
|
||||
beatmaps.ItemAdded += setAdded;
|
||||
beatmaps.ItemRemoved += setRemoved;
|
||||
}
|
||||
|
||||
#region Disposal
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (beatmaps != null)
|
||||
{
|
||||
beatmaps.BeatmapDownloadBegan -= attachDownload;
|
||||
beatmaps.ItemAdded -= setAdded;
|
||||
}
|
||||
|
||||
State.UnbindAll();
|
||||
|
||||
attachDownload(null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private DownloadBeatmapSetRequest attachedRequest;
|
||||
|
||||
private void attachDownload(DownloadBeatmapSetRequest request)
|
||||
{
|
||||
if (attachedRequest != null)
|
||||
{
|
||||
attachedRequest.Failure -= onRequestFailure;
|
||||
attachedRequest.DownloadProgressed -= onRequestProgress;
|
||||
attachedRequest.Success -= onRequestSuccess;
|
||||
}
|
||||
|
||||
attachedRequest = request;
|
||||
|
||||
if (attachedRequest != null)
|
||||
{
|
||||
if (attachedRequest.Progress == 1)
|
||||
{
|
||||
State.Value = DownloadState.Downloaded;
|
||||
Progress.Value = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
State.Value = DownloadState.Downloading;
|
||||
Progress.Value = attachedRequest.Progress;
|
||||
|
||||
attachedRequest.Failure += onRequestFailure;
|
||||
attachedRequest.DownloadProgressed += onRequestProgress;
|
||||
attachedRequest.Success += onRequestSuccess;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
State.Value = DownloadState.NotDownloaded;
|
||||
}
|
||||
}
|
||||
|
||||
private void onRequestSuccess(string _) => Schedule(() => State.Value = DownloadState.Downloaded);
|
||||
|
||||
private void onRequestProgress(float progress) => Schedule(() => Progress.Value = progress);
|
||||
|
||||
private void onRequestFailure(Exception e) => Schedule(() => attachDownload(null));
|
||||
|
||||
private void setAdded(BeatmapSetInfo s, bool existing) => setDownloadStateFromManager(s, DownloadState.LocallyAvailable);
|
||||
|
||||
private void setRemoved(BeatmapSetInfo s) => setDownloadStateFromManager(s, DownloadState.NotDownloaded);
|
||||
|
||||
private void setDownloadStateFromManager(BeatmapSetInfo s, DownloadState state) => Schedule(() =>
|
||||
{
|
||||
if (s.OnlineBeatmapSetID != BeatmapSet.Value?.OnlineBeatmapSetID)
|
||||
return;
|
||||
|
||||
State.Value = state;
|
||||
});
|
||||
}
|
||||
}
|
@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Music
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BeatmapManager beatmaps, IBindable<WorkingBeatmap> beatmap)
|
||||
{
|
||||
beatmaps.GetAllUsableBeatmapSets().ForEach(b => addBeatmapSet(b, false));
|
||||
beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet);
|
||||
beatmaps.ItemAdded += addBeatmapSet;
|
||||
beatmaps.ItemRemoved += removeBeatmapSet;
|
||||
|
||||
@ -83,11 +83,8 @@ namespace osu.Game.Overlays.Music
|
||||
beatmapBacking.ValueChanged += _ => updateSelectedSet();
|
||||
}
|
||||
|
||||
private void addBeatmapSet(BeatmapSetInfo obj, bool existing) => Schedule(() =>
|
||||
private void addBeatmapSet(BeatmapSetInfo obj) => Schedule(() =>
|
||||
{
|
||||
if (existing)
|
||||
return;
|
||||
|
||||
var newItem = new PlaylistItem(obj) { OnSelect = set => Selected?.Invoke(set) };
|
||||
|
||||
items.Add(newItem);
|
||||
|
@ -218,15 +218,9 @@ namespace osu.Game.Overlays
|
||||
beatmapSets.Insert(index, beatmapSetInfo);
|
||||
}
|
||||
|
||||
private void handleBeatmapAdded(BeatmapSetInfo obj, bool existing)
|
||||
{
|
||||
if (existing)
|
||||
return;
|
||||
private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => beatmapSets.Add(set));
|
||||
|
||||
Schedule(() => beatmapSets.Add(obj));
|
||||
}
|
||||
|
||||
private void handleBeatmapRemoved(BeatmapSetInfo obj) => Schedule(() => beatmapSets.RemoveAll(s => s.ID == obj.ID));
|
||||
private void handleBeatmapRemoved(BeatmapSetInfo set) => Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID));
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
@ -259,6 +253,12 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (pendingBeatmapSwitch != null)
|
||||
{
|
||||
pendingBeatmapSwitch();
|
||||
pendingBeatmapSwitch = null;
|
||||
}
|
||||
|
||||
var track = current?.TrackLoaded ?? false ? current.Track : null;
|
||||
|
||||
if (track?.IsDummyDevice == false)
|
||||
@ -368,15 +368,12 @@ namespace osu.Game.Overlays
|
||||
mod.ApplyToClock(track);
|
||||
}
|
||||
|
||||
private ScheduledDelegate pendingBeatmapSwitch;
|
||||
private Action pendingBeatmapSwitch;
|
||||
|
||||
private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction)
|
||||
{
|
||||
//we might be off-screen when this update comes in.
|
||||
//rather than Scheduling, manually handle this to avoid possible memory contention.
|
||||
pendingBeatmapSwitch?.Cancel();
|
||||
|
||||
pendingBeatmapSwitch = Schedule(delegate
|
||||
// avoid using scheduler as our scheduler may not be run for a long time, holding references to beatmaps.
|
||||
pendingBeatmapSwitch = delegate
|
||||
{
|
||||
// todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync()
|
||||
Task.Run(() =>
|
||||
@ -416,7 +413,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
playerContainer.Add(newBackground);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
|
@ -0,0 +1,66 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Header.Components
|
||||
{
|
||||
public class ProfileRulesetSelector : RulesetSelector
|
||||
{
|
||||
private Color4 accentColour = Color4.White;
|
||||
|
||||
public ProfileRulesetSelector()
|
||||
{
|
||||
TabContainer.Masking = false;
|
||||
TabContainer.Spacing = new Vector2(10, 0);
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
accentColour = colours.Seafoam;
|
||||
|
||||
foreach (TabItem<RulesetInfo> tabItem in TabContainer)
|
||||
((ProfileRulesetTabItem)tabItem).AccentColour = accentColour;
|
||||
}
|
||||
|
||||
public void SetDefaultRuleset(RulesetInfo ruleset)
|
||||
{
|
||||
// Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value
|
||||
foreach (TabItem<RulesetInfo> tabItem in TabContainer)
|
||||
((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID;
|
||||
}
|
||||
|
||||
public void SelectDefaultRuleset()
|
||||
{
|
||||
// Todo: This method shouldn't exist, but bindables don't provide the concept of observing a change to the default value
|
||||
foreach (TabItem<RulesetInfo> tabItem in TabContainer)
|
||||
{
|
||||
if (((ProfileRulesetTabItem)tabItem).IsDefault)
|
||||
{
|
||||
Current.Value = ((ProfileRulesetTabItem)tabItem).Value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override TabItem<RulesetInfo> CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value)
|
||||
{
|
||||
AccentColour = accentColour
|
||||
};
|
||||
|
||||
protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Horizontal,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Header.Components
|
||||
{
|
||||
public class ProfileRulesetTabItem : TabItem<RulesetInfo>, IHasAccentColour
|
||||
{
|
||||
private readonly OsuSpriteText text;
|
||||
private readonly SpriteIcon icon;
|
||||
|
||||
private Color4 accentColour;
|
||||
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get => accentColour;
|
||||
set
|
||||
{
|
||||
if (accentColour == value)
|
||||
return;
|
||||
|
||||
accentColour = value;
|
||||
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
private bool isDefault;
|
||||
|
||||
public bool IsDefault
|
||||
{
|
||||
get => isDefault;
|
||||
set
|
||||
{
|
||||
if (isDefault == value)
|
||||
return;
|
||||
|
||||
isDefault = value;
|
||||
|
||||
icon.FadeTo(isDefault ? 1 : 0, 200, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileRulesetTabItem(RulesetInfo value)
|
||||
: base(value)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(3, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
text = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Text = value.Name,
|
||||
},
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true,
|
||||
Icon = FontAwesome.Solid.Star,
|
||||
Size = new Vector2(12),
|
||||
},
|
||||
}
|
||||
},
|
||||
new HoverClickSounds()
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
base.OnHover(e);
|
||||
updateState();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
updateState();
|
||||
}
|
||||
|
||||
protected override void OnActivated() => updateState();
|
||||
|
||||
protected override void OnDeactivated() => updateState();
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium);
|
||||
|
||||
if (IsHovered || Active.Value)
|
||||
{
|
||||
text.FadeColour(Color4.White, 120, Easing.InQuad);
|
||||
icon.FadeColour(Color4.White, 120, Easing.InQuad);
|
||||
}
|
||||
else
|
||||
{
|
||||
text.FadeColour(AccentColour, 120, Easing.InQuad);
|
||||
icon.FadeColour(AccentColour, 120, Easing.InQuad);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Runtime;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
|
||||
@ -14,37 +12,17 @@ namespace osu.Game.Overlays.Settings.Sections.Debug
|
||||
{
|
||||
protected override string Header => "Garbage Collector";
|
||||
|
||||
private readonly Bindable<LatencyMode> latencyMode = new Bindable<LatencyMode>();
|
||||
private Bindable<GCLatencyMode> configLatencyMode;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(FrameworkDebugConfigManager config)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsEnumDropdown<LatencyMode>
|
||||
{
|
||||
LabelText = "Active mode",
|
||||
Bindable = latencyMode
|
||||
},
|
||||
new SettingsButton
|
||||
{
|
||||
Text = "Force garbage collection",
|
||||
Action = GC.Collect
|
||||
},
|
||||
};
|
||||
|
||||
configLatencyMode = config.GetBindable<GCLatencyMode>(DebugSetting.ActiveGCMode);
|
||||
configLatencyMode.BindValueChanged(mode => latencyMode.Value = (LatencyMode)mode.NewValue, true);
|
||||
latencyMode.BindValueChanged(mode => configLatencyMode.Value = (GCLatencyMode)mode.NewValue);
|
||||
}
|
||||
|
||||
private enum LatencyMode
|
||||
{
|
||||
Batch = GCLatencyMode.Batch,
|
||||
Interactive = GCLatencyMode.Interactive,
|
||||
LowLatency = GCLatencyMode.LowLatency,
|
||||
SustainedLowLatency = GCLatencyMode.SustainedLowLatency
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
BackgroundColour = colours.Gray3;
|
||||
}
|
||||
|
||||
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item);
|
||||
protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item);
|
||||
|
||||
private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem
|
||||
{
|
||||
|
@ -82,13 +82,7 @@ namespace osu.Game.Overlays.Settings.Sections
|
||||
|
||||
private void itemRemoved(SkinInfo s) => Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => i.ID != s.ID).ToArray());
|
||||
|
||||
private void itemAdded(SkinInfo s, bool existing)
|
||||
{
|
||||
if (existing)
|
||||
return;
|
||||
|
||||
Schedule(() => skinDropdown.Items = skinDropdown.Items.Append(s).ToArray());
|
||||
}
|
||||
private void itemAdded(SkinInfo s) => Schedule(() => skinDropdown.Items = skinDropdown.Items.Append(s).ToArray());
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ namespace osu.Game.Overlays
|
||||
});
|
||||
}
|
||||
|
||||
protected override bool DimMainContent => false; // dimming is handled by main overlay
|
||||
|
||||
private class BackButton : OsuClickableContainer, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
private AspectContainer aspect;
|
||||
|
@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
@ -23,6 +24,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
public Action OnHome;
|
||||
|
||||
private ToolbarUserButton userButton;
|
||||
private ToolbarRulesetSelector rulesetSelector;
|
||||
|
||||
protected override bool BlockPositionalInput => false;
|
||||
|
||||
@ -40,7 +42,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuGame osuGame)
|
||||
private void load(OsuGame osuGame, Bindable<RulesetInfo> parentRuleset)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -57,7 +59,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
Action = () => OnHome?.Invoke()
|
||||
},
|
||||
new ToolbarRulesetSelector()
|
||||
rulesetSelector = new ToolbarRulesetSelector()
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
@ -84,6 +86,9 @@ namespace osu.Game.Overlays.Toolbar
|
||||
}
|
||||
};
|
||||
|
||||
// Bound after the selector is added to the hierarchy to give it a chance to load the available rulesets
|
||||
rulesetSelector.Current.BindTo(parentRuleset);
|
||||
|
||||
State.ValueChanged += visibility =>
|
||||
{
|
||||
if (overlayActivationMode.Value == OverlayActivation.Disabled)
|
||||
|
@ -1,58 +0,0 @@
|
||||
// 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.Graphics.Effects;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarRulesetButton : ToolbarButton
|
||||
{
|
||||
private RulesetInfo ruleset;
|
||||
|
||||
public RulesetInfo Ruleset
|
||||
{
|
||||
get => ruleset;
|
||||
set
|
||||
{
|
||||
ruleset = value;
|
||||
|
||||
var rInstance = ruleset.CreateInstance();
|
||||
|
||||
TooltipMain = rInstance.Description;
|
||||
TooltipSub = $"Play some {rInstance.Description}";
|
||||
SetIcon(rInstance.CreateIcon());
|
||||
}
|
||||
}
|
||||
|
||||
public bool Active
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
IconContainer.Colour = Color4.White;
|
||||
IconContainer.EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = new Color4(255, 194, 224, 100),
|
||||
Radius = 15,
|
||||
Roundness = 15,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
IconContainer.Colour = new Color4(255, 194, 224, 255);
|
||||
IconContainer.EdgeEffect = new EdgeEffectParameters();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
IconContainer.Scale *= 1.4f;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +1,43 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
using osuTK.Input;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarRulesetSelector : Container
|
||||
public class ToolbarRulesetSelector : RulesetSelector
|
||||
{
|
||||
private const float padding = 10;
|
||||
|
||||
private readonly FillFlowContainer modeButtons;
|
||||
private readonly Drawable modeButtonLine;
|
||||
private ToolbarRulesetButton activeButton;
|
||||
|
||||
private RulesetStore rulesets;
|
||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
protected Drawable ModeButtonLine { get; private set; }
|
||||
|
||||
public ToolbarRulesetSelector()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
AutoSizeAxes = Axes.X;
|
||||
}
|
||||
|
||||
Children = new[]
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
AddRangeInternal(new[]
|
||||
{
|
||||
new OpaqueBackground(),
|
||||
modeButtons = new FillFlowContainer
|
||||
new OpaqueBackground
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding { Left = padding, Right = padding },
|
||||
Depth = 1,
|
||||
},
|
||||
modeButtonLine = new Container
|
||||
ModeButtonLine = new Container
|
||||
{
|
||||
Size = new Vector2(padding * 2 + ToolbarButton.WIDTH, 3),
|
||||
Anchor = Anchor.BottomLeft,
|
||||
@ -58,35 +50,54 @@ namespace osu.Game.Overlays.Toolbar
|
||||
Radius = 15,
|
||||
Roundness = 15,
|
||||
},
|
||||
Children = new[]
|
||||
Child = new Box
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets, Bindable<RulesetInfo> parentRuleset)
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
this.rulesets = rulesets;
|
||||
base.LoadComplete();
|
||||
|
||||
foreach (var r in rulesets.AvailableRulesets)
|
||||
Current.BindDisabledChanged(disabled => this.FadeColour(disabled ? Color4.Gray : Color4.White, 300), true);
|
||||
Current.BindValueChanged(_ => moveLineToCurrent(), true);
|
||||
}
|
||||
|
||||
private bool hasInitialPosition;
|
||||
|
||||
// Scheduled to allow the flow layout to be computed before the line position is updated
|
||||
private void moveLineToCurrent() => ScheduleAfterChildren(() =>
|
||||
{
|
||||
foreach (var tabItem in TabContainer)
|
||||
{
|
||||
modeButtons.Add(new ToolbarRulesetButton
|
||||
if (tabItem.Value == Current.Value)
|
||||
{
|
||||
Ruleset = r,
|
||||
Action = delegate { ruleset.Value = r; }
|
||||
});
|
||||
ModeButtonLine.MoveToX(tabItem.DrawPosition.X, !hasInitialPosition ? 0 : 200, Easing.OutQuint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ruleset.ValueChanged += rulesetChanged;
|
||||
ruleset.DisabledChanged += disabledChanged;
|
||||
ruleset.BindTo(parentRuleset);
|
||||
}
|
||||
hasInitialPosition = true;
|
||||
});
|
||||
|
||||
public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput;
|
||||
|
||||
public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput;
|
||||
|
||||
public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree;
|
||||
|
||||
protected override TabItem<RulesetInfo> CreateTabItem(RulesetInfo value) => new ToolbarRulesetTabButton(value);
|
||||
|
||||
protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Left = padding, Right = padding },
|
||||
};
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
@ -96,46 +107,13 @@ namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
int requested = e.Key - Key.Number1;
|
||||
|
||||
RulesetInfo found = rulesets.AvailableRulesets.Skip(requested).FirstOrDefault();
|
||||
RulesetInfo found = Rulesets.AvailableRulesets.Skip(requested).FirstOrDefault();
|
||||
if (found != null)
|
||||
ruleset.Value = found;
|
||||
Current.Value = found;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HandleNonPositionalInput => !ruleset.Disabled && base.HandleNonPositionalInput;
|
||||
public override bool HandlePositionalInput => !ruleset.Disabled && base.HandlePositionalInput;
|
||||
|
||||
public override bool PropagatePositionalInputSubTree => !ruleset.Disabled && base.PropagatePositionalInputSubTree;
|
||||
|
||||
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);
|
||||
|
||||
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
||||
{
|
||||
foreach (ToolbarRulesetButton m in modeButtons.Children.Cast<ToolbarRulesetButton>())
|
||||
{
|
||||
bool isActive = m.Ruleset.ID == e.NewValue.ID;
|
||||
m.Active = isActive;
|
||||
if (isActive)
|
||||
activeButton = m;
|
||||
}
|
||||
|
||||
activeMode.Invalidate();
|
||||
}
|
||||
|
||||
private Cached activeMode = new Cached();
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
if (!activeMode.IsValid)
|
||||
{
|
||||
modeButtonLine.MoveToX(activeButton.DrawPosition.X, 200, Easing.OutQuint);
|
||||
activeMode.Validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
76
osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs
Normal file
76
osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.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.Graphics.Effects;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Events;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarRulesetTabButton : TabItem<RulesetInfo>
|
||||
{
|
||||
private readonly RulesetButton ruleset;
|
||||
|
||||
public ToolbarRulesetTabButton(RulesetInfo value)
|
||||
: base(value)
|
||||
{
|
||||
AutoSizeAxes = Axes.X;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Child = ruleset = new RulesetButton
|
||||
{
|
||||
Active = false,
|
||||
};
|
||||
|
||||
var rInstance = value.CreateInstance();
|
||||
|
||||
ruleset.TooltipMain = rInstance.Description;
|
||||
ruleset.TooltipSub = $"Play some {rInstance.Description}";
|
||||
ruleset.SetIcon(rInstance.CreateIcon());
|
||||
}
|
||||
|
||||
protected override void OnActivated() => ruleset.Active = true;
|
||||
|
||||
protected override void OnDeactivated() => ruleset.Active = false;
|
||||
|
||||
private class RulesetButton : ToolbarButton
|
||||
{
|
||||
public bool Active
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
IconContainer.Colour = Color4.White;
|
||||
IconContainer.EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = new Color4(255, 194, 224, 100),
|
||||
Radius = 15,
|
||||
Roundness = 15,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
IconContainer.Colour = new Color4(255, 194, 224, 255);
|
||||
IconContainer.EdgeEffect = new EdgeEffectParameters();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
Parent.Click();
|
||||
return base.OnClick(e);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
IconContainer.Scale *= 1.4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -32,7 +32,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
public void ShowUser(User user, bool fetchOnline = true)
|
||||
{
|
||||
if (user == User.SYSTEM_USER) return;
|
||||
if (user == User.SYSTEM_USER)
|
||||
return;
|
||||
|
||||
Show();
|
||||
|
||||
@ -76,7 +77,7 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
Colour = OsuColour.Gray(34),
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
},
|
||||
});
|
||||
sectionsContainer.SelectedSection.ValueChanged += section =>
|
||||
{
|
||||
|
Reference in New Issue
Block a user