Merge branch 'master' into generic-download-model-manager

This commit is contained in:
Dean Herbert
2019-06-24 18:35:58 +09:00
committed by GitHub
185 changed files with 9501 additions and 1557 deletions

View File

@ -6,7 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics.Effects;

View File

@ -45,7 +45,7 @@ namespace osu.Game.Overlays.BeatmapSet
ExternalLinkButton externalLink;
RelativeSizeAxes = Axes.X;
Height = 400;
AutoSizeAxes = Axes.Y;
Masking = true;
EdgeEffect = new EdgeEffectParameters
@ -72,7 +72,8 @@ namespace osu.Game.Overlays.BeatmapSet
},
new Container
{
RelativeSizeAxes = Axes.Both,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Top = tabs_height },
Children = new Drawable[]
{
@ -84,6 +85,7 @@ namespace osu.Game.Overlays.BeatmapSet
cover = new UpdateableBeatmapSetCover
{
RelativeSizeAxes = Axes.Both,
Masking = true,
},
new Box
{
@ -94,18 +96,26 @@ namespace osu.Game.Overlays.BeatmapSet
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = BeatmapSetOverlay.X_PADDING },
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding
{
Top = 20,
Bottom = 30,
Left = BeatmapSetOverlay.X_PADDING,
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
},
Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = 113,
AutoSizeAxes = Axes.Y,
Child = Picker = new BeatmapPicker(),
},
new FillFlowContainer
@ -158,7 +168,7 @@ namespace osu.Game.Overlays.BeatmapSet
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Right = BeatmapSetOverlay.X_PADDING },
Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING },
Direction = FillDirection.Vertical,
Spacing = new Vector2(10),
Children = new Drawable[]

View File

@ -13,7 +13,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Online.Leaderboards;
using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
using osuTK.Graphics;
@ -103,7 +103,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Text = $"#{index + 1}",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
},
new DrawableRank(score.Rank)
new UpdateableRank(score.Rank)
{
Size = new Vector2(30, 20)
},
@ -135,7 +135,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Spacing = new Vector2(5, 0),
Children = new Drawable[]
{
new DrawableFlag(score.User.Country) { Size = new Vector2(20, 13) },
new UpdateableFlag(score.User.Country)
{
Size = new Vector2(20, 13),
ShowPlaceholderOnNull = false,
},
username
}
},

View File

@ -124,6 +124,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
loading = false;
scoreTable.Scores = scores?.Count > 1 ? scores : new List<ScoreInfo>();
scoreTable.FadeTo(scores?.Count > 1 ? 1 : 0);
if (scores?.Any() == true)
{

View File

@ -13,7 +13,7 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.Leaderboards;
using osu.Game.Scoring;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
using osuTK.Graphics;
@ -22,11 +22,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
public class TopScoreUserSection : CompositeDrawable
{
private readonly SpriteText rankText;
private readonly DrawableRank rank;
private readonly UpdateableRank rank;
private readonly UpdateableAvatar avatar;
private readonly LinkFlowContainer usernameText;
private readonly SpriteText date;
private readonly DrawableFlag flag;
private readonly UpdateableFlag flag;
public TopScoreUserSection()
{
@ -46,7 +46,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Text = "#1",
Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true)
},
rank = new DrawableRank(ScoreRank.D)
rank = new UpdateableRank(ScoreRank.D)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -67,6 +67,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Offset = new Vector2(0, 2),
Radius = 1,
},
ShowGuestOnNull = false,
},
new FillFlowContainer
{
@ -89,11 +90,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold)
},
flag = new DrawableFlag
flag = new UpdateableFlag
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(20, 13),
ShowPlaceholderOnNull = false,
},
}
}
@ -121,7 +123,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
usernameText.Clear();
usernameText.AddUserLink(value.User);
rank.UpdateRank(value.Rank);
rank.Rank = value.Rank;
}
}
}

View File

@ -24,6 +24,7 @@ namespace osu.Game.Overlays
private const int fade_duration = 300;
public const float X_PADDING = 40;
public const float TOP_PADDING = 25;
public const float RIGHT_WIDTH = 275;
private readonly Header header;

View File

@ -74,17 +74,12 @@ namespace osu.Game.Overlays.Chat
}
}
private bool senderHasBackground => !string.IsNullOrEmpty(message.Sender.Colour);
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
customUsernameColour = colours.ChatBlue;
}
private bool senderHasBackground => !string.IsNullOrEmpty(message.Sender.Colour);
protected override void LoadComplete()
{
base.LoadComplete();
bool hasBackground = senderHasBackground;
@ -179,6 +174,11 @@ namespace osu.Game.Overlays.Chat
};
updateMessageContent();
}
protected override void LoadComplete()
{
base.LoadComplete();
FinishTransforms(true);
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -17,15 +18,18 @@ namespace osu.Game.Overlays.Chat
public class DrawableChannel : Container
{
public readonly Channel Channel;
protected readonly ChatLineContainer ChatLineFlow;
private readonly OsuScrollContainer scroll;
protected ChatLineContainer ChatLineFlow;
private OsuScrollContainer scroll;
public DrawableChannel(Channel channel)
{
Channel = channel;
RelativeSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
scroll = new OsuScrollContainer
@ -48,18 +52,17 @@ namespace osu.Game.Overlays.Chat
},
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
newMessagesArrived(Channel.Messages);
Channel.NewMessagesArrived += newMessagesArrived;
Channel.MessageRemoved += messageRemoved;
Channel.PendingMessageResolved += pendingMessageResolved;
}
protected override void LoadComplete()
{
base.LoadComplete();
scrollToEnd();
}

View File

@ -10,7 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Online.Chat;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
namespace osu.Game.Overlays.Chat.Tabs
@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Chat.Tabs
if (value.Type != ChannelType.PM)
throw new ArgumentException("Argument value needs to have the targettype user!");
Avatar avatar;
DrawableAvatar avatar;
AddRange(new Drawable[]
{
@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Chat.Tabs
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Masking = true,
Child = new DelayedLoadWrapper(avatar = new Avatar(value.Users.First())
Child = new DelayedLoadWrapper(avatar = new DrawableAvatar(value.Users.First())
{
RelativeSizeAxes = Axes.Both,
OpenOnClick = { Value = false },

View File

@ -31,12 +31,13 @@ namespace osu.Game.Overlays
private ChannelManager channelManager;
private readonly Container<DrawableChannel> currentChannelContainer;
private Container<DrawableChannel> currentChannelContainer;
private readonly List<DrawableChannel> loadedChannels = new List<DrawableChannel>();
private readonly LoadingAnimation loading;
private LoadingAnimation loading;
private readonly FocusedTextBox textbox;
private FocusedTextBox textbox;
private const int transition_length = 500;
@ -44,17 +45,17 @@ namespace osu.Game.Overlays
public const float TAB_AREA_HEIGHT = 50;
private readonly ChannelTabControl channelTabControl;
private ChannelTabControl channelTabControl;
private readonly Container chatContainer;
private readonly TabsArea tabsArea;
private readonly Box chatBackground;
private readonly Box tabBackground;
private Container chatContainer;
private TabsArea tabsArea;
private Box chatBackground;
private Box tabBackground;
public Bindable<double> ChatHeight { get; set; }
private readonly Container channelSelectionContainer;
private readonly ChannelSelectionOverlay channelSelectionOverlay;
private Container channelSelectionContainer;
private ChannelSelectionOverlay channelSelectionOverlay;
public override bool Contains(Vector2 screenSpacePos) => chatContainer.ReceivePositionalInputAt(screenSpacePos) || (channelSelectionOverlay.State.Value == Visibility.Visible && channelSelectionOverlay.ReceivePositionalInputAt(screenSpacePos));
@ -64,7 +65,11 @@ namespace osu.Game.Overlays
RelativePositionAxes = Axes.Both;
Anchor = Anchor.BottomLeft;
Origin = Anchor.BottomLeft;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, OsuColour colours, ChannelManager channelManager)
{
const float padding = 5;
Children = new Drawable[]
@ -154,7 +159,7 @@ namespace osu.Game.Overlays
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
OnRequestLeave = channel => channelManager.LeaveChannel(channel)
OnRequestLeave = channelManager.LeaveChannel
},
}
},
@ -166,7 +171,7 @@ namespace osu.Game.Overlays
channelTabControl.ChannelSelectorActive.ValueChanged += active => channelSelectionOverlay.State.Value = active.NewValue ? Visibility.Visible : Visibility.Hidden;
channelSelectionOverlay.State.ValueChanged += state =>
{
if (state.NewValue == Visibility.Hidden && channelManager.CurrentChannel.Value == null)
if (state.NewValue == Visibility.Hidden && channelManager.JoinedChannels.Count == 0)
{
channelSelectionOverlay.Show();
Hide();
@ -186,9 +191,45 @@ namespace osu.Game.Overlays
};
channelSelectionOverlay.OnRequestJoin = channel => channelManager.JoinChannel(channel);
channelSelectionOverlay.OnRequestLeave = channel => channelManager.LeaveChannel(channel);
channelSelectionOverlay.OnRequestLeave = channelManager.LeaveChannel;
ChatHeight = config.GetBindable<double>(OsuSetting.ChatDisplayHeight);
ChatHeight.ValueChanged += height =>
{
chatContainer.Height = (float)height.NewValue;
channelSelectionContainer.Height = 1f - (float)height.NewValue;
tabBackground.FadeTo(height.NewValue == 1 ? 1 : 0.8f, 200);
};
ChatHeight.TriggerChange();
chatBackground.Colour = colours.ChatBlue;
this.channelManager = channelManager;
loading.Show();
// This is a relatively expensive (and blocking) operation.
// Scheduling it ensures that it won't be performed unless the user decides to open chat.
// TODO: Refactor OsuFocusedOverlayContainer / OverlayContainer to support delayed content loading.
Schedule(() =>
{
// TODO: consider scheduling bindable callbacks to not perform when overlay is not present.
channelManager.JoinedChannels.ItemsAdded += onChannelAddedToJoinedChannels;
channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels;
foreach (Channel channel in channelManager.JoinedChannels)
channelTabControl.AddChannel(channel);
channelManager.AvailableChannels.ItemsAdded += availableChannelsChanged;
channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged;
channelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels);
currentChannel = channelManager.CurrentChannel.GetBoundCopy();
currentChannel.BindValueChanged(currentChannelChanged, true);
});
}
private Bindable<Channel> currentChannel;
private void currentChannelChanged(ValueChangedEvent<Channel> e)
{
if (e.NewValue == null)
@ -331,35 +372,6 @@ namespace osu.Game.Overlays
base.PopOut();
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, OsuColour colours, ChannelManager channelManager)
{
ChatHeight = config.GetBindable<double>(OsuSetting.ChatDisplayHeight);
ChatHeight.ValueChanged += height =>
{
chatContainer.Height = (float)height.NewValue;
channelSelectionContainer.Height = 1f - (float)height.NewValue;
tabBackground.FadeTo(height.NewValue == 1 ? 1 : 0.8f, 200);
};
ChatHeight.TriggerChange();
chatBackground.Colour = colours.ChatBlue;
loading.Show();
this.channelManager = channelManager;
channelManager.CurrentChannel.ValueChanged += currentChannelChanged;
channelManager.JoinedChannels.ItemsAdded += onChannelAddedToJoinedChannels;
channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels;
channelManager.AvailableChannels.ItemsAdded += availableChannelsChanged;
channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged;
//for the case that channelmanager was faster at fetching the channels than our attachment to CollectionChanged.
channelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels);
foreach (Channel channel in channelManager.JoinedChannels)
channelTabControl.AddChannel(channel);
}
private void onChannelAddedToJoinedChannels(IEnumerable<Channel> channels)
{
foreach (Channel channel in channels)

View File

@ -134,9 +134,9 @@ namespace osu.Game.Overlays.Dialog
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Position = new Vector2(0f, -50f),
Direction = FillDirection.Vertical,
Spacing = new Vector2(0f, 10f),
Padding = new MarginPadding { Bottom = 10 },
Children = new Drawable[]
{
new Container
@ -144,10 +144,6 @@ namespace osu.Game.Overlays.Dialog
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Size = ringSize,
Margin = new MarginPadding
{
Bottom = 30,
},
Children = new Drawable[]
{
ring = new CircularContainer
@ -181,15 +177,15 @@ namespace osu.Game.Overlays.Dialog
Anchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding(15),
TextAnchor = Anchor.TopCentre,
},
body = new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 18))
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
TextAnchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding(15),
TextAnchor = Anchor.TopCentre,
},
},
},

View File

@ -13,9 +13,10 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
@ -47,7 +48,7 @@ namespace osu.Game.Overlays.KeyBinding
public bool FilteringActive { get; set; }
private OsuSpriteText text;
private OsuTextFlowContainer pressAKey;
private Drawable pressAKey;
private FillFlowContainer<KeyButton> buttons;
@ -80,7 +81,7 @@ namespace osu.Game.Overlays.KeyBinding
Hollow = true,
};
Children = new Drawable[]
Children = new[]
{
new Box
{
@ -99,15 +100,19 @@ namespace osu.Game.Overlays.KeyBinding
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
},
pressAKey = new OsuTextFlowContainer
pressAKey = new FillFlowContainer
{
Text = "Press a key to change binding, Shift+Delete to delete, Escape to cancel.",
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding(padding),
Padding = new MarginPadding { Top = height },
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding(padding) { Top = height + padding * 2 },
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Alpha = 0,
Colour = colours.YellowDark
Spacing = new Vector2(5),
Children = new Drawable[]
{
new CancelButton { Action = finalise },
new ClearButton { Action = clear },
},
}
};
@ -205,21 +210,6 @@ namespace osu.Game.Overlays.KeyBinding
if (!HasFocus)
return false;
switch (e.Key)
{
case Key.Delete:
{
if (e.ShiftPressed)
{
bindTarget.UpdateKeyCombination(InputKey.None);
finalise();
return true;
}
break;
}
}
bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState));
if (!isModifier(e.Key)) finalise();
@ -254,6 +244,12 @@ namespace osu.Game.Overlays.KeyBinding
return true;
}
private void clear()
{
bindTarget.UpdateKeyCombination(InputKey.None);
finalise();
}
private void finalise()
{
if (bindTarget != null)
@ -300,6 +296,41 @@ namespace osu.Game.Overlays.KeyBinding
if (bindTarget != null) bindTarget.IsBinding = true;
}
private class CancelButton : TriangleButton
{
public CancelButton()
{
Text = "Cancel";
Size = new Vector2(80, 20);
}
}
private class ClearButton : TriangleButton
{
public ClearButton()
{
Text = "Clear";
Size = new Vector2(80, 20);
}
protected override bool OnMouseUp(MouseUpEvent e)
{
base.OnMouseUp(e);
// without this, the mouse up triggers a finalise (and deselection) of the current binding target.
return true;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.Pink;
Triangles.ColourDark = colours.PinkDark;
Triangles.ColourLight = colours.PinkLight;
}
}
private class KeyButton : Container
{
public readonly Framework.Input.Bindings.KeyBinding KeyBinding;

View File

@ -60,7 +60,7 @@ namespace osu.Game.Overlays.KeyBinding
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Text = "Reset";
Text = "Reset all bindings in section";
RelativeSizeAxes = Axes.X;
Margin = new MarginPadding { Top = 5 };
Height = 20;

View File

@ -10,6 +10,7 @@ using osu.Game.Rulesets.Mods;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
@ -33,6 +34,13 @@ namespace osu.Game.Overlays.Mods
public IEnumerable<Mod> SelectedMods => buttons.Select(b => b.SelectedMod).Where(m => m != null);
private CancellationTokenSource modsLoadCts;
/// <summary>
/// True when all mod icons have completed loading.
/// </summary>
public bool ModIconsLoaded { get; private set; } = true;
public IEnumerable<Mod> Mods
{
set
@ -48,8 +56,28 @@ namespace osu.Game.Overlays.Mods
};
}).ToArray();
ButtonsContainer.Children = modContainers;
modsLoadCts?.Cancel();
ModIconsLoaded = false;
LoadComponentsAsync(modContainers, c =>
{
ModIconsLoaded = true;
ButtonsContainer.ChildrenEnumerable = c;
}, (modsLoadCts = new CancellationTokenSource()).Token);
buttons = modContainers.OfType<ModButton>().ToArray();
if (value.Any())
{
headerLabel.FadeIn(200);
this.FadeIn(200);
}
else
{
// transition here looks weird as mods instantly disappear.
headerLabel.Hide();
Hide();
}
}
}

View File

@ -172,6 +172,8 @@ namespace osu.Game.Overlays.Mods
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 10f),
Width = content_width,
LayoutDuration = 200,
LayoutEasing = Easing.OutQuint,
Children = new ModSection[]
{
new DifficultyReductionSection { Action = modButtonPressed },

View File

@ -70,9 +70,6 @@ namespace osu.Game.Overlays
{
Width = 400;
Margin = new MarginPadding(10);
// required to let MusicController handle beatmap cycling.
AlwaysPresent = true;
}
[BackgroundDependencyLoader]
@ -349,18 +346,11 @@ namespace osu.Game.Overlays
direction = last > next ? TransformDirection.Prev : TransformDirection.Next;
}
//current.Track.Completed -= currentTrackCompleted;
}
current = beatmap.NewValue;
if (current != null)
current.Track.Completed += currentTrackCompleted;
progressBar.CurrentTime = 0;
updateDisplay(current, direction);
updateDisplay(current = beatmap.NewValue, direction);
updateAudioAdjustments();
queuedDirection = null;
@ -378,12 +368,6 @@ namespace osu.Game.Overlays
mod.ApplyToClock(track);
}
private void currentTrackCompleted() => Schedule(() =>
{
if (!current.Track.Looping && !beatmap.Disabled && beatmapSets.Any())
next();
});
private ScheduledDelegate pendingBeatmapSwitch;
private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction)
@ -447,10 +431,6 @@ namespace osu.Game.Overlays
{
base.PopOut();
// This is here mostly as a performance fix.
// If the playlist is not hidden it will update children even when the music controller is hidden (due to AlwaysPresent).
playlist.Hide();
this.FadeOut(transition_length, Easing.OutQuint);
dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint);
}
@ -548,5 +528,10 @@ namespace osu.Game.Overlays
return base.OnDragEnd(e);
}
}
/// <summary>
/// Play the next random or playlist track.
/// </summary>
public void NextTrack() => next();
}
}

View File

@ -35,8 +35,6 @@ namespace osu.Game.Overlays
Width = width;
RelativeSizeAxes = Axes.Y;
AlwaysPresent = true;
Children = new Drawable[]
{
new Box
@ -58,16 +56,12 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.X,
Children = new[]
{
new NotificationSection
new NotificationSection(@"Notifications", @"Clear All")
{
Title = @"Notifications",
ClearText = @"Clear All",
AcceptTypes = new[] { typeof(SimpleNotification) }
},
new NotificationSection
new NotificationSection(@"Running Tasks", @"Cancel All")
{
Title = @"Running Tasks",
ClearText = @"Cancel All",
AcceptTypes = new[] { typeof(ProgressNotification) }
}
}
@ -100,9 +94,6 @@ namespace osu.Game.Overlays
OverlayActivationMode.BindValueChanged(_ => updateProcessingMode(), true);
}
private int totalCount => sections.Select(c => c.DisplayedCount).Sum();
private int unreadCount => sections.Select(c => c.UnreadCount).Sum();
public readonly BindableInt UnreadCount = new BindableInt();
private int runningDepth;
@ -111,6 +102,8 @@ namespace osu.Game.Overlays
private readonly Scheduler postScheduler = new Scheduler();
public override bool IsPresent => base.IsPresent || postScheduler.HasPendingTasks;
private bool processingPosts = true;
public void Post(Notification notification) => postScheduler.Add(() =>
@ -160,7 +153,7 @@ namespace osu.Game.Overlays
private void updateCounts()
{
UnreadCount.Value = unreadCount;
UnreadCount.Value = sections.Select(c => c.UnreadCount).Sum();
}
private void markAllRead()

View File

@ -17,10 +17,7 @@ namespace osu.Game.Overlays.Notifications
{
public class NotificationSection : AlwaysUpdateFillFlowContainer<Drawable>
{
private OsuSpriteText titleText;
private OsuSpriteText countText;
private ClearAllButton clearButton;
private OsuSpriteText countDrawable;
private FlowContainer<Notification> notifications;
@ -35,28 +32,14 @@ namespace osu.Game.Overlays.Notifications
public IEnumerable<Type> AcceptTypes;
private string clearText;
private readonly string clearButtonText;
public string ClearText
private readonly string titleText;
public NotificationSection(string title, string clearButtonText)
{
get => clearText;
set
{
clearText = value;
if (clearButton != null) clearButton.Text = clearText;
}
}
private string title;
public string Title
{
get => title;
set
{
title = value;
if (titleText != null) titleText.Text = title.ToUpperInvariant();
}
this.clearButtonText = clearButtonText;
titleText = title;
}
[BackgroundDependencyLoader]
@ -82,9 +65,9 @@ namespace osu.Game.Overlays.Notifications
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
clearButton = new ClearAllButton
new ClearAllButton
{
Text = clearText,
Text = clearButtonText,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Action = clearAll
@ -99,12 +82,12 @@ namespace osu.Game.Overlays.Notifications
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
titleText = new OsuSpriteText
new OsuSpriteText
{
Text = title.ToUpperInvariant(),
Text = titleText.ToUpperInvariant(),
Font = OsuFont.GetFont(weight: FontWeight.Black)
},
countText = new OsuSpriteText
countDrawable = new OsuSpriteText
{
Text = "3",
Colour = colours.Yellow,
@ -134,7 +117,7 @@ namespace osu.Game.Overlays.Notifications
{
base.Update();
countText.Text = notifications.Children.Count(c => c.Alpha > 0.99f).ToString();
countDrawable.Text = notifications.Children.Count(c => c.Alpha > 0.99f).ToString();
}
private class ClearAllButton : OsuClickableContainer

View File

@ -23,10 +23,16 @@ namespace osu.Game.Overlays.Notifications
public string CompletionText { get; set; } = "Task has completed!";
private float progress;
public float Progress
{
get => progressBar.Progress;
set => Schedule(() => progressBar.Progress = value);
get => progress;
set
{
progress = value;
Scheduler.AddOnce(() => progressBar.Progress = progress);
}
}
protected override void LoadComplete()
@ -34,59 +40,56 @@ namespace osu.Game.Overlays.Notifications
base.LoadComplete();
//we may have received changes before we were displayed.
State = state;
updateState();
}
private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
public CancellationToken CancellationToken => cancellationTokenSource.Token;
public virtual ProgressNotificationState State
public ProgressNotificationState State
{
get => state;
set =>
Schedule(() =>
{
bool stateChanged = state != value;
state = value;
set
{
if (state == value) return;
if (IsLoaded)
{
switch (state)
{
case ProgressNotificationState.Queued:
Light.Colour = colourQueued;
Light.Pulsate = false;
progressBar.Active = false;
break;
state = value;
case ProgressNotificationState.Active:
Light.Colour = colourActive;
Light.Pulsate = true;
progressBar.Active = true;
break;
if (IsLoaded)
Schedule(updateState);
}
}
case ProgressNotificationState.Cancelled:
cancellationTokenSource.Cancel();
private void updateState()
{
switch (state)
{
case ProgressNotificationState.Queued:
Light.Colour = colourQueued;
Light.Pulsate = false;
progressBar.Active = false;
break;
Light.Colour = colourCancelled;
Light.Pulsate = false;
progressBar.Active = false;
break;
}
}
case ProgressNotificationState.Active:
Light.Colour = colourActive;
Light.Pulsate = true;
progressBar.Active = true;
break;
if (stateChanged)
{
switch (state)
{
case ProgressNotificationState.Completed:
NotificationContent.MoveToY(-DrawSize.Y / 2, 200, Easing.OutQuint);
this.FadeOut(200).Finally(d => Completed());
break;
}
}
});
case ProgressNotificationState.Cancelled:
cancellationTokenSource.Cancel();
Light.Colour = colourCancelled;
Light.Pulsate = false;
progressBar.Active = false;
break;
case ProgressNotificationState.Completed:
NotificationContent.MoveToY(-DrawSize.Y / 2, 200, Easing.OutQuint);
this.FadeOut(200).Finally(d => Completed());
break;
}
}
private ProgressNotificationState state;

View File

@ -1,153 +1,23 @@
// 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.Shapes;
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 osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays
{
public class OverlayHeaderTabControl : TabControl<string>
public class OverlayHeaderTabControl : OverlayTabControl<string>
{
private readonly Box bar;
private Color4 accentColour = Color4.White;
public Color4 AccentColour
protected override TabItem<string> CreateTabItem(string value) => new OverlayHeaderTabItem(value)
{
get => accentColour;
set
{
if (accentColour == value)
return;
accentColour = value;
bar.Colour = value;
foreach (TabItem<string> tabItem in TabContainer)
{
((HeaderTabItem)tabItem).AccentColour = value;
}
}
}
public new MarginPadding Padding
{
get => TabContainer.Padding;
set => TabContainer.Padding = value;
}
public OverlayHeaderTabControl()
{
TabContainer.Masking = false;
TabContainer.Spacing = new Vector2(15, 0);
AddInternal(bar = new Box
{
RelativeSizeAxes = Axes.X,
Height = 2,
Anchor = Anchor.BottomLeft,
Origin = Anchor.CentreLeft
});
}
protected override Dropdown<string> CreateDropdown() => null;
protected override TabItem<string> CreateTabItem(string value) => new HeaderTabItem(value)
{
AccentColour = AccentColour
AccentColour = AccentColour,
};
private class HeaderTabItem : TabItem<string>
private class OverlayHeaderTabItem : OverlayTabItem<string>
{
private readonly OsuSpriteText text;
private readonly ExpandingBar bar;
private Color4 accentColour;
public Color4 AccentColour
{
get => accentColour;
set
{
if (accentColour == value)
return;
accentColour = value;
bar.Colour = value;
updateState();
}
}
public HeaderTabItem(string value)
public OverlayHeaderTabItem(string value)
: base(value)
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
Children = new Drawable[]
{
text = new OsuSpriteText
{
Margin = new MarginPadding { Bottom = 10 },
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Text = value,
Font = OsuFont.GetFont()
},
bar = new ExpandingBar
{
Anchor = Anchor.BottomCentre,
ExpandedSize = 7.5f,
CollapsedSize = 0
},
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()
{
if (Active.Value || IsHovered)
{
text.FadeColour(Color4.White, 120, Easing.InQuad);
bar.Expand();
if (Active.Value)
text.Font = text.Font.With(weight: FontWeight.Bold);
}
else
{
text.FadeColour(AccentColour, 120, Easing.InQuad);
bar.Collapse();
text.Font = text.Font.With(weight: FontWeight.Medium);
}
Text.Text = value;
}
}
}

View File

@ -0,0 +1,163 @@
// 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.Shapes;
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 osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays
{
public abstract class OverlayTabControl<T> : TabControl<T>
{
private readonly Box bar;
private Color4 accentColour = Color4.White;
public Color4 AccentColour
{
get => accentColour;
set
{
if (accentColour == value)
return;
accentColour = value;
bar.Colour = value;
foreach (TabItem<T> tabItem in TabContainer)
{
((OverlayTabItem<T>)tabItem).AccentColour = value;
}
}
}
public new MarginPadding Padding
{
get => TabContainer.Padding;
set => TabContainer.Padding = value;
}
protected OverlayTabControl()
{
TabContainer.Masking = false;
TabContainer.Spacing = new Vector2(15, 0);
AddInternal(bar = new Box
{
RelativeSizeAxes = Axes.X,
Height = 2,
Anchor = Anchor.BottomLeft,
Origin = Anchor.CentreLeft
});
}
protected override Dropdown<T> CreateDropdown() => null;
protected override TabItem<T> CreateTabItem(T value) => new OverlayTabItem<T>(value);
protected class OverlayTabItem<U> : TabItem<U>
{
private readonly ExpandingBar bar;
protected readonly OsuSpriteText Text;
private Color4 accentColour;
public Color4 AccentColour
{
get => accentColour;
set
{
if (accentColour == value)
return;
accentColour = value;
bar.Colour = value;
updateState();
}
}
public OverlayTabItem(U value)
: base(value)
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
Children = new Drawable[]
{
Text = new OsuSpriteText
{
Margin = new MarginPadding { Bottom = 10 },
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Font = OsuFont.GetFont(),
},
bar = new ExpandingBar
{
Anchor = Anchor.BottomCentre,
ExpandedSize = 7.5f,
CollapsedSize = 0
},
new HoverClickSounds()
};
}
protected override bool OnHover(HoverEvent e)
{
base.OnHover(e);
if (!Active.Value)
HoverAction();
return true;
}
protected override void OnHoverLost(HoverLostEvent e)
{
base.OnHoverLost(e);
if (!Active.Value)
UnhoverAction();
}
protected override void OnActivated()
{
HoverAction();
Text.Font = Text.Font.With(weight: FontWeight.Bold);
}
protected override void OnDeactivated()
{
UnhoverAction();
Text.Font = Text.Font.With(weight: FontWeight.Medium);
}
private void updateState()
{
if (Active.Value)
OnActivated();
else
OnDeactivated();
}
protected virtual void HoverAction()
{
bar.Expand();
Text.FadeColour(Color4.White, 120, Easing.InQuad);
}
protected virtual void UnhoverAction()
{
bar.Collapse();
Text.FadeColour(AccentColour, 120, Easing.InQuad);
}
}
}
}

View File

@ -87,7 +87,12 @@ namespace osu.Game.Overlays.Profile.Header
addSpacer(topLinkContainer);
if (user.LastVisit.HasValue)
if (user.IsOnline)
{
topLinkContainer.AddText("Currently online");
addSpacer(topLinkContainer);
}
else if (user.LastVisit.HasValue)
{
topLinkContainer.AddText("Last seen ");
topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden);

View File

@ -116,6 +116,7 @@ namespace osu.Game.Overlays.Profile.Header
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
Children = new[]
{
scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH),

View File

@ -12,6 +12,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Profile.Header.Components;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
namespace osu.Game.Overlays.Profile.Header
@ -27,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Header
private OsuSpriteText usernameText;
private ExternalLinkButton openUserExternally;
private OsuSpriteText titleText;
private DrawableFlag userFlag;
private UpdateableFlag userFlag;
private OsuSpriteText userCountryText;
private FillFlowContainer userStats;
@ -51,7 +52,7 @@ namespace osu.Game.Overlays.Profile.Header
AutoSizeAxes = Axes.X,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Children = new[]
Children = new Drawable[]
{
avatar = new UpdateableAvatar
{
@ -59,6 +60,7 @@ namespace osu.Game.Overlays.Profile.Header
Masking = true,
CornerRadius = avatar_size * 0.25f,
OpenOnClick = { Value = false },
ShowGuestOnNull = false,
},
new Container
{
@ -115,9 +117,10 @@ namespace osu.Game.Overlays.Profile.Header
Margin = new MarginPadding { Top = 5 },
Children = new Drawable[]
{
userFlag = new DrawableFlag
userFlag = new UpdateableFlag
{
Size = new Vector2(30, 20)
Size = new Vector2(30, 20),
ShowPlaceholderOnNull = false,
},
userCountryText = new OsuSpriteText
{

View File

@ -1,25 +1,29 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.Profile
{
public abstract class ProfileSection : FillFlowContainer
public abstract class ProfileSection : Container
{
public abstract string Title { get; }
public abstract string Identifier { get; }
private readonly FillFlowContainer content;
private readonly Box background;
private readonly Box underscore;
protected override Container<Drawable> Content => content;
@ -27,50 +31,109 @@ namespace osu.Game.Overlays.Profile
protected ProfileSection()
{
Direction = FillDirection.Vertical;
AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X;
InternalChildren = new Drawable[]
{
new OsuSpriteText
background = new Box
{
Text = Title,
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Regular, italics: true),
Margin = new MarginPadding
{
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN,
Vertical = 10
}
RelativeSizeAxes = Axes.Both,
},
content = new FillFlowContainer
new SectionTriangles
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
},
new FillFlowContainer
{
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding
Children = new Drawable[]
{
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN,
Bottom = 20
}
},
new Box
{
RelativeSizeAxes = Axes.X,
Height = 1,
Colour = OsuColour.Gray(34),
EdgeSmoothness = new Vector2(1)
new Container
{
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding
{
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN,
Top = 15,
Bottom = 10,
},
Children = new Drawable[]
{
new OsuSpriteText
{
Text = Title,
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold),
},
underscore = new Box
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.TopCentre,
Margin = new MarginPadding { Top = 4 },
RelativeSizeAxes = Axes.X,
Height = 2,
}
}
},
content = new FillFlowContainer
{
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding
{
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN,
Bottom = 20
}
},
},
}
};
}
// placeholder
Add(new OsuSpriteText
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
background.Colour = colours.GreySeafoamDarker;
underscore.Colour = colours.Seafoam;
}
private class SectionTriangles : Container
{
private readonly Triangles triangles;
private readonly Box foreground;
public SectionTriangles()
{
Text = @"coming soon!",
Colour = Color4.Gray,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Margin = new MarginPadding { Top = 100, Bottom = 100 }
});
RelativeSizeAxes = Axes.X;
Height = 100;
Masking = true;
Children = new Drawable[]
{
triangles = new Triangles
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Both,
TriangleScale = 3,
},
foreground = new Box
{
RelativeSizeAxes = Axes.Both,
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
triangles.ColourLight = colours.GreySeafoamDark;
triangles.ColourDark = colours.GreySeafoamDarker.Darken(0.2f);
foreground.Colour = ColourInfo.GradientVertical(colours.GreySeafoamDarker, colours.GreySeafoamDarker.Opacity(0));
}
}
}
}

View File

@ -59,7 +59,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
modsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.5f) });
}
protected override Drawable CreateLeftVisual() => new DrawableRank(Score.Rank)
protected override Drawable CreateLeftVisual() => new UpdateableRank(Score.Rank)
{
RelativeSizeAxes = Axes.Y,
Width = 60,

View File

@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
switch (activity.Type)
{
case RecentActivityType.Rank:
return new DrawableRank(activity.ScoreRank)
return new UpdateableRank(activity.ScoreRank)
{
RelativeSizeAxes = Axes.Y,
Width = 60,

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
@ -12,7 +13,6 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osuTK;
using osuTK.Graphics;
using DebugUtils = osu.Game.Utils.DebugUtils;
namespace osu.Game.Overlays.Settings
{
@ -59,7 +59,7 @@ namespace osu.Game.Overlays.Settings
Text = game.Name,
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold),
},
new BuildDisplay(game.Version, DebugUtils.IsDebug)
new BuildDisplay(game.Version, DebugUtils.IsDebugBuild)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,

View File

@ -63,6 +63,9 @@ namespace osu.Game.Overlays.Settings
set
{
if (bindable != null)
controlWithCurrent?.Current.UnbindFrom(bindable);
bindable = value;
controlWithCurrent?.Current.BindTo(bindable);

View File

@ -0,0 +1,17 @@
// 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.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Settings
{
public class SettingsNumberBox : SettingsItem<string>
{
protected override Drawable CreateControl() => new OsuNumberBox
{
Margin = new MarginPadding { Top = 5 },
RelativeSizeAxes = Axes.X,
};
}
}

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics.Effects;
using osu.Game.Graphics;
using osu.Game.Online.API;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
using osuTK.Graphics;

View File

@ -4,11 +4,11 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Profile;
using osu.Game.Overlays.Profile.Sections;
@ -23,7 +23,7 @@ namespace osu.Game.Overlays
private ProfileSection[] sections;
private GetUserRequest userReq;
protected ProfileHeader Header;
private SectionsContainer<ProfileSection> sectionsContainer;
private ProfileSectionsContainer sectionsContainer;
private ProfileTabControl tabs;
public const float CONTENT_X_MARGIN = 70;
@ -65,12 +65,11 @@ namespace osu.Game.Overlays
Add(new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(0.2f)
Colour = OsuColour.Gray(0.1f)
});
Add(sectionsContainer = new SectionsContainer<ProfileSection>
Add(sectionsContainer = new ProfileSectionsContainer
{
RelativeSizeAxes = Axes.Both,
ExpandableHeader = Header = new ProfileHeader(),
FixedHeader = tabs,
HeaderBackground = new Box
@ -141,31 +140,28 @@ namespace osu.Game.Overlays
}
}
private class ProfileTabControl : PageTabControl<ProfileSection>
private class ProfileTabControl : OverlayTabControl<ProfileSection>
{
private readonly Box bottom;
public ProfileTabControl()
{
TabContainer.RelativeSizeAxes &= ~Axes.X;
TabContainer.AutoSizeAxes |= Axes.X;
TabContainer.Anchor |= Anchor.x1;
TabContainer.Origin |= Anchor.x1;
AddInternal(bottom = new Box
{
RelativeSizeAxes = Axes.X,
Height = 1,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
EdgeSmoothness = new Vector2(1)
});
}
protected override TabItem<ProfileSection> CreateTabItem(ProfileSection value) => new ProfileTabItem(value);
protected override TabItem<ProfileSection> CreateTabItem(ProfileSection value) => new ProfileTabItem(value)
{
AccentColour = AccentColour
};
protected override Dropdown<ProfileSection> CreateDropdown() => null;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.Seafoam;
}
private class ProfileTabItem : PageTabItem
private class ProfileTabItem : OverlayTabItem<ProfileSection>
{
public ProfileTabItem(ProfileSection value)
: base(value)
@ -173,12 +169,22 @@ namespace osu.Game.Overlays
Text.Text = value.Title;
}
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private class ProfileSectionsContainer : SectionsContainer<ProfileSection>
{
public ProfileSectionsContainer()
{
bottom.Colour = colours.Yellow;
RelativeSizeAxes = Axes.Both;
}
protected override FlowContainer<ProfileSection> CreateScrollContentContainer() => new FillFlowContainer<ProfileSection>
{
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Spacing = new Vector2(0, 20),
};
}
}
}