From 8fca0fddb374cc15410eb11945480ce5d7076a4f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 00:52:01 -0300 Subject: [PATCH 01/45] Abstract DirectOverlay layout into base class for Social and osu!direct - BrowseOverlay, initial layout of social browser --- .../Tests/TestCaseSocial.cs | 23 +++ .../osu.Desktop.VisualTests.csproj | 1 + .../UserInterface/PageTabControl.cs} | 24 +-- .../Overlays/Browse/BrowseFilterControl.cs | 111 +++++++++++ osu.Game/Overlays/Browse/BrowseHeader.cs | 96 ++++++++++ osu.Game/Overlays/Browse/BrowseOverlay.cs | 126 +++++++++++++ .../Overlays/Browse/DisplayStyleControl.cs | 102 ++++++++++ osu.Game/Overlays/Browse/HeaderTabControl.cs | 28 +++ .../{Direct => Browse}/SlimEnumDropdown.cs | 6 +- osu.Game/Overlays/Direct/FilterControl.cs | 175 +++--------------- osu.Game/Overlays/Direct/Header.cs | 98 +--------- osu.Game/Overlays/DirectOverlay.cs | 142 ++++---------- osu.Game/Overlays/Social/FilterControl.cs | 15 ++ osu.Game/Overlays/Social/Header.cs | 51 +++++ osu.Game/Overlays/SocialOverlay.cs | 44 +++++ osu.Game/osu.Game.csproj | 12 +- 16 files changed, 683 insertions(+), 371 deletions(-) create mode 100644 osu.Desktop.VisualTests/Tests/TestCaseSocial.cs rename osu.Game/{Overlays/Direct/SortTabControl.cs => Graphics/UserInterface/PageTabControl.cs} (80%) create mode 100644 osu.Game/Overlays/Browse/BrowseFilterControl.cs create mode 100644 osu.Game/Overlays/Browse/BrowseHeader.cs create mode 100644 osu.Game/Overlays/Browse/BrowseOverlay.cs create mode 100644 osu.Game/Overlays/Browse/DisplayStyleControl.cs create mode 100644 osu.Game/Overlays/Browse/HeaderTabControl.cs rename osu.Game/Overlays/{Direct => Browse}/SlimEnumDropdown.cs (89%) create mode 100644 osu.Game/Overlays/Social/FilterControl.cs create mode 100644 osu.Game/Overlays/Social/Header.cs create mode 100644 osu.Game/Overlays/SocialOverlay.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs new file mode 100644 index 0000000000..8fee8e6887 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Testing; +using osu.Game.Overlays; + +namespace osu.Desktop.VisualTests.Tests +{ + public class TestCaseSocial : TestCase + { + public override string Description => @"social browser overlay"; + + public override void Reset() + { + base.Reset(); + + SocialOverlay s = new SocialOverlay(); + Add(s); + + AddStep(@"toggle", s.ToggleVisibility); + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 7b7997063b..0b8b4f2105 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -223,6 +223,7 @@ + diff --git a/osu.Game/Overlays/Direct/SortTabControl.cs b/osu.Game/Graphics/UserInterface/PageTabControl.cs similarity index 80% rename from osu.Game/Overlays/Direct/SortTabControl.cs rename to osu.Game/Graphics/UserInterface/PageTabControl.cs index 4d4e02d875..8bf455b099 100644 --- a/osu.Game/Overlays/Direct/SortTabControl.cs +++ b/osu.Game/Graphics/UserInterface/PageTabControl.cs @@ -10,22 +10,20 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; -using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -namespace osu.Game.Overlays.Direct +namespace osu.Game.Graphics.UserInterface { - public class SortTabControl : OsuTabControl + public class PageTabControl : OsuTabControl { - protected override TabItem CreateTabItem(SortCriteria value) => new SortTabItem(value); + protected override TabItem CreateTabItem(T value) => new PageTabItem(value); - public SortTabControl() + public PageTabControl() { Height = 30; } - private class SortTabItem : TabItem + private class PageTabItem : TabItem { private const float transition_duration = 100; @@ -46,7 +44,7 @@ namespace osu.Game.Overlays.Direct } } - public SortTabItem(SortCriteria value) : base(value) + public PageTabItem(T value) : base(value) { AutoSizeAxes = Axes.X; RelativeSizeAxes = Axes.Y; @@ -104,14 +102,4 @@ namespace osu.Game.Overlays.Direct } } } - - public enum SortCriteria - { - Title, - Artist, - Creator, - Difficulty, - Ranked, - Rating, - } } diff --git a/osu.Game/Overlays/Browse/BrowseFilterControl.cs b/osu.Game/Overlays/Browse/BrowseFilterControl.cs new file mode 100644 index 0000000000..fe61771f5b --- /dev/null +++ b/osu.Game/Overlays/Browse/BrowseFilterControl.cs @@ -0,0 +1,111 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Browse +{ + public abstract class BrowseFilterControl : Container + { + private const float padding = 10; + + private readonly Box tabStrip; + + public readonly SearchTextBox Search; + public readonly PageTabControl Tabs; + + protected abstract Color4 BackgroundColour { get; } + protected abstract T DefaultTab { get; } + protected virtual Drawable CreateControls() => new Container(); //todo: naming + + public BrowseFilterControl() + { + if (!typeof(T).IsEnum) + throw new InvalidOperationException("BrowseFilterControl only supports enums as the generic type argument"); + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = BackgroundColour, + }, + tabStrip = new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + Alpha = 0.9f, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Top = padding, Horizontal = BrowseOverlay.WIDTH_PADDING }, + Children = new Drawable[] + { + Search = new FilterSearchTextBox + { + RelativeSizeAxes = Axes.X, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = padding }, //todo: margin is still applied without any controls + Children = new[] + { + CreateControls(), + }, + }, + Tabs = new PageTabControl + { + RelativeSizeAxes = Axes.X, + }, + new Box //keep the tab strip part of autosize, but don't put it in the flow container + { + RelativeSizeAxes = Axes.X, + Height = 1, + Colour = Color4.White.Opacity(0), + }, + }, + }, + }; + + Tabs.Current.Value = DefaultTab; + Tabs.Current.TriggerChange(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + tabStrip.Colour = colours.Yellow; + } + + private class FilterSearchTextBox : SearchTextBox + { + protected override Color4 BackgroundUnfocused => backgroundColour; + protected override Color4 BackgroundFocused => backgroundColour; + + private Color4 backgroundColour; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + backgroundColour = colours.Gray2.Opacity(0.9f); + } + } + } +} diff --git a/osu.Game/Overlays/Browse/BrowseHeader.cs b/osu.Game/Overlays/Browse/BrowseHeader.cs new file mode 100644 index 0000000000..47f2d6d8c2 --- /dev/null +++ b/osu.Game/Overlays/Browse/BrowseHeader.cs @@ -0,0 +1,96 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.Browse +{ + public abstract class BrowseHeader : Container + { + public static readonly float HEIGHT = 90; + + private readonly Box tabStrip; + + public readonly HeaderTabControl Tabs; + + protected abstract Color4 BackgroundColour { get; } + protected abstract float TabStripWidth { get; } //can be removed once (if?) TabControl support auto sizing + protected abstract T DefaultTab { get; } + protected abstract Drawable CreateHeaderText(); + + public BrowseHeader() + { + if (!typeof(T).IsEnum) + throw new InvalidOperationException("BrowseHeader only supports enums as the generic type argument"); + + RelativeSizeAxes = Axes.X; + Height = HEIGHT; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = BackgroundColour, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = BrowseOverlay.WIDTH_PADDING, Right = BrowseOverlay.WIDTH_PADDING },  + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.BottomLeft, + Position = new Vector2(-35f, 5f), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10f, 0f), + Children = new Drawable[] + { + new TextAwesome + { + TextSize = 25, + Icon = FontAwesome.fa_osu_chevron_down_o, + }, + CreateHeaderText(), + }, + }, + tabStrip = new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Width = TabStripWidth, + Height = 1, + }, + Tabs = new HeaderTabControl + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + }, + }, + }, + }; + + Tabs.Current.Value = DefaultTab; + Tabs.Current.TriggerChange(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + tabStrip.Colour = colours.Green; + } + } +} diff --git a/osu.Game/Overlays/Browse/BrowseOverlay.cs b/osu.Game/Overlays/Browse/BrowseOverlay.cs new file mode 100644 index 0000000000..dc5732b58f --- /dev/null +++ b/osu.Game/Overlays/Browse/BrowseOverlay.cs @@ -0,0 +1,126 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Backgrounds; + +namespace osu.Game.Overlays.Browse +{ + public abstract class BrowseOverlay : WaveOverlayContainer + { + public static readonly float WIDTH_PADDING = 80; + } + + //todo: naming + //todo: crash when pressing tab + public abstract class BrowseOverlay : BrowseOverlay + { + private readonly Container scrollContainer; + + protected readonly BrowseHeader Header; + protected readonly BrowseFilterControl Filter; + protected readonly FillFlowContainer ScrollFlow; + + protected abstract Color4 BackgroundColour { get; } + protected abstract Color4 TrianglesColourLight { get; } + protected abstract Color4 TrianglesColourDark { get; } + protected abstract BrowseHeader CreateHeader(); + protected abstract BrowseFilterControl CreateFilterControl(); + + public BrowseOverlay() + { + RelativeSizeAxes = Axes.Both; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = BackgroundColour, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Children = new[] + { + new Triangles + { + RelativeSizeAxes = Axes.Both, + TriangleScale = 5, + ColourLight = TrianglesColourLight, + ColourDark = TrianglesColourDark, + }, + }, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + Header = CreateHeader(), + Filter = CreateFilterControl(), + }, + }, + scrollContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollDraggerVisible = false, + Children = new[] + { + ScrollFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = BrowseOverlay.WIDTH_PADDING }, + Direction = FillDirection.Vertical, + }, + }, + }, + }, + }, + }; + + Filter.Search.Exit = Hide; + } + + protected override void Update() + { + base.Update(); + + scrollContainer.Padding = new MarginPadding { Top = Header.Height + Filter.Height }; + } + + protected override bool OnFocus(InputState state) + { + Filter.Search.TriggerFocus(); + return false; + } + + protected override void PopIn() + { + base.PopIn(); + + Filter.Search.HoldFocus = true; + } + + protected override void PopOut() + { + base.PopOut(); + + Filter.Search.HoldFocus = false; + } + } +} diff --git a/osu.Game/Overlays/Browse/DisplayStyleControl.cs b/osu.Game/Overlays/Browse/DisplayStyleControl.cs new file mode 100644 index 0000000000..ae9397eca7 --- /dev/null +++ b/osu.Game/Overlays/Browse/DisplayStyleControl.cs @@ -0,0 +1,102 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.Browse +{ + public class DisplayStyleControl : Container + { + public readonly SlimEnumDropdown Dropdown; + public readonly Bindable DisplayStyle = new Bindable(); + + public DisplayStyleControl() + { + AutoSizeAxes = Axes.Both; + + Children = new[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Spacing = new Vector2(10f, 0f), + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(5f, 0f), + Direction = FillDirection.Horizontal, + Children = new[] + { + new DisplayStyleToggleButton(FontAwesome.fa_th_large, PanelDisplayStyle.Grid, DisplayStyle), + new DisplayStyleToggleButton(FontAwesome.fa_list_ul, PanelDisplayStyle.List, DisplayStyle), + }, + }, + Dropdown = new SlimEnumDropdown + { + RelativeSizeAxes = Axes.None, + Width = 160f, + }, + }, + }, + }; + + DisplayStyle.Value = PanelDisplayStyle.Grid; + } + + private class DisplayStyleToggleButton : ClickableContainer + { + private readonly TextAwesome icon; + private readonly PanelDisplayStyle style; + private readonly Bindable bindable; + + public DisplayStyleToggleButton(FontAwesome icon, PanelDisplayStyle style, Bindable bindable) + { + this.bindable = bindable; + this.style = style; + Size = new Vector2(25f); + + Children = new Drawable[] + { + this.icon = new TextAwesome + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = icon, + TextSize = 18, + UseFullGlyphHeight = false, + Alpha = 0.5f, + }, + }; + + bindable.ValueChanged += Bindable_ValueChanged; + Bindable_ValueChanged(bindable.Value); + Action = () => bindable.Value = this.style; + } + + private void Bindable_ValueChanged(PanelDisplayStyle style) + { + icon.FadeTo(style == this.style ? 1.0f : 0.5f, 100); + } + + protected override void Dispose(bool isDisposing) + { + bindable.ValueChanged -= Bindable_ValueChanged; + } + } + } + + public enum PanelDisplayStyle + { + Grid, + List, + } +} diff --git a/osu.Game/Overlays/Browse/HeaderTabControl.cs b/osu.Game/Overlays/Browse/HeaderTabControl.cs new file mode 100644 index 0000000000..afe3f2cb5e --- /dev/null +++ b/osu.Game/Overlays/Browse/HeaderTabControl.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Browse +{ + public class HeaderTabControl : OsuTabControl + { + protected override TabItem CreateTabItem(T value) => new HeaderTabItem(value); + + public HeaderTabControl() + { + Height = 26; + AccentColour = Color4.White; + } + + private class HeaderTabItem : OsuTabItem + { + public HeaderTabItem(T value) : base(value) + { + Text.TextSize = 16; + } + } + } +} diff --git a/osu.Game/Overlays/Direct/SlimEnumDropdown.cs b/osu.Game/Overlays/Browse/SlimEnumDropdown.cs similarity index 89% rename from osu.Game/Overlays/Direct/SlimEnumDropdown.cs rename to osu.Game/Overlays/Browse/SlimEnumDropdown.cs index 1d12b8477b..a3687174a0 100644 --- a/osu.Game/Overlays/Direct/SlimEnumDropdown.cs +++ b/osu.Game/Overlays/Browse/SlimEnumDropdown.cs @@ -7,12 +7,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Overlays.Direct +namespace osu.Game.Overlays.Browse { public class SlimEnumDropdown : OsuEnumDropdown { - public const float HEIGHT = 25; - protected override DropdownHeader CreateHeader() => new SlimDropdownHeader { AccentColour = AccentColour }; protected override Menu CreateMenu() => new SlimMenu(); @@ -20,7 +18,7 @@ namespace osu.Game.Overlays.Direct { public SlimDropdownHeader() { - Height = HEIGHT; + Height = 25; Icon.TextSize = 16; Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 8, Right = 4 }; } diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 735e14b8c1..20e9eb4aa1 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -5,117 +5,47 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Game.Database; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Browse; namespace osu.Game.Overlays.Direct { - public class FilterControl : Container + public class FilterControl : BrowseFilterControl { - public static readonly float HEIGHT = 35 + 32 + 30 + padding * 2; // search + mode toggle buttons + sort tabs + padding + private FillFlowContainer modeButtons; - private const float padding = 10; + public readonly DisplayStyleControl DisplayStyleControl; //todo: naming - private readonly Box tabStrip; - private readonly FillFlowContainer modeButtons; + protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); + protected override DirectSortCritera DefaultTab => DirectSortCritera.Title; + protected override Drawable CreateControls() + { + modeButtons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(10f, 0f), + }; - public readonly SearchTextBox Search; - public readonly SortTabControl SortTabs; - public readonly OsuEnumDropdown RankStatusDropdown; - public readonly Bindable DisplayStyle = new Bindable(); - - protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || RankStatusDropdown.Contains(screenSpacePos); + return modeButtons; + } public FilterControl() { - RelativeSizeAxes = Axes.X; - Height = HEIGHT; - DisplayStyle.Value = DirectOverlay.PanelDisplayStyle.Grid; - - Children = new Drawable[] + Add(DisplayStyleControl = new DisplayStyleControl { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"384552"), - Alpha = 0.9f, - }, - tabStrip = new Box - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.TopLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = DirectOverlay.WIDTH_PADDING, Right = DirectOverlay.WIDTH_PADDING }, - Children = new Drawable[] - { - Search = new DirectSearchTextBox - { - RelativeSizeAxes = Axes.X, - Margin = new MarginPadding { Top = padding }, - }, - modeButtons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(padding, 0f), - Margin = new MarginPadding { Top = padding }, - }, - SortTabs = new SortTabControl - { - RelativeSizeAxes = Axes.X, - }, - }, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Spacing = new Vector2(10f, 0f), - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Top = HEIGHT - SlimEnumDropdown.HEIGHT - padding, Right = DirectOverlay.WIDTH_PADDING }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(5f, 0f), - Direction = FillDirection.Horizontal, - Children = new[] - { - new DisplayStyleToggleButton(FontAwesome.fa_th_large, DirectOverlay.PanelDisplayStyle.Grid, DisplayStyle), - new DisplayStyleToggleButton(FontAwesome.fa_list_ul, DirectOverlay.PanelDisplayStyle.List, DisplayStyle), - }, - }, - RankStatusDropdown = new SlimEnumDropdown - { - RelativeSizeAxes = Axes.None, - Width = 160f, - }, - }, - }, - }; - - RankStatusDropdown.Current.Value = RankStatus.RankedApproved; - SortTabs.Current.Value = SortCriteria.Title; - SortTabs.Current.TriggerChange(); + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Margin = new MarginPadding { Bottom = 5, Right = BrowseOverlay.WIDTH_PADDING }, + }); } [BackgroundDependencyLoader(true)] private void load(OsuGame game, RulesetDatabase rulesets, OsuColour colours) { - tabStrip.Colour = colours.Yellow; - RankStatusDropdown.AccentColour = colours.BlueDark; + DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; var b = new Bindable(); //backup bindable incase the game is null foreach (var r in rulesets.AllRulesets) @@ -124,20 +54,6 @@ namespace osu.Game.Overlays.Direct } } - private class DirectSearchTextBox : SearchTextBox - { - protected override Color4 BackgroundUnfocused => backgroundColour; - protected override Color4 BackgroundFocused => backgroundColour; - - private Color4 backgroundColour; - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - backgroundColour = colours.Gray2.Opacity(0.9f); - } - } - private class RulesetToggleButton : ClickableContainer { private readonly TextAwesome icon; @@ -188,46 +104,15 @@ namespace osu.Game.Overlays.Direct base.Dispose(isDisposing); } } + } - private class DisplayStyleToggleButton : ClickableContainer - { - private readonly TextAwesome icon; - private readonly DirectOverlay.PanelDisplayStyle style; - private readonly Bindable bindable; - - public DisplayStyleToggleButton(FontAwesome icon, DirectOverlay.PanelDisplayStyle style, Bindable bindable) - { - this.bindable = bindable; - this.style = style; - Size = new Vector2(SlimEnumDropdown.HEIGHT); - - Children = new Drawable[] - { - this.icon = new TextAwesome - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = icon, - TextSize = 18, - UseFullGlyphHeight = false, - Alpha = 0.5f, - }, - }; - - bindable.ValueChanged += Bindable_ValueChanged; - Bindable_ValueChanged(bindable.Value); - Action = () => bindable.Value = this.style; - } - - private void Bindable_ValueChanged(DirectOverlay.PanelDisplayStyle style) - { - icon.FadeTo(style == this.style ? 1.0f : 0.5f, 100); - } - - protected override void Dispose(bool isDisposing) - { - bindable.ValueChanged -= Bindable_ValueChanged; - } - } + public enum DirectSortCritera + { + Title, + Artist, + Creator, + Difficulty, + Ranked, + Rating, } } diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index 8e4ede48d5..b8b06580c2 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -2,113 +2,27 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.ComponentModel; -using OpenTK; using OpenTK.Graphics; -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; - -using Container = osu.Framework.Graphics.Containers.Container; +using osu.Game.Overlays.Browse; namespace osu.Game.Overlays.Direct { - public class Header : Container + public class Header : BrowseHeader { - public static readonly float HEIGHT = 90; + protected override Color4 BackgroundColour => OsuColour.FromHex(@"252f3a"); + protected override float TabStripWidth => 298; - private readonly Box tabStrip; - - public readonly OsuTabControl Tabs; + protected override DirectTab DefaultTab => DirectTab.Search; + protected override Drawable CreateHeaderText() => new OsuSpriteText { Text = @"osu!direct", TextSize = 25, }; public Header() { - Height = HEIGHT; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"252f3a"), - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = DirectOverlay.WIDTH_PADDING, Right = DirectOverlay.WIDTH_PADDING }, - Children = new Drawable[] - { - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - Position = new Vector2(-35f, 5f), - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10f, 0f), - Children = new Drawable[] - { - new TextAwesome - { - TextSize = 25, - Icon = FontAwesome.fa_osu_chevron_down_o, - }, - new OsuSpriteText - { - TextSize = 25, - Text = @"osu!direct", - }, - }, - }, - tabStrip = new Box - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Width = 282, //todo: make this actually match the tab control's width instead of hardcoding - Height = 1, - }, - Tabs = new DirectTabControl - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - }, - }, - }, - }; - Tabs.Current.Value = DirectTab.Search; Tabs.Current.TriggerChange(); } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - tabStrip.Colour = colours.Green; - } - - private class DirectTabControl : OsuTabControl - { - protected override TabItem CreateTabItem(DirectTab value) => new DirectTabItem(value); - - public DirectTabControl() - { - Height = 25; - AccentColour = Color4.White; - } - - private class DirectTabItem : OsuTabItem - { - public DirectTabItem(DirectTab value) : base(value) - { - Text.TextSize = 15; - } - } - } } public enum DirectTab diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 0930c825b6..e57a556461 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -7,28 +7,33 @@ using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input; using osu.Game.Database; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Direct; +using osu.Game.Overlays.Browse; +using OpenTK.Graphics; +using System.ComponentModel; using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Overlays { - public class DirectOverlay : WaveOverlayContainer + public class DirectOverlay : BrowseOverlay { - public static readonly int WIDTH_PADDING = 80; private const float panel_padding = 10f; - private readonly FilterControl filter; private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; private readonly FillFlowContainer panels; + protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74"); + protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71"); + protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); + + protected override BrowseHeader CreateHeader() => new Header(); + protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); + private IEnumerable beatmapSets; public IEnumerable BeatmapSets { @@ -38,7 +43,7 @@ namespace osu.Game.Overlays if (beatmapSets?.Equals(value) ?? false) return; beatmapSets = value; - recreatePanels(filter.DisplayStyle.Value); + recreatePanels((Filter as FilterControl).DisplayStyleControl.DisplayStyle.Value); //todo: potential nullref } } @@ -66,96 +71,39 @@ namespace osu.Game.Overlays ThirdWaveColour = OsuColour.FromHex(@"005774"); FourthWaveColour = OsuColour.FromHex(@"003a4e"); - Header header; - Children = new Drawable[] + ScrollFlow.Children = new Drawable[] { - new Box + resultCountsContainer = new FillFlowContainer { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"485e74"), - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Top = 5 }, + Children = new Drawable[] { - new Triangles + new OsuSpriteText { - RelativeSizeAxes = Axes.Both, - TriangleScale = 5, - ColourLight = OsuColour.FromHex(@"465b71"), - ColourDark = OsuColour.FromHex(@"3f5265"), + Text = "Found ", + TextSize = 15, }, - }, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Header.HEIGHT + FilterControl.HEIGHT }, - Children = new[] - { - new ScrollContainer + resultCountsText = new OsuSpriteText { - RelativeSizeAxes = Axes.Both, - ScrollDraggerVisible = false, - Children = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - resultCountsContainer = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Left = WIDTH_PADDING, Top = 6 }, - Children = new Drawable[] - { - new OsuSpriteText - { - Text = "Found ", - TextSize = 15, - }, - resultCountsText = new OsuSpriteText - { - TextSize = 15, - Font = @"Exo2.0-Bold", - }, - } - }, - panels = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = panel_padding, Bottom = panel_padding, Left = WIDTH_PADDING, Right = WIDTH_PADDING }, - Spacing = new Vector2(panel_padding), - }, - }, - }, - }, + TextSize = 15, + Font = @"Exo2.0-Bold", }, - }, + } }, - filter = new FilterControl - { - RelativeSizeAxes = Axes.X, - Margin = new MarginPadding { Top = Header.HEIGHT }, - }, - header = new Header + panels = new FillFlowContainer { RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(panel_padding), + Margin = new MarginPadding { Top = 10 }, }, }; - header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) filter.Search.Current.Value = string.Empty; }; - - filter.Search.Exit = Hide; - filter.Search.Current.ValueChanged += text => { if (text != string.Empty) header.Tabs.Current.Value = DirectTab.Search; }; - filter.DisplayStyle.ValueChanged += recreatePanels; + Header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) Filter.Search.Text = string.Empty; }; + Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; }; + (Filter as FilterControl).DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; //todo: potential nullref updateResultCounts(); } @@ -187,26 +135,6 @@ namespace osu.Game.Overlays panels.Children = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b)); } - protected override bool OnFocus(InputState state) - { - filter.Search.TriggerFocus(); - return false; - } - - protected override void PopIn() - { - base.PopIn(); - - filter.Search.HoldFocus = true; - } - - protected override void PopOut() - { - base.PopOut(); - - filter.Search.HoldFocus = false; - } - public class ResultCounts { public readonly int Artists; @@ -220,11 +148,5 @@ namespace osu.Game.Overlays Tags = tags; } } - - public enum PanelDisplayStyle - { - Grid, - List, - } } } diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs new file mode 100644 index 0000000000..a5dcddad00 --- /dev/null +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Game.Graphics; +using osu.Game.Overlays.Browse; + +namespace osu.Game.Overlays.Social +{ + public class FilterControl : BrowseFilterControl + { + protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); + protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Name; + } +} diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs new file mode 100644 index 0000000000..b540bd9a18 --- /dev/null +++ b/osu.Game/Overlays/Social/Header.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Overlays.Browse; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Framework.Allocation; + +namespace osu.Game.Overlays.Social +{ + public class Header : BrowseHeader + { + private OsuSpriteText browser; + + protected override Color4 BackgroundColour => OsuColour.FromHex(@"672b51"); + protected override float TabStripWidth => 438; + protected override SocialTab DefaultTab => SocialTab.OnlinePlayers; + + protected override Drawable CreateHeaderText() + { + return new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Text = "social ", + TextSize = 25, + }, + browser = new OsuSpriteText + { + Text = "browser", + TextSize = 25, + Font = @"Exo2.0-Light", + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + browser.Colour = colours.Pink; + } + } +} diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs new file mode 100644 index 0000000000..571d0b7130 --- /dev/null +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.ComponentModel; +using OpenTK.Graphics; +using osu.Game.Graphics; +using osu.Game.Overlays.Browse; +using osu.Game.Overlays.Social; + +namespace osu.Game.Overlays +{ + public class SocialOverlay : BrowseOverlay + { + protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); + protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); + protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); + + protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); + protected override BrowseHeader CreateHeader() => new Header(); + } + + public enum SocialTab + { + [Description("Online Players")] + OnlinePlayers, + [Description("Online Friends")] + OnlineFriends, + [Description("Online Team Members")] + OnlineTeamMembers, + [Description("Chat Channels")] + ChatChannels, + } + + public enum SocialSortCriteria + { + Name, + Rank, + Location, + [Description("Time Zone")] + TimeZone, + [Description("World Map")] + WorldMap, + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 25b692151f..fb1db37f65 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -440,16 +440,24 @@ - - + + + + + + + + + + From 63313045d93fd66137483d0662e9795b43195d10 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 00:58:18 -0300 Subject: [PATCH 02/45] Add SocialOverlay to OsuGame --- osu.Game/OsuGame.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 886ff4f8d1..850e736edb 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -43,6 +43,8 @@ namespace osu.Game private DirectOverlay direct; + private SocialOverlay social; + private Intro intro { get @@ -165,6 +167,7 @@ namespace osu.Game //overlay elements LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add); + LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add); LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add); LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add); LoadComponentAsync(musicController = new MusicController @@ -234,6 +237,9 @@ namespace osu.Game case Key.F8: chat.ToggleVisibility(); return true; + case Key.F9: + social.ToggleVisibility(); + return true; case Key.PageUp: case Key.PageDown: var swClock = (Clock as ThrottledFrameClock)?.Source as StopwatchClock; From 2d3995b85c13a55f1fe4c49310e08fd38acdb313 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 01:32:20 -0300 Subject: [PATCH 03/45] Fix filter controls having margin when no controls given, add DisplayStyleControl to social, misc cleanups --- .../Overlays/Browse/BrowseFilterControl.cs | 13 +++-- osu.Game/Overlays/Browse/BrowseOverlay.cs | 1 - osu.Game/Overlays/Social/FilterControl.cs | 12 +++++ osu.Game/Overlays/Social/Header.cs | 13 +++++ osu.Game/Overlays/SocialOverlay.cs | 47 +++++++++++-------- 5 files changed, 58 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Browse/BrowseFilterControl.cs b/osu.Game/Overlays/Browse/BrowseFilterControl.cs index fe61771f5b..1eeadfb6d3 100644 --- a/osu.Game/Overlays/Browse/BrowseFilterControl.cs +++ b/osu.Game/Overlays/Browse/BrowseFilterControl.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Browse protected abstract Color4 BackgroundColour { get; } protected abstract T DefaultTab { get; } - protected virtual Drawable CreateControls() => new Container(); //todo: naming + protected virtual Drawable CreateControls() => null; //todo: naming public BrowseFilterControl() { @@ -34,6 +34,8 @@ namespace osu.Game.Overlays.Browse RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + var controls = CreateControls(); + Container controlsContainer; Children = new Drawable[] { new Box @@ -60,15 +62,11 @@ namespace osu.Game.Overlays.Browse { RelativeSizeAxes = Axes.X, }, - new Container + controlsContainer = new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = padding }, //todo: margin is still applied without any controls - Children = new[] - { - CreateControls(), - }, + Margin = new MarginPadding { Top = controls != null ? padding : 0 }, }, Tabs = new PageTabControl { @@ -84,6 +82,7 @@ namespace osu.Game.Overlays.Browse }, }; + if (controls != null) controlsContainer.Children = new[] { controls }; Tabs.Current.Value = DefaultTab; Tabs.Current.TriggerChange(); } diff --git a/osu.Game/Overlays/Browse/BrowseOverlay.cs b/osu.Game/Overlays/Browse/BrowseOverlay.cs index dc5732b58f..412662c67b 100644 --- a/osu.Game/Overlays/Browse/BrowseOverlay.cs +++ b/osu.Game/Overlays/Browse/BrowseOverlay.cs @@ -17,7 +17,6 @@ namespace osu.Game.Overlays.Browse } //todo: naming - //todo: crash when pressing tab public abstract class BrowseOverlay : BrowseOverlay { private readonly Container scrollContainer; diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index a5dcddad00..9e15cf4fe9 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel; using OpenTK.Graphics; using osu.Game.Graphics; using osu.Game.Overlays.Browse; @@ -12,4 +13,15 @@ namespace osu.Game.Overlays.Social protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Name; } + + public enum SocialSortCriteria + { + Name, + Rank, + Location, + [Description("Time Zone")] + TimeZone, + [Description("World Map")] + WorldMap, + } } diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index b540bd9a18..47ddc61453 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -8,6 +8,7 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Framework.Allocation; +using System.ComponentModel; namespace osu.Game.Overlays.Social { @@ -48,4 +49,16 @@ namespace osu.Game.Overlays.Social browser.Colour = colours.Pink; } } + + public enum SocialTab + { + [Description("Online Players")] + OnlinePlayers, + [Description("Online Friends")] + OnlineFriends, + [Description("Online Team Members")] + OnlineTeamMembers, + [Description("Chat Channels")] + ChatChannels, + } } diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 571d0b7130..19dfa6f182 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -3,10 +3,13 @@ using System.ComponentModel; using OpenTK.Graphics; +using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Overlays.Browse; using osu.Game.Overlays.Social; +using Container = osu.Framework.Graphics.Containers.Container; + namespace osu.Game.Overlays { public class SocialOverlay : BrowseOverlay @@ -17,28 +20,32 @@ namespace osu.Game.Overlays protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); protected override BrowseHeader CreateHeader() => new Header(); + + public SocialOverlay() + { + ScrollFlow.Children = new[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Vertical = 10 }, + Children = new[] + { + new DisplayStyleControl + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }, + }, + }, + }; + } } - public enum SocialTab + public enum SortDirection { - [Description("Online Players")] - OnlinePlayers, - [Description("Online Friends")] - OnlineFriends, - [Description("Online Team Members")] - OnlineTeamMembers, - [Description("Chat Channels")] - ChatChannels, - } - - public enum SocialSortCriteria - { - Name, - Rank, - Location, - [Description("Time Zone")] - TimeZone, - [Description("World Map")] - WorldMap, + Ascending, + Descending, } } From 5c0d0cb7e7cc68cb468b95d08bd572f085d86a05 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 01:34:30 -0300 Subject: [PATCH 04/45] Alpha on wrong object --- osu.Game/Overlays/Browse/BrowseFilterControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Browse/BrowseFilterControl.cs b/osu.Game/Overlays/Browse/BrowseFilterControl.cs index 1eeadfb6d3..9819ea4330 100644 --- a/osu.Game/Overlays/Browse/BrowseFilterControl.cs +++ b/osu.Game/Overlays/Browse/BrowseFilterControl.cs @@ -42,6 +42,7 @@ namespace osu.Game.Overlays.Browse { RelativeSizeAxes = Axes.Both, Colour = BackgroundColour, + Alpha = 0.9f, }, tabStrip = new Box { @@ -49,7 +50,6 @@ namespace osu.Game.Overlays.Browse Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, Height = 1, - Alpha = 0.9f, }, new FillFlowContainer { From e19a4f5e6f62d6383c20e7217c6af1e216ce657d Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 02:00:38 -0300 Subject: [PATCH 05/45] Add displaying users --- .../Tests/TestCaseSocial.cs | 64 ++++++++++++++++++- osu.Game/Overlays/SocialOverlay.cs | 33 +++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs index 8fee8e6887..8f4ae0dbfe 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs @@ -3,6 +3,7 @@ using osu.Framework.Testing; using osu.Game.Overlays; +using osu.Game.Users; namespace osu.Desktop.VisualTests.Tests { @@ -14,7 +15,68 @@ namespace osu.Desktop.VisualTests.Tests { base.Reset(); - SocialOverlay s = new SocialOverlay(); + SocialOverlay s = new SocialOverlay + { + Users = new[] + { + new User + { + Username = @"flyte", + Id = 3103765, + Country = new Country { FlagName = @"JP" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3103765/5b012e13611d5761caa7e24fecb3d3a16e1cf48fc2a3032cfd43dd444af83d82.jpeg", + }, + new User + { + Username = @"Cookiezi", + Id = 124493, + Country = new Country { FlagName = @"KR" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg", + }, + new User + { + Username = @"Angelism", + Id = 1777162, + Country = new Country { FlagName = @"KR" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg", + }, + new User + { + Username = @"Rafis", + Id = 2558286, + Country = new Country { FlagName = @"PL" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c5.jpg", + }, + new User + { + Username = @"hvick225", + Id = 50265, + Country = new Country { FlagName = @"TW" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/50265/cb79df0d6ddd04b57d057623417aa55c505810d8e73b1a96d6e665e0e18e5770.jpeg", + }, + new User + { + Username = @"peppy", + Id = 2, + Country = new Country { FlagName = @"AU" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/2/615362d26dc37cc4d46e61a08a2537e7cdf0e0e00f40574b18bf90156ad0280f.jpeg" + }, + new User + { + Username = @"filsdelama", + Id = 2831793, + Country = new Country { FlagName = @"FR" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg" + }, + new User + { + Username = @"_index", + Id = 652457, + Country = new Country { FlagName = @"RU" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c7.jpg" + }, + }, + }; Add(s); AddStep(@"toggle", s.ToggleVisibility); diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 19dfa6f182..17cd587d1f 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -1,12 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using System.ComponentModel; +using System.Linq; +using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Overlays.Browse; using osu.Game.Overlays.Social; +using osu.Game.Users; using Container = osu.Framework.Graphics.Containers.Container; @@ -14,6 +19,26 @@ namespace osu.Game.Overlays { public class SocialOverlay : BrowseOverlay { + private readonly FillFlowContainer panelFlow; + + private IEnumerable users; + public IEnumerable Users + { + get { return users; } + set + { + if (users == value) return; + users = value; + + panelFlow.Children = users.Select(u => + { + var p = new UserPanel(u) { Width = 300 }; + p.Status.BindTo(u.Status); + return p; + }); + } + } + protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); @@ -23,7 +48,7 @@ namespace osu.Game.Overlays public SocialOverlay() { - ScrollFlow.Children = new[] + ScrollFlow.Children = new Drawable[] { new Container { @@ -39,6 +64,12 @@ namespace osu.Game.Overlays }, }, }, + panelFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10f), + }, }; } } From fc67582c3f3a3c13303b3dfd4602f45a3c53b8fa Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 02:16:56 -0300 Subject: [PATCH 06/45] Cleanup --- osu.Desktop.VisualTests/Tests/TestCaseSocial.cs | 2 +- osu.Game/Overlays/Browse/BrowseFilterControl.cs | 3 ++- osu.Game/Overlays/Browse/BrowseHeader.cs | 4 +--- osu.Game/Overlays/Browse/BrowseOverlay.cs | 3 +-- osu.Game/Overlays/Browse/DisplayStyleControl.cs | 2 +- osu.Game/Overlays/Browse/HeaderTabControl.cs | 2 +- osu.Game/Overlays/Direct/Header.cs | 2 +- osu.Game/Overlays/DirectOverlay.cs | 3 --- osu.Game/Overlays/SocialOverlay.cs | 17 +++++++---------- 9 files changed, 15 insertions(+), 23 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs index 8f4ae0dbfe..37d85ce0c9 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Testing; diff --git a/osu.Game/Overlays/Browse/BrowseFilterControl.cs b/osu.Game/Overlays/Browse/BrowseFilterControl.cs index 9819ea4330..d21c36bd5c 100644 --- a/osu.Game/Overlays/Browse/BrowseFilterControl.cs +++ b/osu.Game/Overlays/Browse/BrowseFilterControl.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; @@ -83,6 +83,7 @@ namespace osu.Game.Overlays.Browse }; if (controls != null) controlsContainer.Children = new[] { controls }; + Tabs.Current.Value = DefaultTab; Tabs.Current.TriggerChange(); } diff --git a/osu.Game/Overlays/Browse/BrowseHeader.cs b/osu.Game/Overlays/Browse/BrowseHeader.cs index 47f2d6d8c2..450245bde5 100644 --- a/osu.Game/Overlays/Browse/BrowseHeader.cs +++ b/osu.Game/Overlays/Browse/BrowseHeader.cs @@ -1,8 +1,7 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -10,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Browse { diff --git a/osu.Game/Overlays/Browse/BrowseOverlay.cs b/osu.Game/Overlays/Browse/BrowseOverlay.cs index 412662c67b..ba8262ef06 100644 --- a/osu.Game/Overlays/Browse/BrowseOverlay.cs +++ b/osu.Game/Overlays/Browse/BrowseOverlay.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK.Graphics; @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input; -using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; namespace osu.Game.Overlays.Browse diff --git a/osu.Game/Overlays/Browse/DisplayStyleControl.cs b/osu.Game/Overlays/Browse/DisplayStyleControl.cs index ae9397eca7..5570d60bb7 100644 --- a/osu.Game/Overlays/Browse/DisplayStyleControl.cs +++ b/osu.Game/Overlays/Browse/DisplayStyleControl.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; diff --git a/osu.Game/Overlays/Browse/HeaderTabControl.cs b/osu.Game/Overlays/Browse/HeaderTabControl.cs index afe3f2cb5e..cdac8d2dd9 100644 --- a/osu.Game/Overlays/Browse/HeaderTabControl.cs +++ b/osu.Game/Overlays/Browse/HeaderTabControl.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK.Graphics; diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index b8b06580c2..a1daa0a2b4 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Direct protected override float TabStripWidth => 298; protected override DirectTab DefaultTab => DirectTab.Search; - protected override Drawable CreateHeaderText() => new OsuSpriteText { Text = @"osu!direct", TextSize = 25, }; + protected override Drawable CreateHeaderText() => new OsuSpriteText { Text = @"osu!direct", TextSize = 25 }; public Header() { diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index e57a556461..9ab19aa6f9 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -13,9 +13,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Direct; using osu.Game.Overlays.Browse; using OpenTK.Graphics; -using System.ComponentModel; - -using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Overlays { diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 17cd587d1f..e744e4ca13 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.ComponentModel; using System.Linq; using OpenTK; using OpenTK.Graphics; @@ -13,14 +12,19 @@ using osu.Game.Overlays.Browse; using osu.Game.Overlays.Social; using osu.Game.Users; -using Container = osu.Framework.Graphics.Containers.Container; - namespace osu.Game.Overlays { public class SocialOverlay : BrowseOverlay { private readonly FillFlowContainer panelFlow; + protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); + protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); + protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); + + protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); + protected override BrowseHeader CreateHeader() => new Header(); + private IEnumerable users; public IEnumerable Users { @@ -39,13 +43,6 @@ namespace osu.Game.Overlays } } - protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); - protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); - protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); - - protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); - protected override BrowseHeader CreateHeader() => new Header(); - public SocialOverlay() { ScrollFlow.Children = new Drawable[] From 5831da69788c3d43ed0ca9f701293e4420eb3bb5 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 02:32:01 -0300 Subject: [PATCH 07/45] Autohide social when entering a screen that doesn't allow overlays, fix potential nullrefs in DirectOverlay, CreateControls -> CreateSupplementaryControls --- osu.Game/OsuGame.cs | 1 + osu.Game/Overlays/Browse/BrowseFilterControl.cs | 4 ++-- osu.Game/Overlays/Direct/FilterControl.cs | 4 ++-- osu.Game/Overlays/DirectOverlay.cs | 13 +++++++++++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 850e736edb..224d944ac4 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -295,6 +295,7 @@ namespace osu.Game musicController.State = Visibility.Hidden; chat.State = Visibility.Hidden; direct.State = Visibility.Hidden; + social.State = Visibility.Hidden; } else { diff --git a/osu.Game/Overlays/Browse/BrowseFilterControl.cs b/osu.Game/Overlays/Browse/BrowseFilterControl.cs index d21c36bd5c..a395c1c01d 100644 --- a/osu.Game/Overlays/Browse/BrowseFilterControl.cs +++ b/osu.Game/Overlays/Browse/BrowseFilterControl.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Browse protected abstract Color4 BackgroundColour { get; } protected abstract T DefaultTab { get; } - protected virtual Drawable CreateControls() => null; //todo: naming + protected virtual Drawable CreateSupplementaryControls() => null; public BrowseFilterControl() { @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Browse RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - var controls = CreateControls(); + var controls = CreateSupplementaryControls(); Container controlsContainer; Children = new Drawable[] { diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 20e9eb4aa1..bc82352c33 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -17,11 +17,11 @@ namespace osu.Game.Overlays.Direct { private FillFlowContainer modeButtons; - public readonly DisplayStyleControl DisplayStyleControl; //todo: naming + public readonly DisplayStyleControl DisplayStyleControl; protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); protected override DirectSortCritera DefaultTab => DirectSortCritera.Title; - protected override Drawable CreateControls() + protected override Drawable CreateSupplementaryControls() { modeButtons = new FillFlowContainer { diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9ab19aa6f9..d4522e227b 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -13,6 +13,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Direct; using osu.Game.Overlays.Browse; using OpenTK.Graphics; +using System; namespace osu.Game.Overlays { @@ -40,7 +41,9 @@ namespace osu.Game.Overlays if (beatmapSets?.Equals(value) ?? false) return; beatmapSets = value; - recreatePanels((Filter as FilterControl).DisplayStyleControl.DisplayStyle.Value); //todo: potential nullref + var s = PanelDisplayStyle.Grid; + withDisplayStyleControl(c => s = c.DisplayStyle.Value); + recreatePanels(s); } } @@ -100,7 +103,7 @@ namespace osu.Game.Overlays Header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) Filter.Search.Text = string.Empty; }; Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; }; - (Filter as FilterControl).DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; //todo: potential nullref + withDisplayStyleControl(c => c.DisplayStyle.ValueChanged += recreatePanels); updateResultCounts(); } @@ -132,6 +135,12 @@ namespace osu.Game.Overlays panels.Children = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b)); } + private void withDisplayStyleControl(Action> action) + { + var f = (Filter as FilterControl); + if (f != null) action.Invoke(f.DisplayStyleControl); + } + public class ResultCounts { public readonly int Artists; From 68377494f728a0863800ffa389fb16cb5e33b292 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 02:44:09 -0300 Subject: [PATCH 08/45] Browser - SearchableList --- osu.Game/Overlays/Direct/FilterControl.cs | 6 +++--- osu.Game/Overlays/Direct/Header.cs | 4 ++-- osu.Game/Overlays/DirectOverlay.cs | 8 ++++---- .../DisplayStyleControl.cs | 2 +- .../HeaderTabControl.cs | 2 +- .../SearchableListFilterControl.cs} | 8 ++++---- .../SearchableListHeader.cs} | 8 ++++---- .../SearchableListOverlay.cs} | 18 +++++++++--------- .../SlimEnumDropdown.cs | 2 +- osu.Game/Overlays/Social/FilterControl.cs | 4 ++-- osu.Game/Overlays/Social/Header.cs | 4 ++-- osu.Game/Overlays/SocialOverlay.cs | 8 ++++---- osu.Game/osu.Game.csproj | 12 ++++++------ 13 files changed, 43 insertions(+), 43 deletions(-) rename osu.Game/Overlays/{Browse => SearchableList}/DisplayStyleControl.cs (96%) rename osu.Game/Overlays/{Browse => SearchableList}/HeaderTabControl.cs (91%) rename osu.Game/Overlays/{Browse/BrowseFilterControl.cs => SearchableList/SearchableListFilterControl.cs} (92%) rename osu.Game/Overlays/{Browse/BrowseHeader.cs => SearchableList/SearchableListHeader.cs} (89%) rename osu.Game/Overlays/{Browse/BrowseOverlay.cs => SearchableList/SearchableListOverlay.cs} (84%) rename osu.Game/Overlays/{Browse => SearchableList}/SlimEnumDropdown.cs (93%) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index bc82352c33..05b7597e67 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -9,11 +9,11 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Database; using osu.Game.Graphics; -using osu.Game.Overlays.Browse; +using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Direct { - public class FilterControl : BrowseFilterControl + public class FilterControl : SearchableListFilterControl { private FillFlowContainer modeButtons; @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Direct { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, - Margin = new MarginPadding { Bottom = 5, Right = BrowseOverlay.WIDTH_PADDING }, + Margin = new MarginPadding { Bottom = 5, Right = SearchableListOverlay.WIDTH_PADDING }, }); } diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index a1daa0a2b4..e5b7c7f149 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -6,11 +6,11 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.Browse; +using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Direct { - public class Header : BrowseHeader + public class Header : SearchableListHeader { protected override Color4 BackgroundColour => OsuColour.FromHex(@"252f3a"); protected override float TabStripWidth => 298; diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index d4522e227b..0aeec4397a 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -11,13 +11,13 @@ using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Direct; -using osu.Game.Overlays.Browse; +using osu.Game.Overlays.SearchableList; using OpenTK.Graphics; using System; namespace osu.Game.Overlays { - public class DirectOverlay : BrowseOverlay + public class DirectOverlay : SearchableListOverlay { private const float panel_padding = 10f; @@ -29,8 +29,8 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71"); protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); - protected override BrowseHeader CreateHeader() => new Header(); - protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListHeader CreateHeader() => new Header(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable beatmapSets; public IEnumerable BeatmapSets diff --git a/osu.Game/Overlays/Browse/DisplayStyleControl.cs b/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs similarity index 96% rename from osu.Game/Overlays/Browse/DisplayStyleControl.cs rename to osu.Game/Overlays/SearchableList/DisplayStyleControl.cs index 5570d60bb7..b37b0db139 100644 --- a/osu.Game/Overlays/Browse/DisplayStyleControl.cs +++ b/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -namespace osu.Game.Overlays.Browse +namespace osu.Game.Overlays.SearchableList { public class DisplayStyleControl : Container { diff --git a/osu.Game/Overlays/Browse/HeaderTabControl.cs b/osu.Game/Overlays/SearchableList/HeaderTabControl.cs similarity index 91% rename from osu.Game/Overlays/Browse/HeaderTabControl.cs rename to osu.Game/Overlays/SearchableList/HeaderTabControl.cs index cdac8d2dd9..56569fcca5 100644 --- a/osu.Game/Overlays/Browse/HeaderTabControl.cs +++ b/osu.Game/Overlays/SearchableList/HeaderTabControl.cs @@ -5,7 +5,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Overlays.Browse +namespace osu.Game.Overlays.SearchableList { public class HeaderTabControl : OsuTabControl { diff --git a/osu.Game/Overlays/Browse/BrowseFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs similarity index 92% rename from osu.Game/Overlays/Browse/BrowseFilterControl.cs rename to osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index a395c1c01d..4d4855b3c9 100644 --- a/osu.Game/Overlays/Browse/BrowseFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -11,9 +11,9 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Overlays.Browse +namespace osu.Game.Overlays.SearchableList { - public abstract class BrowseFilterControl : Container + public abstract class SearchableListFilterControl : Container { private const float padding = 10; @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Browse protected abstract T DefaultTab { get; } protected virtual Drawable CreateSupplementaryControls() => null; - public BrowseFilterControl() + public SearchableListFilterControl() { if (!typeof(T).IsEnum) throw new InvalidOperationException("BrowseFilterControl only supports enums as the generic type argument"); @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Browse { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = padding, Horizontal = BrowseOverlay.WIDTH_PADDING }, + Padding = new MarginPadding { Top = padding, Horizontal = SearchableListOverlay.WIDTH_PADDING }, Children = new Drawable[] { Search = new FilterSearchTextBox diff --git a/osu.Game/Overlays/Browse/BrowseHeader.cs b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs similarity index 89% rename from osu.Game/Overlays/Browse/BrowseHeader.cs rename to osu.Game/Overlays/SearchableList/SearchableListHeader.cs index 450245bde5..4ea908a8c2 100644 --- a/osu.Game/Overlays/Browse/BrowseHeader.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs @@ -10,9 +10,9 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; -namespace osu.Game.Overlays.Browse +namespace osu.Game.Overlays.SearchableList { - public abstract class BrowseHeader : Container + public abstract class SearchableListHeader : Container { public static readonly float HEIGHT = 90; @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Browse protected abstract T DefaultTab { get; } protected abstract Drawable CreateHeaderText(); - public BrowseHeader() + public SearchableListHeader() { if (!typeof(T).IsEnum) throw new InvalidOperationException("BrowseHeader only supports enums as the generic type argument"); @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.Browse new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = BrowseOverlay.WIDTH_PADDING, Right = BrowseOverlay.WIDTH_PADDING },  + Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING, Right = SearchableListOverlay.WIDTH_PADDING },  Children = new Drawable[] { new FillFlowContainer diff --git a/osu.Game/Overlays/Browse/BrowseOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs similarity index 84% rename from osu.Game/Overlays/Browse/BrowseOverlay.cs rename to osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index ba8262ef06..c2981bb350 100644 --- a/osu.Game/Overlays/Browse/BrowseOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -8,29 +8,29 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Game.Graphics.Backgrounds; -namespace osu.Game.Overlays.Browse +namespace osu.Game.Overlays.SearchableList { - public abstract class BrowseOverlay : WaveOverlayContainer + public abstract class SearchableListOverlay : WaveOverlayContainer { public static readonly float WIDTH_PADDING = 80; } //todo: naming - public abstract class BrowseOverlay : BrowseOverlay + public abstract class SearchableListOverlay : SearchableListOverlay { private readonly Container scrollContainer; - protected readonly BrowseHeader Header; - protected readonly BrowseFilterControl Filter; + protected readonly SearchableListHeader Header; + protected readonly SearchableListFilterControl Filter; protected readonly FillFlowContainer ScrollFlow; protected abstract Color4 BackgroundColour { get; } protected abstract Color4 TrianglesColourLight { get; } protected abstract Color4 TrianglesColourDark { get; } - protected abstract BrowseHeader CreateHeader(); - protected abstract BrowseFilterControl CreateFilterControl(); + protected abstract SearchableListHeader CreateHeader(); + protected abstract SearchableListFilterControl CreateFilterControl(); - public BrowseOverlay() + public SearchableListOverlay() { RelativeSizeAxes = Axes.Both; @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.Browse { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = BrowseOverlay.WIDTH_PADDING }, + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, Direction = FillDirection.Vertical, }, }, diff --git a/osu.Game/Overlays/Browse/SlimEnumDropdown.cs b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs similarity index 93% rename from osu.Game/Overlays/Browse/SlimEnumDropdown.cs rename to osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs index a3687174a0..6c0887b5df 100644 --- a/osu.Game/Overlays/Browse/SlimEnumDropdown.cs +++ b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Overlays.Browse +namespace osu.Game.Overlays.SearchableList { public class SlimEnumDropdown : OsuEnumDropdown { diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 9e15cf4fe9..848041c7c2 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -4,11 +4,11 @@ using System.ComponentModel; using OpenTK.Graphics; using osu.Game.Graphics; -using osu.Game.Overlays.Browse; +using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Social { - public class FilterControl : BrowseFilterControl + public class FilterControl : SearchableListFilterControl { protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Name; diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 47ddc61453..1e23a0866d 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Overlays.Browse; +using osu.Game.Overlays.SearchableList; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; @@ -12,7 +12,7 @@ using System.ComponentModel; namespace osu.Game.Overlays.Social { - public class Header : BrowseHeader + public class Header : SearchableListHeader { private OsuSpriteText browser; diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index e744e4ca13..c18fc0479d 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -8,13 +8,13 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -using osu.Game.Overlays.Browse; +using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; namespace osu.Game.Overlays { - public class SocialOverlay : BrowseOverlay + public class SocialOverlay : SearchableListOverlay { private readonly FillFlowContainer panelFlow; @@ -22,8 +22,8 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); - protected override BrowseFilterControl CreateFilterControl() => new FilterControl(); - protected override BrowseHeader CreateHeader() => new Header(); + protected override SearchableListHeader CreateHeader() => new Header(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable users; public IEnumerable Users diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fb1db37f65..b1bb5e5828 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -448,16 +448,16 @@ - - + + - - + + - - + + From 8359f6ced0e02441b702a7e8ce8587c4d7b5969f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 02:49:04 -0300 Subject: [PATCH 09/45] Incorrect colour --- osu.Game/Overlays/Social/Header.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 1e23a0866d..bad0e73327 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Social { private OsuSpriteText browser; - protected override Color4 BackgroundColour => OsuColour.FromHex(@"672b51"); + protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e"); protected override float TabStripWidth => 438; protected override SocialTab DefaultTab => SocialTab.OnlinePlayers; From 28ee00109d00da4f5bb25b3303c4afb7ff5aed61 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 02:55:25 -0300 Subject: [PATCH 10/45] Wave colours --- osu.Game/Overlays/SocialOverlay.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index c18fc0479d..816e50dd60 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -45,6 +45,11 @@ namespace osu.Game.Overlays public SocialOverlay() { + FirstWaveColour = OsuColour.FromHex(@"CB5FA0"); + SecondWaveColour = OsuColour.FromHex(@"B04384"); + ThirdWaveColour = OsuColour.FromHex(@"9B2B6E"); + FourthWaveColour = OsuColour.FromHex(@"6D214D"); + ScrollFlow.Children = new Drawable[] { new Container From 5785715ad5870958b7d703234cfcf8a6c70f58ac Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 03:10:36 -0300 Subject: [PATCH 11/45] CI fixes --- osu.Game/Overlays/DirectOverlay.cs | 2 +- .../SearchableList/SearchableListFilterControl.cs | 2 +- osu.Game/Overlays/SearchableList/SearchableListHeader.cs | 8 +++----- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 4 ++-- osu.Game/Overlays/SocialOverlay.cs | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 0aeec4397a..f494d4605d 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -137,7 +137,7 @@ namespace osu.Game.Overlays private void withDisplayStyleControl(Action> action) { - var f = (Filter as FilterControl); + var f = Filter as FilterControl; if (f != null) action.Invoke(f.DisplayStyleControl); } diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index 4d4855b3c9..4984546d8d 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.SearchableList protected abstract T DefaultTab { get; } protected virtual Drawable CreateSupplementaryControls() => null; - public SearchableListFilterControl() + protected SearchableListFilterControl() { if (!typeof(T).IsEnum) throw new InvalidOperationException("BrowseFilterControl only supports enums as the generic type argument"); diff --git a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs index 4ea908a8c2..b65e031488 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs @@ -14,8 +14,6 @@ namespace osu.Game.Overlays.SearchableList { public abstract class SearchableListHeader : Container { - public static readonly float HEIGHT = 90; - private readonly Box tabStrip; public readonly HeaderTabControl Tabs; @@ -25,13 +23,13 @@ namespace osu.Game.Overlays.SearchableList protected abstract T DefaultTab { get; } protected abstract Drawable CreateHeaderText(); - public SearchableListHeader() + protected SearchableListHeader() { if (!typeof(T).IsEnum) throw new InvalidOperationException("BrowseHeader only supports enums as the generic type argument"); RelativeSizeAxes = Axes.X; - Height = HEIGHT; + Height = 90; Children = new Drawable[] { @@ -54,7 +52,7 @@ namespace osu.Game.Overlays.SearchableList AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(10f, 0f), - Children = new Drawable[] + Children = new[] { new TextAwesome { diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index c2981bb350..ea4ce029e5 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.SearchableList protected abstract SearchableListHeader CreateHeader(); protected abstract SearchableListFilterControl CreateFilterControl(); - public SearchableListOverlay() + protected SearchableListOverlay() { RelativeSizeAxes = Axes.Both; @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.SearchableList { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Padding = new MarginPadding { Horizontal = WIDTH_PADDING }, Direction = FillDirection.Vertical, }, }, diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 816e50dd60..18f9dab8f4 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays get { return users; } set { - if (users == value) return; + if (users?.Equals(value) ?? false) return; users = value; panelFlow.Children = users.Select(u => From 12f6276e050878d8c4e630ee0b3b27721b16d3be Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 06:05:05 -0300 Subject: [PATCH 12/45] Move DisplayStyleControl to all FilterControls --- osu.Game/Overlays/Direct/FilterControl.cs | 14 +------------ osu.Game/Overlays/DirectOverlay.cs | 16 ++++---------- .../SearchableListFilterControl.cs | 9 +++++++- .../SearchableList/SearchableListOverlay.cs | 7 +++---- osu.Game/Overlays/Social/FilterControl.cs | 9 +++++++- osu.Game/Overlays/SocialOverlay.cs | 21 ++++--------------- 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 05b7597e67..6aa45d8321 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -13,12 +13,10 @@ using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Direct { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { private FillFlowContainer modeButtons; - public readonly DisplayStyleControl DisplayStyleControl; - protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); protected override DirectSortCritera DefaultTab => DirectSortCritera.Title; protected override Drawable CreateSupplementaryControls() @@ -32,16 +30,6 @@ namespace osu.Game.Overlays.Direct return modeButtons; } - public FilterControl() - { - Add(DisplayStyleControl = new DisplayStyleControl - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Margin = new MarginPadding { Bottom = 5, Right = SearchableListOverlay.WIDTH_PADDING }, - }); - } - [BackgroundDependencyLoader(true)] private void load(OsuGame game, RulesetDatabase rulesets, OsuColour colours) { diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index f494d4605d..0d39e6bf73 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -17,7 +17,7 @@ using System; namespace osu.Game.Overlays { - public class DirectOverlay : SearchableListOverlay + public class DirectOverlay : SearchableListOverlay { private const float panel_padding = 10f; @@ -30,7 +30,7 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); protected override SearchableListHeader CreateHeader() => new Header(); - protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable beatmapSets; public IEnumerable BeatmapSets @@ -41,9 +41,7 @@ namespace osu.Game.Overlays if (beatmapSets?.Equals(value) ?? false) return; beatmapSets = value; - var s = PanelDisplayStyle.Grid; - withDisplayStyleControl(c => s = c.DisplayStyle.Value); - recreatePanels(s); + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } } @@ -103,7 +101,7 @@ namespace osu.Game.Overlays Header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) Filter.Search.Text = string.Empty; }; Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; }; - withDisplayStyleControl(c => c.DisplayStyle.ValueChanged += recreatePanels); + Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; updateResultCounts(); } @@ -135,12 +133,6 @@ namespace osu.Game.Overlays panels.Children = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b)); } - private void withDisplayStyleControl(Action> action) - { - var f = Filter as FilterControl; - if (f != null) action.Invoke(f.DisplayStyleControl); - } - public class ResultCounts { public readonly int Artists; diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index 4984546d8d..54863e0219 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.SearchableList { - public abstract class SearchableListFilterControl : Container + public abstract class SearchableListFilterControl : Container { private const float padding = 10; @@ -21,6 +21,7 @@ namespace osu.Game.Overlays.SearchableList public readonly SearchTextBox Search; public readonly PageTabControl Tabs; + public readonly DisplayStyleControl DisplayStyleControl; protected abstract Color4 BackgroundColour { get; } protected abstract T DefaultTab { get; } @@ -80,6 +81,12 @@ namespace osu.Game.Overlays.SearchableList }, }, }, + DisplayStyleControl = new DisplayStyleControl + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Margin = new MarginPadding { Bottom = 5, Right = SearchableListOverlay.WIDTH_PADDING }, + }, }; if (controls != null) controlsContainer.Children = new[] { controls }; diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index ea4ce029e5..7e0be0ff92 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -15,20 +15,19 @@ namespace osu.Game.Overlays.SearchableList public static readonly float WIDTH_PADDING = 80; } - //todo: naming - public abstract class SearchableListOverlay : SearchableListOverlay + public abstract class SearchableListOverlay : SearchableListOverlay { private readonly Container scrollContainer; protected readonly SearchableListHeader Header; - protected readonly SearchableListFilterControl Filter; + protected readonly SearchableListFilterControl Filter; protected readonly FillFlowContainer ScrollFlow; protected abstract Color4 BackgroundColour { get; } protected abstract Color4 TrianglesColourLight { get; } protected abstract Color4 TrianglesColourDark { get; } protected abstract SearchableListHeader CreateHeader(); - protected abstract SearchableListFilterControl CreateFilterControl(); + protected abstract SearchableListFilterControl CreateFilterControl(); protected SearchableListOverlay() { diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 848041c7c2..30470097e6 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -3,15 +3,22 @@ using System.ComponentModel; using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Social { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Name; + + public FilterControl() + { + Tabs.Margin = new MarginPadding { Top = 10 }; + } } public enum SocialSortCriteria diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 18f9dab8f4..64ad26b137 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Users; namespace osu.Game.Overlays { - public class SocialOverlay : SearchableListOverlay + public class SocialOverlay : SearchableListOverlay { private readonly FillFlowContainer panelFlow; @@ -23,7 +23,7 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); protected override SearchableListHeader CreateHeader() => new Header(); - protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable users; public IEnumerable Users @@ -50,26 +50,13 @@ namespace osu.Game.Overlays ThirdWaveColour = OsuColour.FromHex(@"9B2B6E"); FourthWaveColour = OsuColour.FromHex(@"6D214D"); - ScrollFlow.Children = new Drawable[] + ScrollFlow.Children = new[] { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Vertical = 10 }, - Children = new[] - { - new DisplayStyleControl - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }, - }, - }, panelFlow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 20 }, Spacing = new Vector2(10f), }, }; From c0999c7fc117b4b41b38d42585c523d9197a30f5 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 26 May 2017 06:12:22 -0300 Subject: [PATCH 13/45] Unused using directives --- osu.Game/Overlays/DirectOverlay.cs | 1 - osu.Game/Overlays/Social/FilterControl.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 0d39e6bf73..916c774ecc 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Direct; using osu.Game.Overlays.SearchableList; using OpenTK.Graphics; -using System; namespace osu.Game.Overlays { diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 30470097e6..feb3c737f0 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -4,7 +4,6 @@ using System.ComponentModel; using OpenTK.Graphics; using osu.Framework.Graphics; -using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Overlays.SearchableList; From 7bdbd3713adc236fe3119d282ecde3d079eb2ce7 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 27 May 2017 17:23:14 -0300 Subject: [PATCH 14/45] More reliable test data --- osu.Desktop.VisualTests/Tests/TestCaseSocial.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs index 37d85ce0c9..1f2f655a5a 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs @@ -24,14 +24,14 @@ namespace osu.Desktop.VisualTests.Tests Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3103765/5b012e13611d5761caa7e24fecb3d3a16e1cf48fc2a3032cfd43dd444af83d82.jpeg", + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", }, new User { Username = @"Cookiezi", Id = 124493, Country = new Country { FlagName = @"KR" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg", + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg", }, new User { @@ -45,35 +45,35 @@ namespace osu.Desktop.VisualTests.Tests Username = @"Rafis", Id = 2558286, Country = new Country { FlagName = @"PL" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c5.jpg", + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg", }, new User { Username = @"hvick225", Id = 50265, Country = new Country { FlagName = @"TW" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/50265/cb79df0d6ddd04b57d057623417aa55c505810d8e73b1a96d6e665e0e18e5770.jpeg", + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c5.jpg", }, new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/2/615362d26dc37cc4d46e61a08a2537e7cdf0e0e00f40574b18bf90156ad0280f.jpeg" + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg" }, new User { Username = @"filsdelama", Id = 2831793, Country = new Country { FlagName = @"FR" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg" + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c7.jpg" }, new User { Username = @"_index", Id = 652457, Country = new Country { FlagName = @"RU" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c7.jpg" + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c8.jpg" }, }, }; From 239472c451c010067d6bcc72c1e5889f4e48b2b6 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 27 May 2017 18:35:46 -0300 Subject: [PATCH 15/45] Lowercase hex colours --- osu.Game/Overlays/SocialOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 64ad26b137..2b4dfe9198 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -45,10 +45,10 @@ namespace osu.Game.Overlays public SocialOverlay() { - FirstWaveColour = OsuColour.FromHex(@"CB5FA0"); - SecondWaveColour = OsuColour.FromHex(@"B04384"); - ThirdWaveColour = OsuColour.FromHex(@"9B2B6E"); - FourthWaveColour = OsuColour.FromHex(@"6D214D"); + FirstWaveColour = OsuColour.FromHex(@"cb5fa0"); + SecondWaveColour = OsuColour.FromHex(@"b04384"); + ThirdWaveColour = OsuColour.FromHex(@"9b2b6e"); + FourthWaveColour = OsuColour.FromHex(@"6d214d"); ScrollFlow.Children = new[] { From 816caf86eabe5d5a7a7471a740a212da2e7ad969 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 27 May 2017 18:49:55 -0300 Subject: [PATCH 16/45] Better exception for SearchableListFilterControl's generic type argument not being an enum --- osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index 54863e0219..50011e4b8e 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.SearchableList protected SearchableListFilterControl() { if (!typeof(T).IsEnum) - throw new InvalidOperationException("BrowseFilterControl only supports enums as the generic type argument"); + throw new InvalidOperationException("SearchableListFilterControl's sort tabs only support enums as the generic type argument"); RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From 8994c57f3c4f54e389d35a2b67af6ab17baa97ea Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sun, 28 May 2017 15:14:22 -0300 Subject: [PATCH 17/45] Update with framework changes --- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 7e0be0ff92..7a32b74032 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -102,7 +102,7 @@ namespace osu.Game.Overlays.SearchableList protected override bool OnFocus(InputState state) { - Filter.Search.TriggerFocus(); + Filter.Search.TriggerOnFocus(); return false; } From b6cb9d32298e70dc77764466286420ac1b006e50 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 29 May 2017 22:39:59 -0300 Subject: [PATCH 18/45] Fix display style dropdown scaling the filter control --- .../SearchableListFilterControl.cs | 84 +++++++++++-------- .../SearchableList/SearchableListOverlay.cs | 23 ++--- 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index 50011e4b8e..95651833d3 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -17,6 +18,7 @@ namespace osu.Game.Overlays.SearchableList { private const float padding = 10; + private readonly Container filterContainer; private readonly Box tabStrip; public readonly SearchTextBox Search; @@ -27,65 +29,73 @@ namespace osu.Game.Overlays.SearchableList protected abstract T DefaultTab { get; } protected virtual Drawable CreateSupplementaryControls() => null; + protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || DisplayStyleControl.Dropdown.Contains(screenSpacePos); + protected SearchableListFilterControl() { if (!typeof(T).IsEnum) throw new InvalidOperationException("SearchableListFilterControl's sort tabs only support enums as the generic type argument"); RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; var controls = CreateSupplementaryControls(); Container controlsContainer; Children = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = BackgroundColour, - Alpha = 0.9f, - }, - tabStrip = new Box - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - }, - new FillFlowContainer + filterContainer = new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = padding, Horizontal = SearchableListOverlay.WIDTH_PADDING }, Children = new Drawable[] { - Search = new FilterSearchTextBox + new Box { - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + Colour = BackgroundColour, + Alpha = 0.9f, }, - controlsContainer = new Container + tabStrip = new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + }, + new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = controls != null ? padding : 0 }, - }, - Tabs = new PageTabControl - { - RelativeSizeAxes = Axes.X, - }, - new Box //keep the tab strip part of autosize, but don't put it in the flow container - { - RelativeSizeAxes = Axes.X, - Height = 1, - Colour = Color4.White.Opacity(0), + Padding = new MarginPadding { Top = padding, Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Children = new Drawable[] + { + Search = new FilterSearchTextBox + { + RelativeSizeAxes = Axes.X, + }, + controlsContainer = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = controls != null ? padding : 0 }, + }, + Tabs = new PageTabControl + { + RelativeSizeAxes = Axes.X, + }, + new Box //keep the tab strip part of autosize, but don't put it in the flow container + { + RelativeSizeAxes = Axes.X, + Height = 1, + Colour = Color4.White.Opacity(0), + }, + }, }, }, }, DisplayStyleControl = new DisplayStyleControl { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Margin = new MarginPadding { Bottom = 5, Right = SearchableListOverlay.WIDTH_PADDING }, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, }, }; @@ -101,6 +111,14 @@ namespace osu.Game.Overlays.SearchableList tabStrip.Colour = colours.Yellow; } + protected override void Update() + { + base.Update(); + + Height = filterContainer.Height; + DisplayStyleControl.Margin = new MarginPadding { Top = filterContainer.Height - 35, Right = SearchableListOverlay.WIDTH_PADDING }; + } + private class FilterSearchTextBox : SearchTextBox { protected override Color4 BackgroundUnfocused => backgroundColour; diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 7a32b74032..4f96807eb7 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -55,17 +55,6 @@ namespace osu.Game.Overlays.SearchableList }, }, }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - Header = CreateHeader(), - Filter = CreateFilterControl(), - }, - }, scrollContainer = new Container { RelativeSizeAxes = Axes.Both, @@ -88,6 +77,18 @@ namespace osu.Game.Overlays.SearchableList }, }, }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + AlwaysReceiveInput = true, + Children = new Drawable[] + { + Header = CreateHeader(), + Filter = CreateFilterControl(), + }, + }, }; Filter.Search.Exit = Hide; From a1453eb9e1f0c6b14990f50ec8febedc00311379 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 29 May 2017 22:52:38 -0300 Subject: [PATCH 19/45] Fix filter text box input --- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 4f96807eb7..7f9aed3939 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -103,7 +103,7 @@ namespace osu.Game.Overlays.SearchableList protected override bool OnFocus(InputState state) { - Filter.Search.TriggerOnFocus(); + InputManager.ChangeFocus(Filter.Search); return false; } From 9942733b63ea3b3753441bb7f79629c791cea860 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 31 May 2017 05:22:54 -0300 Subject: [PATCH 20/45] Trim whitespace --- osu.Game/Overlays/DirectOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 281d27b7c1..916c774ecc 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -131,7 +131,7 @@ namespace osu.Game.Overlays if (BeatmapSets == null) return; panels.Children = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b)); } - + public class ResultCounts { public readonly int Artists; From ec8a88c96a1b5dfee6d98febd17f2547b22c856f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 31 May 2017 05:28:50 -0300 Subject: [PATCH 21/45] Update with framework changes --- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 7f9aed3939..7705fa0582 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.SearchableList new ScrollContainer { RelativeSizeAxes = Axes.Both, - ScrollDraggerVisible = false, + ScrollbarVisible = false, Children = new[] { ScrollFlow = new FillFlowContainer @@ -101,10 +101,9 @@ namespace osu.Game.Overlays.SearchableList scrollContainer.Padding = new MarginPadding { Top = Header.Height + Filter.Height }; } - protected override bool OnFocus(InputState state) + protected override void OnFocus(InputState state) { InputManager.ChangeFocus(Filter.Search); - return false; } protected override void PopIn() From 0439b15728bb42051dc496dbcc7a260b2e7d5cde Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 31 May 2017 21:29:50 -0300 Subject: [PATCH 22/45] Generic type argument formatting --- osu.Game/Overlays/Direct/FilterControl.cs | 2 +- osu.Game/Overlays/DirectOverlay.cs | 4 ++-- osu.Game/Overlays/Social/FilterControl.cs | 2 +- osu.Game/Overlays/SocialOverlay.cs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 6aa45d8321..455d0ab77b 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Direct { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { private FillFlowContainer modeButtons; diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 916c774ecc..93c440384b 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -16,7 +16,7 @@ using OpenTK.Graphics; namespace osu.Game.Overlays { - public class DirectOverlay : SearchableListOverlay + public class DirectOverlay : SearchableListOverlay { private const float panel_padding = 10f; @@ -29,7 +29,7 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); protected override SearchableListHeader CreateHeader() => new Header(); - protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable beatmapSets; public IEnumerable BeatmapSets diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index feb3c737f0..789c7b6a64 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.SearchableList; namespace osu.Game.Overlays.Social { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Name; diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 2b4dfe9198..448539607d 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Users; namespace osu.Game.Overlays { - public class SocialOverlay : SearchableListOverlay + public class SocialOverlay : SearchableListOverlay { private readonly FillFlowContainer panelFlow; @@ -23,7 +23,7 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648"); protected override SearchableListHeader CreateHeader() => new Header(); - protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable users; public IEnumerable Users From c9403c520033e0cef8e7b2ad5c1c3ed2e5dc7d5c Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 31 May 2017 21:32:50 -0300 Subject: [PATCH 23/45] Incorrect test data spelling --- osu.Desktop.VisualTests/Tests/TestCaseSocial.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs index 1f2f655a5a..eb7df96355 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseSocial.cs @@ -35,7 +35,7 @@ namespace osu.Desktop.VisualTests.Tests }, new User { - Username = @"Angelism", + Username = @"Angelsim", Id = 1777162, Country = new Country { FlagName = @"KR" }, CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg", From c624712f2f413df06ee8e1670846d3210e5b5fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Mon, 5 Jun 2017 23:45:22 +0200 Subject: [PATCH 24/45] Refactor ppv2 to allow integration of pp+ features. --- .../Objects/OsuHitObjectDifficulty.cs | 201 ------------------ .../OsuDifficulty/OsuDifficultyCalculator.cs | 73 +++++++ .../Preprocessing/OsuDifficultyBeatmap.cs | 83 ++++++++ .../Preprocessing/OsuDifficultyHitObject.cs | 58 +++++ .../OsuDifficulty/Skills/Aim.cs | 15 ++ .../OsuDifficulty/Skills/Skill.cs | 85 ++++++++ .../OsuDifficulty/Skills/Speed.cs | 34 +++ .../OsuDifficulty/Utils/History.cs | 73 +++++++ .../OsuDifficultyCalculator.cs | 192 ----------------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 1 + .../osu.Game.Rulesets.Osu.csproj | 9 +- 11 files changed, 429 insertions(+), 395 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs create mode 100644 osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs delete mode 100644 osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs deleted file mode 100644 index 1786771dca..0000000000 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using System; -using System.Diagnostics; -using System.Linq; - -namespace osu.Game.Rulesets.Osu.Objects -{ - internal class OsuHitObjectDifficulty - { - /// - /// Factor by how much speed / aim strain decays per second. - /// - /// - /// These values are results of tweaking a lot and taking into account general feedback. - /// Opinionated observation: Speed is easier to maintain than accurate jumps. - /// - internal static readonly double[] DECAY_BASE = { 0.3, 0.15 }; - - /// - /// Pseudo threshold values to distinguish between "singles" and "streams" - /// - /// - /// Of course the border can not be defined clearly, therefore the algorithm has a smooth transition between those values. - /// They also are based on tweaking and general feedback. - /// - private const double stream_spacing_threshold = 110, - single_spacing_threshold = 125; - - /// - /// Scaling values for weightings to keep aim and speed difficulty in balance. - /// - /// - /// Found from testing a very large map pool (containing all ranked maps) and keeping the average values the same. - /// - private static readonly double[] spacing_weight_scaling = { 1400, 26.25 }; - - /// - /// Almost the normed diameter of a circle (104 osu pixel). That is -after- position transforming. - /// - private const double almost_diameter = 90; - - internal OsuHitObject BaseHitObject; - internal double[] Strains = { 1, 1 }; - - internal int MaxCombo = 1; - - private readonly float scalingFactor; - private float lazySliderLength; - - private readonly Vector2 startPosition; - private readonly Vector2 endPosition; - - internal OsuHitObjectDifficulty(OsuHitObject baseHitObject) - { - BaseHitObject = baseHitObject; - float circleRadius = baseHitObject.Scale * 64; - - Slider slider = BaseHitObject as Slider; - if (slider != null) - MaxCombo += slider.Ticks.Count(); - - // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps. - scalingFactor = 52.0f / circleRadius; - if (circleRadius < 30) - { - float smallCircleBonus = Math.Min(30.0f - circleRadius, 5.0f) / 50.0f; - scalingFactor *= 1.0f + smallCircleBonus; - } - - lazySliderLength = 0; - startPosition = baseHitObject.StackedPosition; - - // Calculate approximation of lazy movement on the slider - if (slider != null) - { - float sliderFollowCircleRadius = circleRadius * 3; // Not sure if this is correct, but here we do not need 100% exact values. This comes pretty darn close in my tests. - - // For simplifying this step we use actual osu! coordinates and simply scale the length, that we obtain by the ScalingFactor later - Vector2 cursorPos = startPosition; - - Action addSliderVertex = delegate (Vector2 pos) - { - Vector2 difference = pos - cursorPos; - float distance = difference.Length; - - // Did we move away too far? - if (distance > sliderFollowCircleRadius) - { - // Yep, we need to move the cursor - difference.Normalize(); // Obtain the direction of difference. We do no longer need the actual difference - distance -= sliderFollowCircleRadius; - cursorPos += difference * distance; // We move the cursor just as far as needed to stay in the follow circle - lazySliderLength += distance; - } - }; - - // Actual computation of the first lazy curve - foreach (var tick in slider.Ticks) - addSliderVertex(tick.StackedPosition); - - addSliderVertex(baseHitObject.StackedEndPosition); - - lazySliderLength *= scalingFactor; - endPosition = cursorPos; - } - // We have a normal HitCircle or a spinner - else - endPosition = startPosition; - } - - internal void CalculateStrains(OsuHitObjectDifficulty previousHitObject, double timeRate) - { - calculateSpecificStrain(previousHitObject, OsuDifficultyCalculator.DifficultyType.Speed, timeRate); - calculateSpecificStrain(previousHitObject, OsuDifficultyCalculator.DifficultyType.Aim, timeRate); - } - - // Caution: The subjective values are strong with this one - private static double spacingWeight(double distance, OsuDifficultyCalculator.DifficultyType type) - { - switch (type) - { - case OsuDifficultyCalculator.DifficultyType.Speed: - if (distance > single_spacing_threshold) - return 2.5; - else if (distance > stream_spacing_threshold) - return 1.6 + 0.9 * (distance - stream_spacing_threshold) / (single_spacing_threshold - stream_spacing_threshold); - else if (distance > almost_diameter) - return 1.2 + 0.4 * (distance - almost_diameter) / (stream_spacing_threshold - almost_diameter); - else if (distance > almost_diameter / 2) - return 0.95 + 0.25 * (distance - almost_diameter / 2) / (almost_diameter / 2); - else - return 0.95; - - case OsuDifficultyCalculator.DifficultyType.Aim: - return Math.Pow(distance, 0.99); - } - - Debug.Assert(false, "Invalid osu difficulty hit object type."); - return 0; - } - - private void calculateSpecificStrain(OsuHitObjectDifficulty previousHitObject, OsuDifficultyCalculator.DifficultyType type, double timeRate) - { - double addition = 0; - double timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) / timeRate; - double decay = Math.Pow(DECAY_BASE[(int)type], timeElapsed / 1000); - - if (BaseHitObject is Spinner) - { - // Do nothing for spinners - } - else if (BaseHitObject is Slider) - { - switch (type) - { - case OsuDifficultyCalculator.DifficultyType.Speed: - - // For speed strain we treat the whole slider as a single spacing entity, since "Speed" is about how hard it is to click buttons fast. - // The spacing weight exists to differentiate between being able to easily alternate or having to single. - addition = - spacingWeight(previousHitObject.lazySliderLength + - DistanceTo(previousHitObject), type) * - spacing_weight_scaling[(int)type]; - - break; - case OsuDifficultyCalculator.DifficultyType.Aim: - - // For Aim strain we treat each slider segment and the jump after the end of the slider as separate jumps, since movement-wise there is no difference - // to multiple jumps. - addition = - ( - spacingWeight(previousHitObject.lazySliderLength, type) + - spacingWeight(DistanceTo(previousHitObject), type) - ) * - spacing_weight_scaling[(int)type]; - - break; - } - } - else if (BaseHitObject is HitCircle) - { - addition = spacingWeight(DistanceTo(previousHitObject), type) * spacing_weight_scaling[(int)type]; - } - - // Scale addition by the time, that elapsed. Filter out HitObjects that are too close to be played anyway to avoid crazy values by division through close to zero. - // You will never find maps that require this amongst ranked maps. - addition /= Math.Max(timeElapsed, 50); - - Strains[(int)type] = previousHitObject.Strains[(int)type] * decay + addition; - } - - internal double DistanceTo(OsuHitObjectDifficulty other) - { - // Scale the distance by circle size. - return (startPosition - other.endPosition).Length * scalingFactor; - } - } -} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs new file mode 100644 index 0000000000..ee26109dd7 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Beatmaps; +using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +using osu.Game.Rulesets.Osu.OsuDifficulty.Skills; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty +{ + public class OsuDifficultyCalculator : DifficultyCalculator + { + private const int section_length = 400; + private const double difficulty_multiplier = 0.0675; + + public OsuDifficultyCalculator(Beatmap beatmap) : base(beatmap) + { + } + + protected override void PreprocessHitObjects() + { + foreach (OsuHitObject h in Objects) + (h as Slider)?.Curve?.Calculate(); + } + + protected override double CalculateInternal(Dictionary categoryDifficulty) + { + OsuDifficulyBeatmap beatmap = new OsuDifficulyBeatmap(Objects); + Skill[] skills = new Skill[2] + { + new Aim(), + new Speed() + }; + + double sectionEnd = section_length / TimeRate; + foreach (OsuDifficultyHitObject h in beatmap) + { + while (h.BaseObject.StartTime > sectionEnd) + { + foreach (Skill s in skills) + { + s.SaveCurrentPeak(); + s.StartNewSectionFrom(sectionEnd); + } + + sectionEnd += section_length; + } + + foreach (Skill s in skills) + s.Process(h); + } + + double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; + double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; + + double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; + + if (categoryDifficulty != null) + { + categoryDifficulty.Add("Aim", aimRating.ToString("0.00")); + categoryDifficulty.Add("Speed", speedRating.ToString("0.00")); + } + + return starRating; + } + + protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs new file mode 100644 index 0000000000..35a84a3018 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections; +using System.Collections.Generic; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing +{ + public class OsuDifficulyBeatmap : IEnumerable + { + IEnumerator difficultyObjects; + private Queue onScreen = new Queue(); + + public OsuDifficulyBeatmap(List objects) + { + // Sort HitObjects by StartTime - they are not correctly ordered in some cases. + // This should probably happen before the objects reach the difficulty calculator. + objects.Sort((a, b) => a.StartTime.CompareTo(b.StartTime)); + difficultyObjects = createDifficultyObjectEnumerator(objects); + } + + public IEnumerator GetEnumerator() + { + do + { + // Add upcoming notes to the queue until we have at least one note that had been hit and can be dequeued. + // This means there is always at least one note in the queue unless we reached the end of the map. + bool hasNext; + do + { + hasNext = difficultyObjects.MoveNext(); + if (onScreen.Count == 0 && !hasNext) + yield break; // Stop if we have an empty enumerator. + + if (hasNext) + { + OsuDifficultyHitObject latest = difficultyObjects.Current; + // Calculate flow values here + + foreach (OsuDifficultyHitObject h in onScreen) + { + h.MSUntilHit -= latest.MS; + // Calculate reading strain here + } + + onScreen.Enqueue(latest); + } + } + while (onScreen.Peek().MSUntilHit > 0 && hasNext); // Keep adding new notes on screen while there is still time before we have to hit the next one. + + yield return onScreen.Dequeue(); // Remove and return notes one by one that had to be hit before the latest note appeared. + } + while (onScreen.Count > 0); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator createDifficultyObjectEnumerator(List objects) + { + // We will process HitObjects in groups of three to form a triangle, so we can calculate an angle for each note. + OsuHitObject[] triangle = new OsuHitObject[3]; + + // Difficulty object construction requires three components, an extra copy of the first object is used at the beginning. + if (objects.Count > 1) + { + triangle[1] = objects[0]; // This copy will get shifted to the last spot in the triangle. + triangle[0] = objects[0]; // This is the real first note. + } + + // The final component of the first triangle will be the second note, which forms the first jump. + // If the beatmap has less than two HitObjects, the enumerator will not return anything. + for (int i = 1; i < objects.Count; ++i) + { + triangle[2] = triangle[1]; + triangle[1] = triangle[0]; + triangle[0] = objects[i]; + + yield return new OsuDifficultyHitObject(triangle); + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs new file mode 100644 index 0000000000..ca10b19fc1 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing +{ + public class OsuDifficultyHitObject + { + public OsuHitObject BaseObject { get; } + + /// + /// Normalized distance from the StartPosition of the previous note. + /// + public double Distance { get; private set; } + + /// + /// Milliseconds elapsed since the StartTime of the previous note. + /// + public double MS { get; private set; } + + public double MSUntilHit { get; set; } + + private const int normalized_radius = 52; + + private OsuHitObject[] t; + + public OsuDifficultyHitObject(OsuHitObject[] triangle) + { + t = triangle; + BaseObject = t[0]; + setDistances(); + setTimingValues(); + // Calculate angle here + } + + private void setDistances() + { + // We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps. + double scalingFactor = normalized_radius / BaseObject.Radius; + if (BaseObject.Radius < 30) + { + double smallCircleBonus = Math.Min(30 - BaseObject.Radius, 5) / 50; + scalingFactor *= 1 + smallCircleBonus; + } + + Distance = (t[0].StackedPosition - t[1].StackedPosition).Length * scalingFactor; + } + + private void setTimingValues() + { + // Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure. + MS = Math.Max(40, t[0].StartTime - t[1].StartTime); + MSUntilHit = 450; // BaseObject.PreEmpt; + } + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs new file mode 100644 index 0000000000..2880098627 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +{ + public class Aim : Skill + { + protected override double skillMultiplier => 26.25; + protected override double strainDecayBase => 0.15; + + protected override double strainValue() => Math.Pow(current.Distance, 0.99) / current.MS; + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs new file mode 100644 index 0000000000..3ac23ccd34 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +using osu.Game.Rulesets.Osu.OsuDifficulty.Utils; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +{ + public abstract class Skill + { + protected abstract double skillMultiplier { get; } + protected abstract double strainDecayBase { get; } + + protected OsuDifficultyHitObject current; + protected History previous = new History(2); // Contained objects not used yet + + private double currentStrain = 1; // We keep track of the strain level at all times throughout the beatmap. + private double currentSectionPeak = 1; // We also keep track of the peak strain level in the current section. + private List strainPeaks = new List(); + + /// + /// Process a HitObject and update current strain values accordingly. + /// + public void Process(OsuDifficultyHitObject h) + { + current = h; + + currentStrain *= strainDecay(current.MS); + if (!(current.BaseObject is Spinner)) + currentStrain += strainValue() * skillMultiplier; + + currentSectionPeak = Math.Max(currentStrain, currentSectionPeak); + + previous.Push(current); + } + + /// + /// Saves the current peak strain level to the list of strain peaks, which will be used to calculate an overall difficulty. + /// + public void SaveCurrentPeak() + { + if (previous.Count > 0) + strainPeaks.Add(currentSectionPeak); + } + + /// + /// Sets the initial strain level for a new section. + /// + /// The beginning of the new section in milliseconds + public void StartNewSectionFrom(double offset) + { + // The maximum strain of the new section is not zero by default, strain decays as usual regardless of section boundaries. + // This means we need to capture the strain level at the beginning of the new section, and use that as the initial peak level. + if (previous.Count > 0) + currentSectionPeak = currentStrain * strainDecay(offset - previous[0].BaseObject.StartTime); + } + + /// + /// Returns the calculated difficulty value representing all currently processed HitObjects. + /// + public double DifficultyValue() + { + strainPeaks.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain. + + double difficulty = 0; + double weight = 1; + + // Difficulty is the weighted sum of the highest strains from every section. + foreach (double strain in strainPeaks) + { + difficulty += strain * weight; + weight *= 0.9; + } + + return difficulty; + } + + protected abstract double strainValue(); + + private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs new file mode 100644 index 0000000000..42da6b8ed2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +{ + public class Speed : Skill + { + protected override double skillMultiplier => 1400; + protected override double strainDecayBase => 0.3; + + private const double single_spacing_threshold = 125; + private const double stream_spacing_threshold = 110; + private const double almost_diameter = 90; + + protected override double strainValue() + { + double distance = current.Distance; + + double speedValue; + if (distance > single_spacing_threshold) + speedValue = 2.5; + else if (distance > stream_spacing_threshold) + speedValue = 1.6 + 0.9 * (distance - stream_spacing_threshold) / (single_spacing_threshold - stream_spacing_threshold); + else if (distance > almost_diameter) + speedValue = 1.2 + 0.4 * (distance - almost_diameter) / (stream_spacing_threshold - almost_diameter); + else if (distance > almost_diameter / 2) + speedValue = 0.95 + 0.25 * (distance - almost_diameter / 2) / (almost_diameter / 2); + else + speedValue = 0.95; + + return speedValue / current.MS; + } + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs new file mode 100644 index 0000000000..4bf20b1830 --- /dev/null +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils +{ + /// + /// An indexed stack with Push() only, which disposes items at the bottom once the size limit has been reached. + /// Indexing starts at the top of the stack. + /// + public class History : IEnumerable + { + public int Count { get; private set; } = 0; + + private T[] array; + private int size; + private int marker; // Marks the position of the most recently added item. + + public History(int size) + { + this.size = size; + array = new T[size]; + marker = size; // Set marker to the end of the array, outside of the indexed range by one. + } + + public T this[int i] // Index 0 returns the most recently added item. + { + get + { + if (i > Count - 1) + throw new IndexOutOfRangeException(); + + i += marker; + if (i > size - 1) + i -= size; + + return array[i]; + } + } + + /// + /// Adds the element as the most recent one in the history. + /// The oldest element is disposed if the history is full. + /// + public void Push(T item) // Overwrite the oldest item instead of shifting every item by one with every addition. + { + if (marker == 0) + marker = size - 1; + else + --marker; + + array[marker] = item; + + if (Count < size) + ++Count; + } + + public IEnumerator GetEnumerator() + { + for (int i = marker; i < size; ++i) + yield return array[i]; + + if (Count == size) + for (int i = 0; i < marker; ++i) + yield return array[i]; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs deleted file mode 100644 index 5669993e67..0000000000 --- a/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Beatmaps; -using osu.Game.Rulesets.Osu.Beatmaps; -using osu.Game.Rulesets.Osu.Objects; -using System; -using System.Collections.Generic; - -namespace osu.Game.Rulesets.Osu -{ - public class OsuDifficultyCalculator : DifficultyCalculator - { - private const double star_scaling_factor = 0.0675; - private const double extreme_scaling_factor = 0.5; - - /// - /// HitObjects are stored as a member variable. - /// - internal List DifficultyHitObjects = new List(); - - public OsuDifficultyCalculator(Beatmap beatmap) : base(beatmap) - { - } - - protected override void PreprocessHitObjects() - { - foreach (var h in Objects) - (h as Slider)?.Curve?.Calculate(); - } - - protected override double CalculateInternal(Dictionary categoryDifficulty) - { - // Fill our custom DifficultyHitObject class, that carries additional information - DifficultyHitObjects.Clear(); - - foreach (var hitObject in Objects) - DifficultyHitObjects.Add(new OsuHitObjectDifficulty(hitObject)); - - // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. - DifficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime)); - - if (!CalculateStrainValues()) return 0; - - double speedDifficulty = CalculateDifficulty(DifficultyType.Speed); - double aimDifficulty = CalculateDifficulty(DifficultyType.Aim); - - // OverallDifficulty is not considered in this algorithm and neither is HpDrainRate. That means, that in this form the algorithm determines how hard it physically is - // to play the map, assuming, that too much of an error will not lead to a death. - // It might be desirable to include OverallDifficulty into map difficulty, but in my personal opinion it belongs more to the weighting of the actual peformance - // and is superfluous in the beatmap difficulty rating. - // If it were to be considered, then I would look at the hit window of normal HitCircles only, since Sliders and Spinners are (almost) "free" 300s and take map length - // into account as well. - - // The difficulty can be scaled by any desired metric. - // In osu!tp it gets squared to account for the rapid increase in difficulty as the limit of a human is approached. (Of course it also gets scaled afterwards.) - // It would not be suitable for a star rating, therefore: - - // The following is a proposal to forge a star rating from 0 to 5. It consists of taking the square root of the difficulty, since by simply scaling the easier - // 5-star maps would end up with one star. - double speedStars = Math.Sqrt(speedDifficulty) * star_scaling_factor; - double aimStars = Math.Sqrt(aimDifficulty) * star_scaling_factor; - - if (categoryDifficulty != null) - { - categoryDifficulty.Add("Aim", aimStars.ToString("0.00")); - categoryDifficulty.Add("Speed", speedStars.ToString("0.00")); - - double hitWindow300 = 30/*HitObjectManager.HitWindow300*/ / TimeRate; - double preEmpt = 450/*HitObjectManager.PreEmpt*/ / TimeRate; - - categoryDifficulty.Add("OD", (-(hitWindow300 - 80.0) / 6.0).ToString("0.00")); - categoryDifficulty.Add("AR", (preEmpt > 1200.0 ? -(preEmpt - 1800.0) / 120.0 : -(preEmpt - 1200.0) / 150.0 + 5.0).ToString("0.00")); - - int maxCombo = 0; - foreach (OsuHitObjectDifficulty hitObject in DifficultyHitObjects) - maxCombo += hitObject.MaxCombo; - - categoryDifficulty.Add("Max combo", maxCombo.ToString()); - } - - // Again, from own observations and from the general opinion of the community a map with high speed and low aim (or vice versa) difficulty is harder, - // than a map with mediocre difficulty in both. Therefore we can not just add both difficulties together, but will introduce a scaling that favors extremes. - double starRating = speedStars + aimStars + Math.Abs(speedStars - aimStars) * extreme_scaling_factor; - // Another approach to this would be taking Speed and Aim separately to a chosen power, which again would be equivalent. This would be more convenient if - // the hit window size is to be considered as well. - - // Note: The star rating is tuned extremely tight! Airman (/b/104229) and Freedom Dive (/b/126645), two of the hardest ranked maps, both score ~4.66 stars. - // Expect the easier kind of maps that officially get 5 stars to obtain around 2 by this metric. The tutorial still scores about half a star. - // Tune by yourself as you please. ;) - - return starRating; - } - - protected bool CalculateStrainValues() - { - // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment. - using (List.Enumerator hitObjectsEnumerator = DifficultyHitObjects.GetEnumerator()) - { - - if (!hitObjectsEnumerator.MoveNext()) return false; - - OsuHitObjectDifficulty current = hitObjectsEnumerator.Current; - - // First hitObject starts at strain 1. 1 is the default for strain values, so we don't need to set it here. See DifficultyHitObject. - while (hitObjectsEnumerator.MoveNext()) - { - var next = hitObjectsEnumerator.Current; - next?.CalculateStrains(current, TimeRate); - current = next; - } - - return true; - } - } - - /// - /// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP. - /// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain. - /// The higher this value, the less strains there will be, indirectly giving long beatmaps an advantage. - /// - protected const double STRAIN_STEP = 400; - - /// - /// The weighting of each strain value decays to this number * it's previous value - /// - protected const double DECAY_WEIGHT = 0.9; - - protected double CalculateDifficulty(DifficultyType type) - { - double actualStrainStep = STRAIN_STEP * TimeRate; - - // Find the highest strain value within each strain step - List highestStrains = new List(); - double intervalEndTime = actualStrainStep; - double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval - - OsuHitObjectDifficulty previousHitObject = null; - foreach (OsuHitObjectDifficulty hitObject in DifficultyHitObjects) - { - // While we are beyond the current interval push the currently available maximum to our strain list - while (hitObject.BaseHitObject.StartTime > intervalEndTime) - { - highestStrains.Add(maximumStrain); - - // The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay - // until the beginning of the next interval. - if (previousHitObject == null) - { - maximumStrain = 0; - } - else - { - double decay = Math.Pow(OsuHitObjectDifficulty.DECAY_BASE[(int)type], (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000); - maximumStrain = previousHitObject.Strains[(int)type] * decay; - } - - // Go to the next time interval - intervalEndTime += actualStrainStep; - } - - // Obtain maximum strain - maximumStrain = Math.Max(hitObject.Strains[(int)type], maximumStrain); - - previousHitObject = hitObject; - } - - // Build the weighted sum over the highest strains for each interval - double difficulty = 0; - double weight = 1; - highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain. - - foreach (double strain in highestStrains) - { - difficulty += weight * strain; - weight *= DECAY_WEIGHT; - } - - return difficulty; - } - - protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); - - // Those values are used as array indices. Be careful when changing them! - public enum DifficultyType - { - Speed = 0, - Aim, - }; - } -} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index bfed889b36..63fe6aaa59 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -7,6 +7,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.OsuDifficulty; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index b91bdc6a78..7219cf8769 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -68,9 +68,14 @@ - - + + + + + + + From f9441a7419b5312bc7b2c855028ae37ecbda28e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Tue, 6 Jun 2017 00:07:00 +0200 Subject: [PATCH 25/45] Fix typo and whitespace. --- .../OsuDifficulty/OsuDifficultyCalculator.cs | 2 +- .../OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs | 4 ++-- osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs | 2 +- osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs index ee26109dd7..5da3613e8d 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty protected override double CalculateInternal(Dictionary categoryDifficulty) { - OsuDifficulyBeatmap beatmap = new OsuDifficulyBeatmap(Objects); + OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Objects); Skill[] skills = new Skill[2] { new Aim(), diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index 35a84a3018..a831320f4b 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -7,12 +7,12 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing { - public class OsuDifficulyBeatmap : IEnumerable + public class OsuDifficultyBeatmap : IEnumerable { IEnumerator difficultyObjects; private Queue onScreen = new Queue(); - public OsuDifficulyBeatmap(List objects) + public OsuDifficultyBeatmap(List objects) { // Sort HitObjects by StartTime - they are not correctly ordered in some cases. // This should probably happen before the objects reach the difficulty calculator. diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs index 2880098627..274e50ab2d 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -12,4 +12,4 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills protected override double strainValue() => Math.Pow(current.Distance, 0.99) / current.MS; } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs index 3ac23ccd34..2146ffc4e6 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills currentStrain += strainValue() * skillMultiplier; currentSectionPeak = Math.Max(currentStrain, currentSectionPeak); - + previous.Push(current); } From afb4443763fa445212b1dc83c6ad1c143651851d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Tue, 6 Jun 2017 01:08:34 +0200 Subject: [PATCH 26/45] Capitalised protected members, added readonly modifiers. --- .../OsuDifficulty/OsuDifficultyCalculator.cs | 2 +- .../Preprocessing/OsuDifficultyBeatmap.cs | 10 +++---- .../Preprocessing/OsuDifficultyHitObject.cs | 10 +++---- .../OsuDifficulty/Skills/Aim.cs | 6 ++-- .../OsuDifficulty/Skills/Skill.cs | 30 +++++++++---------- .../OsuDifficulty/Skills/Speed.cs | 10 +++---- .../OsuDifficulty/Utils/History.cs | 6 ++-- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs index 5da3613e8d..d8d48f8734 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty protected override double CalculateInternal(Dictionary categoryDifficulty) { OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Objects); - Skill[] skills = new Skill[2] + Skill[] skills = new Skill[] { new Aim(), new Speed() diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index a831320f4b..c2446409c5 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -9,8 +9,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing { public class OsuDifficultyBeatmap : IEnumerable { - IEnumerator difficultyObjects; - private Queue onScreen = new Queue(); + private readonly IEnumerator difficultyObjects; + private readonly Queue onScreen = new Queue(); public OsuDifficultyBeatmap(List objects) { @@ -40,14 +40,14 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing foreach (OsuDifficultyHitObject h in onScreen) { - h.MSUntilHit -= latest.MS; + h.MsUntilHit -= latest.Ms; // Calculate reading strain here } onScreen.Enqueue(latest); } } - while (onScreen.Peek().MSUntilHit > 0 && hasNext); // Keep adding new notes on screen while there is still time before we have to hit the next one. + while (onScreen.Peek().MsUntilHit > 0 && hasNext); // Keep adding new notes on screen while there is still time before we have to hit the next one. yield return onScreen.Dequeue(); // Remove and return notes one by one that had to be hit before the latest note appeared. } @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - IEnumerator createDifficultyObjectEnumerator(List objects) + private IEnumerator createDifficultyObjectEnumerator(List objects) { // We will process HitObjects in groups of three to form a triangle, so we can calculate an angle for each note. OsuHitObject[] triangle = new OsuHitObject[3]; diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index ca10b19fc1..4497f96c89 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -18,13 +18,13 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing /// /// Milliseconds elapsed since the StartTime of the previous note. /// - public double MS { get; private set; } + public double Ms { get; private set; } - public double MSUntilHit { get; set; } + public double MsUntilHit { get; set; } private const int normalized_radius = 52; - private OsuHitObject[] t; + private readonly OsuHitObject[] t; public OsuDifficultyHitObject(OsuHitObject[] triangle) { @@ -51,8 +51,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing private void setTimingValues() { // Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure. - MS = Math.Max(40, t[0].StartTime - t[1].StartTime); - MSUntilHit = 450; // BaseObject.PreEmpt; + Ms = Math.Max(40, t[0].StartTime - t[1].StartTime); + MsUntilHit = 450; // BaseObject.PreEmpt; } } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs index 274e50ab2d..57fcff965a 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -7,9 +7,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { public class Aim : Skill { - protected override double skillMultiplier => 26.25; - protected override double strainDecayBase => 0.15; + protected override double SkillMultiplier => 26.25; + protected override double StrainDecayBase => 0.15; - protected override double strainValue() => Math.Pow(current.Distance, 0.99) / current.MS; + protected override double StrainValue() => Math.Pow(Current.Distance, 0.99) / Current.Ms; } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs index 2146ffc4e6..c2aa55d650 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs @@ -11,30 +11,30 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { public abstract class Skill { - protected abstract double skillMultiplier { get; } - protected abstract double strainDecayBase { get; } + protected abstract double SkillMultiplier { get; } + protected abstract double StrainDecayBase { get; } - protected OsuDifficultyHitObject current; - protected History previous = new History(2); // Contained objects not used yet + protected OsuDifficultyHitObject Current; + protected History Previous = new History(2); // Contained objects not used yet private double currentStrain = 1; // We keep track of the strain level at all times throughout the beatmap. private double currentSectionPeak = 1; // We also keep track of the peak strain level in the current section. - private List strainPeaks = new List(); + private readonly List strainPeaks = new List(); /// /// Process a HitObject and update current strain values accordingly. /// public void Process(OsuDifficultyHitObject h) { - current = h; + Current = h; - currentStrain *= strainDecay(current.MS); - if (!(current.BaseObject is Spinner)) - currentStrain += strainValue() * skillMultiplier; + currentStrain *= strainDecay(Current.Ms); + if (!(Current.BaseObject is Spinner)) + currentStrain += StrainValue() * SkillMultiplier; currentSectionPeak = Math.Max(currentStrain, currentSectionPeak); - previous.Push(current); + Previous.Push(Current); } /// @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills /// public void SaveCurrentPeak() { - if (previous.Count > 0) + if (Previous.Count > 0) strainPeaks.Add(currentSectionPeak); } @@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { // The maximum strain of the new section is not zero by default, strain decays as usual regardless of section boundaries. // This means we need to capture the strain level at the beginning of the new section, and use that as the initial peak level. - if (previous.Count > 0) - currentSectionPeak = currentStrain * strainDecay(offset - previous[0].BaseObject.StartTime); + if (Previous.Count > 0) + currentSectionPeak = currentStrain * strainDecay(offset - Previous[0].BaseObject.StartTime); } /// @@ -78,8 +78,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills return difficulty; } - protected abstract double strainValue(); + protected abstract double StrainValue(); - private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000); + private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000); } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs index 42da6b8ed2..33e8fec829 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -5,16 +5,16 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { public class Speed : Skill { - protected override double skillMultiplier => 1400; - protected override double strainDecayBase => 0.3; + protected override double SkillMultiplier => 1400; + protected override double StrainDecayBase => 0.3; private const double single_spacing_threshold = 125; private const double stream_spacing_threshold = 110; private const double almost_diameter = 90; - protected override double strainValue() + protected override double StrainValue() { - double distance = current.Distance; + double distance = Current.Distance; double speedValue; if (distance > single_spacing_threshold) @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills else speedValue = 0.95; - return speedValue / current.MS; + return speedValue / Current.Ms; } } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs index 4bf20b1830..38727707d9 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -13,10 +13,10 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils /// public class History : IEnumerable { - public int Count { get; private set; } = 0; + public int Count { get; private set; } - private T[] array; - private int size; + private readonly T[] array; + private readonly int size; private int marker; // Marks the position of the most recently added item. public History(int size) From 01585027b1f869a4e1c26389c569ad4bfed74ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Tue, 6 Jun 2017 15:39:37 +0200 Subject: [PATCH 27/45] OsuDifficultyBeatmap enumeration logic made clearer, more documentation added. --- .../OsuDifficulty/OsuDifficultyCalculator.cs | 2 +- .../Preprocessing/OsuDifficultyBeatmap.cs | 43 +++++++++++-------- .../Preprocessing/OsuDifficultyHitObject.cs | 17 ++++++-- .../OsuDifficulty/Skills/Aim.cs | 2 +- .../OsuDifficulty/Skills/Skill.cs | 20 ++++++++- .../OsuDifficulty/Skills/Speed.cs | 4 +- .../OsuDifficulty/Utils/History.cs | 40 +++++++++++------ 7 files changed, 87 insertions(+), 41 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs index d8d48f8734..a164566263 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty protected override double CalculateInternal(Dictionary categoryDifficulty) { OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Objects); - Skill[] skills = new Skill[] + Skill[] skills = { new Aim(), new Speed() diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index c2446409c5..a96dd31078 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -12,6 +12,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing private readonly IEnumerator difficultyObjects; private readonly Queue onScreen = new Queue(); + /// + /// Creates an enumerable, which handles the preprocessing of HitObjects, getting them ready to be used in difficulty calculation. + /// public OsuDifficultyBeatmap(List objects) { // Sort HitObjects by StartTime - they are not correctly ordered in some cases. @@ -20,38 +23,40 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing difficultyObjects = createDifficultyObjectEnumerator(objects); } + /// + /// Returns an enumerator that enumerates all difficulty objects in the beatmap. + /// The inner loop adds notes that appear on screen into a queue until we need to hit the next note, + /// the outer loop returns notes from this queue one at a time, only after they had to be hit, and should no longer be on screen. + /// This means that we can loop through every object that is on screen at the time when a new one appears, + /// allowing us to determine a reading strain for the note that just appeared. + /// public IEnumerator GetEnumerator() { - do + while (true) { // Add upcoming notes to the queue until we have at least one note that had been hit and can be dequeued. // This means there is always at least one note in the queue unless we reached the end of the map. - bool hasNext; do { - hasNext = difficultyObjects.MoveNext(); - if (onScreen.Count == 0 && !hasNext) - yield break; // Stop if we have an empty enumerator. + if (!difficultyObjects.MoveNext()) + break; // New notes can't be added anymore, but we still need to dequeue and return the ones already on screen. - if (hasNext) + OsuDifficultyHitObject latest = difficultyObjects.Current; + // Calculate flow values here + + foreach (OsuDifficultyHitObject h in onScreen) { - OsuDifficultyHitObject latest = difficultyObjects.Current; - // Calculate flow values here - - foreach (OsuDifficultyHitObject h in onScreen) - { - h.MsUntilHit -= latest.Ms; - // Calculate reading strain here - } - - onScreen.Enqueue(latest); + h.TimeUntilHit -= latest.DeltaTime; + // Calculate reading strain here } - } - while (onScreen.Peek().MsUntilHit > 0 && hasNext); // Keep adding new notes on screen while there is still time before we have to hit the next one. + onScreen.Enqueue(latest); + } + while (onScreen.Peek().TimeUntilHit > 0); // Keep adding new notes on screen while there is still time before we have to hit the next one. + + if (onScreen.Count == 0) break; // We have reached the end of the map and enumerated all the notes. yield return onScreen.Dequeue(); // Remove and return notes one by one that had to be hit before the latest note appeared. } - while (onScreen.Count > 0); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index 4497f96c89..a83ae6ee7e 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -8,6 +8,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing { public class OsuDifficultyHitObject { + /// + /// The current note. Attributes are calculated relative to previous ones. + /// public OsuHitObject BaseObject { get; } /// @@ -18,14 +21,20 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing /// /// Milliseconds elapsed since the StartTime of the previous note. /// - public double Ms { get; private set; } + public double DeltaTime { get; private set; } - public double MsUntilHit { get; set; } + /// + /// Number of milliseconds until the note has to be hit. + /// + public double TimeUntilHit { get; set; } private const int normalized_radius = 52; private readonly OsuHitObject[] t; + /// + /// Constructs a wrapper around a HitObject calculating additional data required for difficulty calculation. + /// public OsuDifficultyHitObject(OsuHitObject[] triangle) { t = triangle; @@ -51,8 +60,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing private void setTimingValues() { // Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure. - Ms = Math.Max(40, t[0].StartTime - t[1].StartTime); - MsUntilHit = 450; // BaseObject.PreEmpt; + DeltaTime = Math.Max(40, t[0].StartTime - t[1].StartTime); + TimeUntilHit = 450; // BaseObject.PreEmpt; } } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs index 57fcff965a..e17679161b 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; - protected override double StrainValue() => Math.Pow(Current.Distance, 0.99) / Current.Ms; + protected override double StrainValue() => Math.Pow(Current.Distance, 0.99) / Current.DeltaTime; } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs index c2aa55d650..498374df8d 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs @@ -11,10 +11,25 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { public abstract class Skill { + /// + /// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other. + /// protected abstract double SkillMultiplier { get; } + + /// + /// Determines how quickly strain decays for the given skill. + /// For example a value of 0.15 indicates that strain decays to 15% of it's original value in one second. + /// protected abstract double StrainDecayBase { get; } + /// + /// The note that will be processed. + /// protected OsuDifficultyHitObject Current; + + /// + /// Notes that were processed previously. They can affect the strain value of the current note. + /// protected History Previous = new History(2); // Contained objects not used yet private double currentStrain = 1; // We keep track of the strain level at all times throughout the beatmap. @@ -28,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { Current = h; - currentStrain *= strainDecay(Current.Ms); + currentStrain *= strainDecay(Current.DeltaTime); if (!(Current.BaseObject is Spinner)) currentStrain += StrainValue() * SkillMultiplier; @@ -78,6 +93,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills return difficulty; } + /// + /// Calculates the strain value of the current note. This value is affected by previous notes. + /// protected abstract double StrainValue(); private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000); diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs index 33e8fec829..934df4dd8a 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills else speedValue = 0.95; - return speedValue / Current.Ms; + return speedValue / Current.DeltaTime; } } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs index 38727707d9..f1f7b189be 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -8,7 +8,7 @@ using System.Collections.Generic; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils { /// - /// An indexed stack with Push() only, which disposes items at the bottom once the size limit has been reached. + /// An indexed stack with Push() only, which disposes items at the bottom after the capacity is full. /// Indexing starts at the top of the stack. /// public class History : IEnumerable @@ -16,17 +16,28 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils public int Count { get; private set; } private readonly T[] array; - private readonly int size; + private readonly int capacity; private int marker; // Marks the position of the most recently added item. - public History(int size) + // + /// + /// Initializes a new instance of the History class that is empty and has the specified capacity. + /// + /// The number of items the History can hold. + public History(int capacity) { - this.size = size; - array = new T[size]; - marker = size; // Set marker to the end of the array, outside of the indexed range by one. + if (capacity < 0) + throw new ArgumentOutOfRangeException(); + + this.capacity = capacity; + array = new T[capacity]; + marker = capacity; // Set marker to the end of the array, outside of the indexed range by one. } - public T this[int i] // Index 0 returns the most recently added item. + /// + /// The most recently added item is returned at index 0. + /// + public T this[int i] { get { @@ -34,8 +45,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils throw new IndexOutOfRangeException(); i += marker; - if (i > size - 1) - i -= size; + if (i > capacity - 1) + i -= capacity; return array[i]; } @@ -48,22 +59,25 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils public void Push(T item) // Overwrite the oldest item instead of shifting every item by one with every addition. { if (marker == 0) - marker = size - 1; + marker = capacity - 1; else --marker; array[marker] = item; - if (Count < size) + if (Count < capacity) ++Count; } + /// + /// Returns an enumerator which enumerates items in the history starting from the most recently added item. + /// public IEnumerator GetEnumerator() { - for (int i = marker; i < size; ++i) + for (int i = marker; i < capacity; ++i) yield return array[i]; - if (Count == size) + if (Count == capacity) for (int i = 0; i < marker; ++i) yield return array[i]; } From ce0d70d6513adc79cc9f77ecbf32adfc7c613539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Tue, 6 Jun 2017 15:52:33 +0200 Subject: [PATCH 28/45] Whitespace fix. --- osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs index f1f7b189be..21b58cd69d 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -19,7 +19,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils private readonly int capacity; private int marker; // Marks the position of the most recently added item. - // /// /// Initializes a new instance of the History class that is empty and has the specified capacity. /// From 93f654a5397c4721fb519cfad6a3e547b859aae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Tue, 6 Jun 2017 18:59:46 +0200 Subject: [PATCH 29/45] More docs, better docs. --- .../Preprocessing/OsuDifficultyBeatmap.cs | 39 +++++++++++-------- .../Preprocessing/OsuDifficultyHitObject.cs | 13 ++++--- .../OsuDifficulty/Skills/Aim.cs | 3 +- .../OsuDifficulty/Skills/Skill.cs | 35 ++++++++--------- .../OsuDifficulty/Skills/Speed.cs | 8 ++-- .../OsuDifficulty/Utils/History.cs | 6 +-- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index a96dd31078..72ba421344 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -7,39 +7,44 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing { + /// + /// An enumerable container wrapping input as + /// which contains extra data required for difficulty calculation. + /// public class OsuDifficultyBeatmap : IEnumerable { private readonly IEnumerator difficultyObjects; private readonly Queue onScreen = new Queue(); /// - /// Creates an enumerable, which handles the preprocessing of HitObjects, getting them ready to be used in difficulty calculation. + /// Creates an enumerator, which preprocesses a list of s recieved as input, wrapping them as + /// which contains extra data required for difficulty calculation. /// public OsuDifficultyBeatmap(List objects) { - // Sort HitObjects by StartTime - they are not correctly ordered in some cases. + // Sort OsuHitObjects by StartTime - they are not correctly ordered in some cases. // This should probably happen before the objects reach the difficulty calculator. objects.Sort((a, b) => a.StartTime.CompareTo(b.StartTime)); difficultyObjects = createDifficultyObjectEnumerator(objects); } /// - /// Returns an enumerator that enumerates all difficulty objects in the beatmap. - /// The inner loop adds notes that appear on screen into a queue until we need to hit the next note, - /// the outer loop returns notes from this queue one at a time, only after they had to be hit, and should no longer be on screen. + /// Returns an enumerator that enumerates all s in the . + /// The inner loop adds objects that appear on screen into a queue until we need to hit the next object. + /// The outer loop returns objects from this queue one at a time, only after they had to be hit, and should no longer be on screen. /// This means that we can loop through every object that is on screen at the time when a new one appears, - /// allowing us to determine a reading strain for the note that just appeared. + /// allowing us to determine a reading strain for the object that just appeared. /// public IEnumerator GetEnumerator() { while (true) { - // Add upcoming notes to the queue until we have at least one note that had been hit and can be dequeued. - // This means there is always at least one note in the queue unless we reached the end of the map. + // Add upcoming objects to the queue until we have at least one object that had been hit and can be dequeued. + // This means there is always at least one object in the queue unless we reached the end of the map. do { if (!difficultyObjects.MoveNext()) - break; // New notes can't be added anymore, but we still need to dequeue and return the ones already on screen. + break; // New objects can't be added anymore, but we still need to dequeue and return the ones already on screen. OsuDifficultyHitObject latest = difficultyObjects.Current; // Calculate flow values here @@ -52,10 +57,10 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing onScreen.Enqueue(latest); } - while (onScreen.Peek().TimeUntilHit > 0); // Keep adding new notes on screen while there is still time before we have to hit the next one. + while (onScreen.Peek().TimeUntilHit > 0); // Keep adding new objects on screen while there is still time before we have to hit the next one. - if (onScreen.Count == 0) break; // We have reached the end of the map and enumerated all the notes. - yield return onScreen.Dequeue(); // Remove and return notes one by one that had to be hit before the latest note appeared. + if (onScreen.Count == 0) break; // We have reached the end of the map and enumerated all the objects. + yield return onScreen.Dequeue(); // Remove and return objects one by one that had to be hit before the latest one appeared. } } @@ -63,18 +68,18 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing private IEnumerator createDifficultyObjectEnumerator(List objects) { - // We will process HitObjects in groups of three to form a triangle, so we can calculate an angle for each note. + // We will process OsuHitObjects in groups of three to form a triangle, so we can calculate an angle for each object. OsuHitObject[] triangle = new OsuHitObject[3]; - // Difficulty object construction requires three components, an extra copy of the first object is used at the beginning. + // OsuDifficultyHitObject construction requires three components, an extra copy of the first OsuHitObject is used at the beginning. if (objects.Count > 1) { triangle[1] = objects[0]; // This copy will get shifted to the last spot in the triangle. - triangle[0] = objects[0]; // This is the real first note. + triangle[0] = objects[0]; // This component corresponds to the real first OsuHitOject. } - // The final component of the first triangle will be the second note, which forms the first jump. - // If the beatmap has less than two HitObjects, the enumerator will not return anything. + // The final component of the first triangle will be the second OsuHitOject of the map, which forms the first jump. + // If the map has less than two OsuHitObjects, the enumerator will not return anything. for (int i = 1; i < objects.Count; ++i) { triangle[2] = triangle[1]; diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index a83ae6ee7e..69399fb02f 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -6,25 +6,28 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing { + /// + /// A wrapper around extending it with additional data required for difficulty calculation. + /// public class OsuDifficultyHitObject { /// - /// The current note. Attributes are calculated relative to previous ones. + /// The this refers to. /// public OsuHitObject BaseObject { get; } /// - /// Normalized distance from the StartPosition of the previous note. + /// Normalized distance from the of the previous . /// public double Distance { get; private set; } /// - /// Milliseconds elapsed since the StartTime of the previous note. + /// Milliseconds elapsed since the StartTime of the previous . /// public double DeltaTime { get; private set; } /// - /// Number of milliseconds until the note has to be hit. + /// Number of milliseconds until the has to be hit. /// public double TimeUntilHit { get; set; } @@ -33,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing private readonly OsuHitObject[] t; /// - /// Constructs a wrapper around a HitObject calculating additional data required for difficulty calculation. + /// Initializes the object calculating extra data required for difficulty calculation. /// public OsuDifficultyHitObject(OsuHitObject[] triangle) { diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs index e17679161b..99d0e761ad 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { @@ -10,6 +11,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; - protected override double StrainValue() => Math.Pow(Current.Distance, 0.99) / Current.DeltaTime; + protected override double StrainValueOf(OsuDifficultyHitObject current) => Math.Pow(current.Distance, 0.99) / current.DeltaTime; } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs index 498374df8d..b9632e18e2 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs @@ -9,6 +9,10 @@ using osu.Game.Rulesets.Osu.OsuDifficulty.Utils; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { + /// + /// Used to processes strain values of s, keep track of strain levels caused by the processed objects + /// and to calculate a final difficulty value representing the difficulty of hitting all the processed objects. + /// public abstract class Skill { /// @@ -18,38 +22,31 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills /// /// Determines how quickly strain decays for the given skill. - /// For example a value of 0.15 indicates that strain decays to 15% of it's original value in one second. + /// For example a value of 0.15 indicates that strain decays to 15% of its original value in one second. /// protected abstract double StrainDecayBase { get; } /// - /// The note that will be processed. + /// s that were processed previously. They can affect the strain values of the following objects. /// - protected OsuDifficultyHitObject Current; - - /// - /// Notes that were processed previously. They can affect the strain value of the current note. - /// - protected History Previous = new History(2); // Contained objects not used yet + protected readonly History Previous = new History(2); // Contained objects not used yet private double currentStrain = 1; // We keep track of the strain level at all times throughout the beatmap. private double currentSectionPeak = 1; // We also keep track of the peak strain level in the current section. private readonly List strainPeaks = new List(); /// - /// Process a HitObject and update current strain values accordingly. + /// Process an and update current strain values accordingly. /// - public void Process(OsuDifficultyHitObject h) + public void Process(OsuDifficultyHitObject current) { - Current = h; - - currentStrain *= strainDecay(Current.DeltaTime); - if (!(Current.BaseObject is Spinner)) - currentStrain += StrainValue() * SkillMultiplier; + currentStrain *= strainDecay(current.DeltaTime); + if (!(current.BaseObject is Spinner)) + currentStrain += StrainValueOf(current) * SkillMultiplier; currentSectionPeak = Math.Max(currentStrain, currentSectionPeak); - Previous.Push(Current); + Previous.Push(current); } /// @@ -74,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills } /// - /// Returns the calculated difficulty value representing all currently processed HitObjects. + /// Returns the calculated difficulty value representing all processed s. /// public double DifficultyValue() { @@ -94,9 +91,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills } /// - /// Calculates the strain value of the current note. This value is affected by previous notes. + /// Calculates the strain value of an . This value is affected by previously processed objects. /// - protected abstract double StrainValue(); + protected abstract double StrainValueOf(OsuDifficultyHitObject current); private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000); } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs index 934df4dd8a..826d62adcc 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; + namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { public class Speed : Skill @@ -12,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills private const double stream_spacing_threshold = 110; private const double almost_diameter = 90; - protected override double StrainValue() + protected override double StrainValueOf(OsuDifficultyHitObject current) { - double distance = Current.Distance; + double distance = current.Distance; double speedValue; if (distance > single_spacing_threshold) @@ -28,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills else speedValue = 0.95; - return speedValue / Current.DeltaTime; + return speedValue / current.DeltaTime; } } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs index 21b58cd69d..92b206ccf8 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -52,8 +52,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils } /// - /// Adds the element as the most recent one in the history. - /// The oldest element is disposed if the history is full. + /// Adds the item as the most recent one in the history. + /// The oldest item is disposed if the history is full. /// public void Push(T item) // Overwrite the oldest item instead of shifting every item by one with every addition. { @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils } /// - /// Returns an enumerator which enumerates items in the history starting from the most recently added item. + /// Returns an enumerator which enumerates items in the history starting from the most recently added one. /// public IEnumerator GetEnumerator() { From 1f311cca0659da77843c7142d7b2f4fe5216a78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Tue, 6 Jun 2017 19:09:26 +0200 Subject: [PATCH 30/45] Fix cref in comment. --- .../OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index 69399fb02f..bdeb62df3e 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing public double DeltaTime { get; private set; } /// - /// Number of milliseconds until the has to be hit. + /// Number of milliseconds until the has to be hit. /// public double TimeUntilHit { get; set; } From 6a12173175ffc00ae67059aa54e286180fd36055 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 20:05:43 +0900 Subject: [PATCH 31/45] Add very temporary data source for social browser --- .../Online/API/Requests/GetUsersRequest.cs | 24 +++++++++ osu.Game/Overlays/SocialOverlay.cs | 51 ++++++++++++++++--- osu.Game/osu.Game.csproj | 1 + 3 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetUsersRequest.cs diff --git a/osu.Game/Online/API/Requests/GetUsersRequest.cs b/osu.Game/Online/API/Requests/GetUsersRequest.cs new file mode 100644 index 0000000000..96d0bccb2d --- /dev/null +++ b/osu.Game/Online/API/Requests/GetUsersRequest.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests +{ + public class GetUsersRequest : APIRequest> + { + public GetUsersRequest() + { + } + + protected override string Target => $@"rankings/osu/performance"; + } + + public class RankingEntry + { + [JsonProperty] + public User User; + } +} diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 448539607d..b0602a3c67 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -3,18 +3,21 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; namespace osu.Game.Overlays { - public class SocialOverlay : SearchableListOverlay + public class SocialOverlay : SearchableListOverlay, IOnlineComponent { private readonly FillFlowContainer panelFlow; @@ -34,12 +37,17 @@ namespace osu.Game.Overlays if (users?.Equals(value) ?? false) return; users = value; - panelFlow.Children = users.Select(u => + if (users == null) + panelFlow.Clear(); + else { - var p = new UserPanel(u) { Width = 300 }; - p.Status.BindTo(u.Status); - return p; - }); + panelFlow.Children = users.Select(u => + { + var p = new UserPanel(u) { Width = 300 }; + p.Status.BindTo(u.Status); + return p; + }); + } } } @@ -61,11 +69,40 @@ namespace osu.Game.Overlays }, }; } + + [BackgroundDependencyLoader] + private void load(APIAccess api) + { + reloadUsers(api); + } + + private void reloadUsers(APIAccess api) + { + Users = null; + + // no this is not the correct data source, but it's something. + var request = new GetUsersRequest(); + request.Success += res => Users = res.Select(e => e.User); + api.Queue(request); + } + + public void APIStateChanged(APIAccess api, APIState state) + { + switch (state) + { + case APIState.Online: + reloadUsers(api); + break; + default: + Users = null; + break; + } + } } public enum SortDirection { - Ascending, Descending, + Ascending, } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 20aa765502..f7412ade5b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -76,6 +76,7 @@ + From fc2d9816dfe6311810181be8e7809c518d2443de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 20:06:02 +0900 Subject: [PATCH 32/45] Make SearchableListHeader icon customisable --- osu.Game/Overlays/Direct/Header.cs | 1 + .../SearchableList/SearchableListHeader.cs | 5 +++-- osu.Game/Overlays/Social/FilterControl.cs | 14 ++++++-------- osu.Game/Overlays/Social/Header.cs | 13 +++++++------ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Direct/Header.cs b/osu.Game/Overlays/Direct/Header.cs index e5b7c7f149..000ef473cc 100644 --- a/osu.Game/Overlays/Direct/Header.cs +++ b/osu.Game/Overlays/Direct/Header.cs @@ -17,6 +17,7 @@ namespace osu.Game.Overlays.Direct protected override DirectTab DefaultTab => DirectTab.Search; protected override Drawable CreateHeaderText() => new OsuSpriteText { Text = @"osu!direct", TextSize = 25 }; + protected override FontAwesome Icon => FontAwesome.fa_osu_chevron_down_o; public Header() { diff --git a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs index b65e031488..26dc9b03c8 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs @@ -22,6 +22,7 @@ namespace osu.Game.Overlays.SearchableList protected abstract float TabStripWidth { get; } //can be removed once (if?) TabControl support auto sizing protected abstract T DefaultTab { get; } protected abstract Drawable CreateHeaderText(); + protected abstract FontAwesome Icon { get; } protected SearchableListHeader() { @@ -41,7 +42,7 @@ namespace osu.Game.Overlays.SearchableList new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING, Right = SearchableListOverlay.WIDTH_PADDING },  + Padding = new MarginPadding { Left = SearchableListOverlay.WIDTH_PADDING, Right = SearchableListOverlay.WIDTH_PADDING }, Children = new Drawable[] { new FillFlowContainer @@ -57,7 +58,7 @@ namespace osu.Game.Overlays.SearchableList new TextAwesome { TextSize = 25, - Icon = FontAwesome.fa_osu_chevron_down_o, + Icon = Icon, }, CreateHeaderText(), }, diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 789c7b6a64..cf4097643e 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.ComponentModel; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Game.Graphics; @@ -12,7 +11,7 @@ namespace osu.Game.Overlays.Social public class FilterControl : SearchableListFilterControl { protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a"); - protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Name; + protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Rank; public FilterControl() { @@ -22,12 +21,11 @@ namespace osu.Game.Overlays.Social public enum SocialSortCriteria { - Name, Rank, - Location, - [Description("Time Zone")] - TimeZone, - [Description("World Map")] - WorldMap, + //Location, + //[Description("Time Zone")] + //TimeZone, + //[Description("World Map")] + //WorldMap, } } diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index bad0e73327..2674854327 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -19,6 +19,7 @@ namespace osu.Game.Overlays.Social protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e"); protected override float TabStripWidth => 438; protected override SocialTab DefaultTab => SocialTab.OnlinePlayers; + protected override FontAwesome Icon => FontAwesome.fa_users; protected override Drawable CreateHeaderText() { @@ -54,11 +55,11 @@ namespace osu.Game.Overlays.Social { [Description("Online Players")] OnlinePlayers, - [Description("Online Friends")] - OnlineFriends, - [Description("Online Team Members")] - OnlineTeamMembers, - [Description("Chat Channels")] - ChatChannels, + //[Description("Online Friends")] + //OnlineFriends, + //[Description("Online Team Members")] + //OnlineTeamMembers, + //[Description("Chat Channels")] + //ChatChannels, } } From 97db4856fca37cb60fedfa41fc53ca54274b21bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 20:15:58 +0900 Subject: [PATCH 33/45] Add toolbar toggle button Also ensure chat is hidden when social is displayed and vice-versa. --- osu.Game/OsuGame.cs | 5 +++++ osu.Game/Overlays/Toolbar/Toolbar.cs | 1 + .../Overlays/Toolbar/ToolbarSocialButton.cs | 22 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 29 insertions(+) create mode 100644 osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ea22d9e97d..ed244a7b48 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -201,11 +201,16 @@ namespace osu.Game }; Dependencies.Cache(settings); + Dependencies.Cache(social); Dependencies.Cache(chat); Dependencies.Cache(musicController); Dependencies.Cache(notificationManager); Dependencies.Cache(dialogOverlay); + // ensure both overlays aren't presented at the same time + chat.StateChanged += (container, state) => social.State = state == Visibility.Visible ? Visibility.Hidden : social.State; + social.StateChanged += (container, state) => chat.State = state == Visibility.Visible ? Visibility.Hidden : chat.State; + LoadComponentAsync(Toolbar = new Toolbar { Depth = -3, diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 43c3cd32f2..158992fef8 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -63,6 +63,7 @@ namespace osu.Game.Overlays.Toolbar AutoSizeAxes = Axes.X, Children = new Drawable[] { + new ToolbarSocialButton(), new ToolbarChatButton(), new ToolbarMusicButton(), new ToolbarButton diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs new file mode 100644 index 0000000000..ed36fd8f9e --- /dev/null +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.Toolbar +{ + internal class ToolbarSocialButton : ToolbarOverlayToggleButton + { + public ToolbarSocialButton() + { + Icon = FontAwesome.fa_users; + } + + [BackgroundDependencyLoader] + private void load(SocialOverlay chat) + { + StateContainer = chat; + } + } +} \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f7412ade5b..1ebbb4adf3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -89,6 +89,7 @@ + From 94c961ddb8db98551000d5252418055e9ac81c23 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 20:16:34 +0900 Subject: [PATCH 34/45] CI Fixes --- osu.Game/Online/API/Requests/GetUsersRequest.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUsersRequest.cs b/osu.Game/Online/API/Requests/GetUsersRequest.cs index 96d0bccb2d..5fb8606e1e 100644 --- a/osu.Game/Online/API/Requests/GetUsersRequest.cs +++ b/osu.Game/Online/API/Requests/GetUsersRequest.cs @@ -9,11 +9,7 @@ namespace osu.Game.Online.API.Requests { public class GetUsersRequest : APIRequest> { - public GetUsersRequest() - { - } - - protected override string Target => $@"rankings/osu/performance"; + protected override string Target => @"rankings/osu/performance"; } public class RankingEntry From 8d434e88ee82ea6446a2fa5eabc9607e395d5899 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 20:20:22 +0900 Subject: [PATCH 35/45] Fix VisualTest not using placeholder data --- osu.Game/Overlays/SocialOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index b0602a3c67..97c27a9ea9 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -73,7 +73,8 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(APIAccess api) { - reloadUsers(api); + if (Users == null) + reloadUsers(api); } private void reloadUsers(APIAccess api) From 59bed2b16ee6f963dd8c8b4684cbabcf704836d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 20:44:54 +0900 Subject: [PATCH 36/45] Add missing spaces --- .../Overlays/SearchableList/SearchableListFilterControl.cs | 2 +- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs index 95651833d3..dfc2dbe49a 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListFilterControl.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.SearchableList { - public abstract class SearchableListFilterControl : Container + public abstract class SearchableListFilterControl : Container { private const float padding = 10; diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 7705fa0582..5b24da1dbe 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -15,19 +15,19 @@ namespace osu.Game.Overlays.SearchableList public static readonly float WIDTH_PADDING = 80; } - public abstract class SearchableListOverlay : SearchableListOverlay + public abstract class SearchableListOverlay : SearchableListOverlay { private readonly Container scrollContainer; protected readonly SearchableListHeader Header; - protected readonly SearchableListFilterControl Filter; + protected readonly SearchableListFilterControl Filter; protected readonly FillFlowContainer ScrollFlow; protected abstract Color4 BackgroundColour { get; } protected abstract Color4 TrianglesColourLight { get; } protected abstract Color4 TrianglesColourDark { get; } protected abstract SearchableListHeader CreateHeader(); - protected abstract SearchableListFilterControl CreateFilterControl(); + protected abstract SearchableListFilterControl CreateFilterControl(); protected SearchableListOverlay() { From 9b0e1c26a3996d0c4abb823c9410445ff27904a2 Mon Sep 17 00:00:00 2001 From: John Neijzen Date: Wed, 7 Jun 2017 19:53:37 +0800 Subject: [PATCH 37/45] Clean Up Code --- .../Legacy/DistanceObjectPatternGenerator.cs | 2 -- osu.Game/Graphics/Cursor/CursorTrail.cs | 4 ++-- osu.Game/OsuGame.cs | 2 +- osu.Game/Screens/Menu/Button.cs | 19 +++++++++++-------- osu.Game/Screens/Menu/OsuLogo.cs | 14 ++++---------- osu.Game/Screens/Play/Player.cs | 1 - osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- osu.Game/Screens/Select/BeatmapDetails.cs | 14 +++++++++----- .../Tournament/ScrollingTeamContainer.cs | 14 +++++++++++--- 9 files changed, 39 insertions(+), 33 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 2d1f75e196..7e9615a703 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -448,7 +448,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy return curveData.RepeatSamples[index]; } - /// /// Constructs and adds a note to a pattern. /// @@ -480,7 +479,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy Tail = { Samples = sampleInfoListAt(endTime) } }; - newObject = holdNote; } diff --git a/osu.Game/Graphics/Cursor/CursorTrail.cs b/osu.Game/Graphics/Cursor/CursorTrail.cs index 11475a0f19..754390047f 100644 --- a/osu.Game/Graphics/Cursor/CursorTrail.cs +++ b/osu.Game/Graphics/Cursor/CursorTrail.cs @@ -136,7 +136,7 @@ namespace osu.Game.Graphics.Cursor for (float d = interval; d < distance; d += interval) { - lastPosition = pos1 + direction * d; + lastPosition = pos1 + (direction * d); addPosition(lastPosition.Value); } } @@ -213,7 +213,7 @@ namespace osu.Game.Graphics.Cursor colour.BottomRight.Linear.A = Parts[i].Time + colour.BottomRight.Linear.A; Texture.DrawQuad( - new Quad(pos.X - Size.X / 2, pos.Y - Size.Y / 2, Size.X, Size.Y), + new Quad(pos.X - (Size.X / 2), pos.Y - (Size.Y / 2), Size.X, Size.Y), colour, null, v => Shared.VertexBuffer.Vertices[end++] = v); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2c952ee514..a8bee97eb4 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -148,7 +148,7 @@ namespace osu.Game RelativeSizeAxes = Axes.Both, }, volume = new VolumeControl(), - overlayContent = new Container{ RelativeSizeAxes = Axes.Both }, + overlayContent = new Container { RelativeSizeAxes = Axes.Both }, new OnScreenDisplay(), new GlobalHotkeys //exists because UserInputManager is at a level below us. { diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index fe9f7b4bf6..b874d8bfed 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Menu Scale = new Vector2(0, 1), Size = boxSize, Shear = new Vector2(ButtonSystem.WEDGE_WIDTH / boxSize.Y, 0), - Children = new [] + Children = new[] { new Box { @@ -143,7 +143,7 @@ namespace osu.Game.Screens.Menu StartValue = -10, EndValue = 10, StartTime = startTime, - EndTime = startTime + duration * 2, + EndTime = startTime + (duration * 2), Easing = EasingTypes.InOutSine, LoopCount = -1, LoopDelay = duration * 2 @@ -176,7 +176,7 @@ namespace osu.Game.Screens.Menu StartValue = new Vector2(0, -10), EndValue = Vector2.Zero, StartTime = startTime + duration, - EndTime = startTime + duration * 2, + EndTime = startTime + (duration * 2), Easing = EasingTypes.In, LoopCount = -1, LoopDelay = duration @@ -187,7 +187,7 @@ namespace osu.Game.Screens.Menu StartValue = Vector2.One, EndValue = new Vector2(1, 0.9f), StartTime = startTime + duration, - EndTime = startTime + duration * 2, + EndTime = startTime + (duration * 2), Easing = EasingTypes.In, LoopCount = -1, LoopDelay = duration @@ -197,8 +197,8 @@ namespace osu.Game.Screens.Menu { StartValue = 10, EndValue = -10, - StartTime = startTime + duration * 2, - EndTime = startTime + duration * 4, + StartTime = startTime + (duration * 2), + EndTime = startTime + (duration * 4), Easing = EasingTypes.InOutSine, LoopCount = -1, LoopDelay = duration * 2 @@ -282,10 +282,13 @@ namespace osu.Game.Screens.Menu public ButtonState State { - get { return state; } + get + { + return state; + } + set { - if (state == value) return; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 44b7b6bceb..4ae6f70d6c 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -51,10 +51,7 @@ namespace osu.Game.Screens.Menu public bool Triangles { - set - { - colourAndTriangles.Alpha = value ? 1 : 0; - } + set { colourAndTriangles.Alpha = value ? 1 : 0; } } protected override bool InternalContains(Vector2 screenSpacePos) => logoContainer.Contains(screenSpacePos); @@ -62,10 +59,7 @@ namespace osu.Game.Screens.Menu public bool Ripple { get { return rippleContainer.Alpha > 0; } - set - { - rippleContainer.Alpha = value ? 1 : 0; - } + set { rippleContainer.Alpha = value ? 1 : 0; } } public bool Interactive = true; @@ -237,7 +231,7 @@ namespace osu.Game.Screens.Menu if (beatIndex < 0) return; - logoBeatContainer.ScaleTo(1 - 0.02f * amplitudeAdjust, beat_in_time, EasingTypes.Out); + logoBeatContainer.ScaleTo(1 - (0.02f * amplitudeAdjust), beat_in_time, EasingTypes.Out); using (logoBeatContainer.BeginDelayedSequence(beat_in_time)) logoBeatContainer.ScaleTo(1, beatLength * 2, EasingTypes.OutQuint); @@ -246,7 +240,7 @@ namespace osu.Game.Screens.Menu ripple.ScaleTo(logoAmplitudeContainer.Scale); ripple.Alpha = 0.15f * amplitudeAdjust; - ripple.ScaleTo(logoAmplitudeContainer.Scale * (1 + 0.04f * amplitudeAdjust), beatLength, EasingTypes.OutQuint); + ripple.ScaleTo(logoAmplitudeContainer.Scale * (1 + (0.04f * amplitudeAdjust)), beatLength, EasingTypes.OutQuint); ripple.FadeOut(beatLength, EasingTypes.OutQuint); if (effectPoint.KiaiMode && flashLayer.Alpha < 0.4f) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d4b8445ed9..c38ea65f90 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -278,7 +278,6 @@ namespace osu.Game.Screens.Play { if (!pauseContainer.IsPaused) decoupledClock.Start(); - }); pauseContainer.Alpha = 0; diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 26820fc388..3f8d6af320 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -244,7 +244,7 @@ namespace osu.Game.Screens.Select private BeatmapGroup createGroup(BeatmapSetInfo beatmapSet) { - foreach(var b in beatmapSet.Beatmaps) + foreach (var b in beatmapSet.Beatmaps) { if (b.Metadata == null) b.Metadata = beatmapSet.Metadata; diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index abe54375cc..81db49b658 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -46,7 +46,11 @@ namespace osu.Game.Screens.Select public BeatmapInfo Beatmap { - get { return beatmap; } + get + { + return beatmap; + } + set { if (beatmap == value) return; @@ -165,7 +169,7 @@ namespace osu.Game.Screens.Select Direction = FillDirection.Vertical, LayoutDuration = 200, LayoutEasing = EasingTypes.OutQuint, - Children = new [] + Children = new[] { description = new MetadataSegment("Description"), source = new MetadataSegment("Source"), @@ -199,9 +203,9 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Spacing = new Vector2(0,5), + Spacing = new Vector2(0, 5), Padding = new MarginPadding(10), - Children = new [] + Children = new[] { circleSize = new DifficultyRow("Circle Size", 7), drainRate = new DifficultyRow("HP Drain"), @@ -479,7 +483,7 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Spacing = new Vector2(5,0), + Spacing = new Vector2(5, 0), Margin = new MarginPadding { Top = header.TextSize } } }; diff --git a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs index 3eea239f55..d3d2a18cfa 100644 --- a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs +++ b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs @@ -82,7 +82,11 @@ namespace osu.Game.Screens.Tournament private ScrollState _scrollState; private ScrollState scrollState { - get { return _scrollState; } + get + { + return _scrollState; + } + set { if (_scrollState == value) @@ -261,7 +265,7 @@ namespace osu.Game.Screens.Tournament else { c.MoveToX(pos, 100); - c.FadeTo(1.0f - Math.Abs(pos - DrawWidth / 2f) / (DrawWidth / 2.5f), 100); + c.FadeTo(1.0f - (Math.Abs(pos - (DrawWidth / 2f)) / (DrawWidth / 2.5f)), 100); } pos += ScrollingTeam.WIDTH; @@ -328,7 +332,11 @@ namespace osu.Game.Screens.Tournament private bool selected; public bool Selected { - get { return selected; } + get + { + return selected; + } + set { selected = value; From 23a7045eeff82b7b39a575a115d272f22d917acb Mon Sep 17 00:00:00 2001 From: John Neijzen Date: Wed, 7 Jun 2017 20:07:18 +0800 Subject: [PATCH 38/45] More Clean UP --- osu.Game/Configuration/OsuConfigManager.cs | 7 ------- osu.Game/Overlays/ChatOverlay.cs | 5 ++--- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 +++++----- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3f56dc0b79..6b07d5c967 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -13,7 +13,6 @@ namespace osu.Game.Configuration protected override void InitialiseDefaults() { // UI/selection defaults - Set(OsuSetting.Ruleset, 0, 0, int.MaxValue); Set(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Details); @@ -25,7 +24,6 @@ namespace osu.Game.Configuration Set(OsuSetting.ChatDisplayHeight, ChatOverlay.DEFAULT_HEIGHT, 0.2, 1); // Online settings - Set(OsuSetting.Username, string.Empty); Set(OsuSetting.Token, string.Empty); @@ -40,14 +38,12 @@ namespace osu.Game.Configuration }; // Audio - Set(OsuSetting.MenuVoice, true); Set(OsuSetting.MenuMusic, true); Set(OsuSetting.AudioOffset, 0, -500.0, 500.0); // Input - Set(OsuSetting.MenuCursorSize, 1.0, 0.5f, 2); Set(OsuSetting.GameplayCursorSize, 1.0, 0.5f, 2); Set(OsuSetting.AutoCursorSize, false); @@ -56,7 +52,6 @@ namespace osu.Game.Configuration Set(OsuSetting.MouseDisableWheel, false); // Graphics - Set(OsuSetting.ShowFpsDisplay, false); Set(OsuSetting.MenuParallax, true); @@ -65,7 +60,6 @@ namespace osu.Game.Configuration Set(OsuSetting.SnakingOutSliders, true); // Gameplay - Set(OsuSetting.DimLevel, 0.3, 0, 1); Set(OsuSetting.ShowInterface, true); @@ -75,7 +69,6 @@ namespace osu.Game.Configuration Set(OsuSetting.PlaybackSpeed, 1.0, 0.5f, 2); // Update - Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index c32199f881..5ec7331578 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -122,7 +122,7 @@ namespace osu.Game.Overlays { Top = padding * 2, Bottom = padding * 2, - Left = ChatLine.LEFT_PADDING + padding * 2, + Left = ChatLine.LEFT_PADDING + (padding * 2), Right = padding * 2, }, Children = new Drawable[] @@ -202,7 +202,7 @@ namespace osu.Game.Overlays { Trace.Assert(state.Mouse.PositionMouseDown != null); - chatHeight.Value = startDragChatHeight - (state.Mouse.Position.Y - state.Mouse.PositionMouseDown.Value.Y) / Parent.DrawSize.Y; + chatHeight.Value = startDragChatHeight - ((state.Mouse.Position.Y - state.Mouse.PositionMouseDown.Value.Y) / Parent.DrawSize.Y); return base.OnDrag(state); } @@ -367,7 +367,6 @@ namespace osu.Game.Overlays } else { - careChannels.Add(channel); channelTabs.AddItem(channel); } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 3f8d6af320..d51978a683 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -311,7 +311,7 @@ namespace osu.Game.Screens.Select foreach (BeatmapPanel panel in group.BeatmapPanels) { if (panel == selectedPanel) - selectedY = currentY + panel.DrawHeight / 2 - DrawHeight / 2; + selectedY = ((currentY + (panel.DrawHeight / 2)) - (DrawHeight / 2)); panel.MoveToX(-50, 500, EasingTypes.OutExpo); @@ -477,7 +477,7 @@ namespace osu.Game.Screens.Select { // The radius of the circle the carousel moves on. const float circle_radius = 3; - double discriminant = Math.Max(0, circle_radius * circle_radius - dist * dist); + double discriminant = Math.Max(0, (circle_radius * circle_radius) - (dist * dist)); float x = (circle_radius - (float)Math.Sqrt(discriminant)) * halfHeight; return 125 + x; @@ -493,8 +493,8 @@ namespace osu.Game.Screens.Select { var height = p.IsPresent ? p.DrawHeight : 0; - float panelDrawY = p.Position.Y - Current + height / 2; - float dist = Math.Abs(1f - panelDrawY / halfHeight); + float panelDrawY = (p.Position.Y - Current) + (height / 2); + float dist = Math.Abs(1f - (panelDrawY / halfHeight)); // Setting the origin position serves as an additive position on top of potential // local transformation we may want to apply (e.g. when a panel gets selected, we @@ -504,7 +504,7 @@ namespace osu.Game.Screens.Select // We are applying a multiplicative alpha (which is internally done by nesting an // additional container and setting that container's alpha) such that we can // layer transformations on top, with a similar reasoning to the previous comment. - p.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - 1.5f * dist, 0, 1)); + p.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - (1.5f * dist), 0, 1)); } } } From f9c466eee9c94a67231dd4ead6c80415b8ddb0c2 Mon Sep 17 00:00:00 2001 From: John Neijzen Date: Wed, 7 Jun 2017 20:12:16 +0800 Subject: [PATCH 39/45] bit more readable --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index d51978a683..c1d6d2eb9d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -311,7 +311,7 @@ namespace osu.Game.Screens.Select foreach (BeatmapPanel panel in group.BeatmapPanels) { if (panel == selectedPanel) - selectedY = ((currentY + (panel.DrawHeight / 2)) - (DrawHeight / 2)); + selectedY = currentY + (panel.DrawHeight / 2) - (DrawHeight / 2); panel.MoveToX(-50, 500, EasingTypes.OutExpo); From e51b4bc4ee8f5d180e5ae1ef1ca8525e2e62a47e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Jun 2017 21:16:41 +0900 Subject: [PATCH 40/45] Fix resources getting rolled back --- osu-resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-resources b/osu-resources index 9f46a456dc..b348c1e540 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 9f46a456dc3a56dcbff09671a3f588b16a464106 +Subproject commit b348c1e540edbb3325a8da9bca452c9dce2938d6 From 0b204bd157140c5c57f4d274667a97b6fb9d7bca Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 7 Jun 2017 10:11:10 -0300 Subject: [PATCH 41/45] Add padding to the bottom of SearchableListOverlay's ScrollFlow --- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 5b24da1dbe..093750bcc0 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays.SearchableList { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = WIDTH_PADDING }, + Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 }, Direction = FillDirection.Vertical, }, }, From aa3a231763b546bb75490e8a3898815127a56017 Mon Sep 17 00:00:00 2001 From: John Neijzen Date: Wed, 7 Jun 2017 22:00:14 +0800 Subject: [PATCH 42/45] Review Changes --- osu.Game/Graphics/Cursor/CursorTrail.cs | 4 ++-- osu.Game/Overlays/ChatOverlay.cs | 4 ++-- osu.Game/Screens/Menu/Button.cs | 15 ++++++--------- osu.Game/Screens/Menu/OsuLogo.cs | 4 ++-- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 +++++----- osu.Game/Screens/Select/BeatmapDetails.cs | 5 +---- .../Screens/Tournament/ScrollingTeamContainer.cs | 12 +++--------- 7 files changed, 21 insertions(+), 33 deletions(-) diff --git a/osu.Game/Graphics/Cursor/CursorTrail.cs b/osu.Game/Graphics/Cursor/CursorTrail.cs index 754390047f..11475a0f19 100644 --- a/osu.Game/Graphics/Cursor/CursorTrail.cs +++ b/osu.Game/Graphics/Cursor/CursorTrail.cs @@ -136,7 +136,7 @@ namespace osu.Game.Graphics.Cursor for (float d = interval; d < distance; d += interval) { - lastPosition = pos1 + (direction * d); + lastPosition = pos1 + direction * d; addPosition(lastPosition.Value); } } @@ -213,7 +213,7 @@ namespace osu.Game.Graphics.Cursor colour.BottomRight.Linear.A = Parts[i].Time + colour.BottomRight.Linear.A; Texture.DrawQuad( - new Quad(pos.X - (Size.X / 2), pos.Y - (Size.Y / 2), Size.X, Size.Y), + new Quad(pos.X - Size.X / 2, pos.Y - Size.Y / 2, Size.X, Size.Y), colour, null, v => Shared.VertexBuffer.Vertices[end++] = v); diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 5ec7331578..08b40b6079 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -122,7 +122,7 @@ namespace osu.Game.Overlays { Top = padding * 2, Bottom = padding * 2, - Left = ChatLine.LEFT_PADDING + (padding * 2), + Left = ChatLine.LEFT_PADDING + padding * 2, Right = padding * 2, }, Children = new Drawable[] @@ -202,7 +202,7 @@ namespace osu.Game.Overlays { Trace.Assert(state.Mouse.PositionMouseDown != null); - chatHeight.Value = startDragChatHeight - ((state.Mouse.Position.Y - state.Mouse.PositionMouseDown.Value.Y) / Parent.DrawSize.Y); + chatHeight.Value = startDragChatHeight - (state.Mouse.Position.Y - state.Mouse.PositionMouseDown.Value.Y) / Parent.DrawSize.Y; return base.OnDrag(state); } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index b874d8bfed..1451bf2619 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -143,7 +143,7 @@ namespace osu.Game.Screens.Menu StartValue = -10, EndValue = 10, StartTime = startTime, - EndTime = startTime + (duration * 2), + EndTime = startTime + duration * 2, Easing = EasingTypes.InOutSine, LoopCount = -1, LoopDelay = duration * 2 @@ -176,7 +176,7 @@ namespace osu.Game.Screens.Menu StartValue = new Vector2(0, -10), EndValue = Vector2.Zero, StartTime = startTime + duration, - EndTime = startTime + (duration * 2), + EndTime = startTime + duration * 2, Easing = EasingTypes.In, LoopCount = -1, LoopDelay = duration @@ -187,7 +187,7 @@ namespace osu.Game.Screens.Menu StartValue = Vector2.One, EndValue = new Vector2(1, 0.9f), StartTime = startTime + duration, - EndTime = startTime + (duration * 2), + EndTime = startTime + duration * 2, Easing = EasingTypes.In, LoopCount = -1, LoopDelay = duration @@ -197,8 +197,8 @@ namespace osu.Game.Screens.Menu { StartValue = 10, EndValue = -10, - StartTime = startTime + (duration * 2), - EndTime = startTime + (duration * 4), + StartTime = startTime + duration * 2, + EndTime = startTime + duration * 4, Easing = EasingTypes.InOutSine, LoopCount = -1, LoopDelay = duration * 2 @@ -282,10 +282,7 @@ namespace osu.Game.Screens.Menu public ButtonState State { - get - { - return state; - } + get{ return state; } set { diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 4ae6f70d6c..db1f008dcf 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -231,7 +231,7 @@ namespace osu.Game.Screens.Menu if (beatIndex < 0) return; - logoBeatContainer.ScaleTo(1 - (0.02f * amplitudeAdjust), beat_in_time, EasingTypes.Out); + logoBeatContainer.ScaleTo(1 - 0.02f * amplitudeAdjust, beat_in_time, EasingTypes.Out); using (logoBeatContainer.BeginDelayedSequence(beat_in_time)) logoBeatContainer.ScaleTo(1, beatLength * 2, EasingTypes.OutQuint); @@ -240,7 +240,7 @@ namespace osu.Game.Screens.Menu ripple.ScaleTo(logoAmplitudeContainer.Scale); ripple.Alpha = 0.15f * amplitudeAdjust; - ripple.ScaleTo(logoAmplitudeContainer.Scale * (1 + (0.04f * amplitudeAdjust)), beatLength, EasingTypes.OutQuint); + ripple.ScaleTo(logoAmplitudeContainer.Scale * (1 + 0.04f * amplitudeAdjust), beatLength, EasingTypes.OutQuint); ripple.FadeOut(beatLength, EasingTypes.OutQuint); if (effectPoint.KiaiMode && flashLayer.Alpha < 0.4f) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index c1d6d2eb9d..3f8d6af320 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -311,7 +311,7 @@ namespace osu.Game.Screens.Select foreach (BeatmapPanel panel in group.BeatmapPanels) { if (panel == selectedPanel) - selectedY = currentY + (panel.DrawHeight / 2) - (DrawHeight / 2); + selectedY = currentY + panel.DrawHeight / 2 - DrawHeight / 2; panel.MoveToX(-50, 500, EasingTypes.OutExpo); @@ -477,7 +477,7 @@ namespace osu.Game.Screens.Select { // The radius of the circle the carousel moves on. const float circle_radius = 3; - double discriminant = Math.Max(0, (circle_radius * circle_radius) - (dist * dist)); + double discriminant = Math.Max(0, circle_radius * circle_radius - dist * dist); float x = (circle_radius - (float)Math.Sqrt(discriminant)) * halfHeight; return 125 + x; @@ -493,8 +493,8 @@ namespace osu.Game.Screens.Select { var height = p.IsPresent ? p.DrawHeight : 0; - float panelDrawY = (p.Position.Y - Current) + (height / 2); - float dist = Math.Abs(1f - (panelDrawY / halfHeight)); + float panelDrawY = p.Position.Y - Current + height / 2; + float dist = Math.Abs(1f - panelDrawY / halfHeight); // Setting the origin position serves as an additive position on top of potential // local transformation we may want to apply (e.g. when a panel gets selected, we @@ -504,7 +504,7 @@ namespace osu.Game.Screens.Select // We are applying a multiplicative alpha (which is internally done by nesting an // additional container and setting that container's alpha) such that we can // layer transformations on top, with a similar reasoning to the previous comment. - p.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - (1.5f * dist), 0, 1)); + p.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - 1.5f * dist, 0, 1)); } } } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 81db49b658..2aec489508 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -46,10 +46,7 @@ namespace osu.Game.Screens.Select public BeatmapInfo Beatmap { - get - { - return beatmap; - } + get { return beatmap; } set { diff --git a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs index d3d2a18cfa..31043a411b 100644 --- a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs +++ b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs @@ -82,10 +82,7 @@ namespace osu.Game.Screens.Tournament private ScrollState _scrollState; private ScrollState scrollState { - get - { - return _scrollState; - } + get { return _scrollState; } set { @@ -265,7 +262,7 @@ namespace osu.Game.Screens.Tournament else { c.MoveToX(pos, 100); - c.FadeTo(1.0f - (Math.Abs(pos - (DrawWidth / 2f)) / (DrawWidth / 2.5f)), 100); + c.FadeTo(1.0f - Math.Abs(pos - DrawWidth / 2f) / (DrawWidth / 2.5f), 100); } pos += ScrollingTeam.WIDTH; @@ -332,10 +329,7 @@ namespace osu.Game.Screens.Tournament private bool selected; public bool Selected { - get - { - return selected; - } + get { return selected; } set { From 59e539f16611b39f45900e40e9ffd356d513f44d Mon Sep 17 00:00:00 2001 From: Alex Amadori Date: Wed, 7 Jun 2017 18:03:27 +0200 Subject: [PATCH 43/45] Fix build error on unix --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1ebbb4adf3..a83945d5db 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -43,7 +43,7 @@ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll - $(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll + $(SolutionDir)\packages\sharpcompress.0.15.2\lib\net45\SharpCompress.dll $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll From a0bdab9f0de894b1c06f28bb720f73b2d0f03584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Nemes?= Date: Wed, 7 Jun 2017 20:29:03 +0200 Subject: [PATCH 44/45] Aaand docs again. --- osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs | 3 +++ osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs | 3 +++ osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs index 99d0e761ad..aad53f6fe8 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs @@ -6,6 +6,9 @@ using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { + /// + /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. + /// public class Aim : Skill { protected override double SkillMultiplier => 26.25; diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs index 826d62adcc..b06063fca4 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -3,6 +3,9 @@ using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +/// +/// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. +/// namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { public class Speed : Skill diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs index 92b206ccf8..d2c2e1d774 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils { get { - if (i > Count - 1) + if (i < 0 || i > Count - 1) throw new IndexOutOfRangeException(); i += marker; From 9d915a691dd6c8273f21d9112b733cc2e7944f19 Mon Sep 17 00:00:00 2001 From: Drezi126 Date: Thu, 8 Jun 2017 00:17:58 +0200 Subject: [PATCH 45/45] Fix comment placement. --- osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs index b06063fca4..6c43c53e35 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs @@ -3,11 +3,11 @@ using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; -/// -/// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. -/// namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills { + /// + /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. + /// public class Speed : Skill { protected override double SkillMultiplier => 1400;