diff --git a/appveyor.yml b/appveyor.yml index cc6dfb9c88..b26a895788 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,4 +20,4 @@ build: verbosity: minimal after_build: - cmd: inspectcode /o="inspectcodereport.xml" /caches-home="inspectcode" osu.sln - - cmd: NVika parsereport "inspectcodereport.xml" \ No newline at end of file + - cmd: NVika parsereport "inspectcodereport.xml" --treatwarningsaserrors \ No newline at end of file diff --git a/osu-framework b/osu-framework index 00e48bcd31..3ad1dd52ae 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 00e48bcd31b7debda89bbcf62927706c43eba644 +Subproject commit 3ad1dd52ae511b816fb928f70ef811ec605c5c18 diff --git a/osu.Desktop.VisualTests/Tests/TestCaseReplaySettingsOverlay.cs b/osu.Desktop.VisualTests/Tests/TestCaseReplaySettingsOverlay.cs new file mode 100644 index 0000000000..b2c211b7f0 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseReplaySettingsOverlay.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Play; +using osu.Game.Screens.Play.ReplaySettings; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseReplaySettingsOverlay : TestCase + { + public override string Description => @"Settings visible in replay/auto"; + + private ExampleContainer container; + + public override void Reset() + { + base.Reset(); + + Add(new ReplaySettingsOverlay() + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }); + + Add(container = new ExampleContainer()); + + AddStep(@"Add button", () => container.Add(new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = @"Button", + })); + + AddStep(@"Add checkbox", () => container.Add(new ReplayCheckbox + { + LabelText = "Checkbox", + })); + + AddStep(@"Add textbox", () => container.Add(new FocusedTextBox + { + RelativeSizeAxes = Axes.X, + Height = 30, + PlaceholderText = "Textbox", + HoldFocus = false, + })); + } + + private class ExampleContainer : ReplayGroup + { + protected override string Title => @"example"; + } + } +} diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSkipButton.cs b/osu.Desktop.VisualTests/Tests/TestCaseSkipButton.cs new file mode 100644 index 0000000000..fb5be719c1 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseSkipButton.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Testing; +using osu.Game.Screens.Play; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseSkipButton : TestCase + { + public override string Description => @"Skip skip skippediskip"; + + public override void Reset() + { + base.Reset(); + Add(new SkipButton(Clock.CurrentTime + 5000)); + } + } +} diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs b/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs index ba17cfc3d8..2decb4c469 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs @@ -3,20 +3,18 @@ using osu.Framework.Testing; using osu.Game.Graphics.UserInterface; -using osu.Game.Screens.Play; namespace osu.Desktop.VisualTests.Tests { internal class TestCaseTwoLayerButton : TestCase { - public override string Description => @"Back and skip and what not"; + public override string Description => @"Mostly back button"; public override void Reset() { base.Reset(); Add(new BackButton()); - Add(new SkipButton(Clock.CurrentTime + 5000)); } } } diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 850c38cc24..f72b08adde 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -196,6 +196,7 @@ <Compile Include="Tests\TestCaseMusicController.cs" /> <Compile Include="Tests\TestCaseNotificationManager.cs" /> <Compile Include="Tests\TestCaseOnScreenDisplay.cs" /> + <Compile Include="Tests\TestCaseReplaySettingsOverlay.cs" /> <Compile Include="Tests\TestCasePlayer.cs" /> <Compile Include="Tests\TestCaseHitObjects.cs" /> <Compile Include="Tests\TestCaseKeyCounter.cs" /> @@ -203,6 +204,7 @@ <Compile Include="Tests\TestCaseReplay.cs" /> <Compile Include="Tests\TestCaseResults.cs" /> <Compile Include="Tests\TestCaseScoreCounter.cs" /> + <Compile Include="Tests\TestCaseSkipButton.cs" /> <Compile Include="Tests\TestCaseTabControl.cs" /> <Compile Include="Tests\TestCaseTaikoHitObjects.cs" /> <Compile Include="Tests\TestCaseTaikoPlayfield.cs" /> diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 8b2a06ad0b..3f56dc0b79 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -71,6 +71,9 @@ namespace osu.Game.Configuration Set(OsuSetting.ShowInterface, true); Set(OsuSetting.KeyOverlay, false); + Set(OsuSetting.FloatingComments, false); + Set(OsuSetting.PlaybackSpeed, 1.0, 0.5f, 2); + // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -90,6 +93,8 @@ namespace osu.Game.Configuration AutoCursorSize, DimLevel, KeyOverlay, + FloatingComments, + PlaybackSpeed, ShowInterface, MouseDisableButtons, MouseDisableWheel, diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index 46addf5ac2..815d820a47 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -24,6 +25,7 @@ namespace osu.Game.Graphics.Cursor { private readonly Box background; private readonly OsuSpriteText text; + private bool instantMovement = true; public override string TooltipText { @@ -32,7 +34,7 @@ namespace osu.Game.Graphics.Cursor if (value == text.Text) return; text.Text = value; - if (Alpha > 0) + if (IsPresent) { AutoSizeDuration = 250; background.FlashColour(OsuColour.Gray(0.4f), 1000, EasingTypes.OutQuint); @@ -80,6 +82,7 @@ namespace osu.Game.Graphics.Cursor protected override void PopIn() { + instantMovement |= !IsPresent; FadeIn(500, EasingTypes.OutQuint); } @@ -88,6 +91,19 @@ namespace osu.Game.Graphics.Cursor using (BeginDelayedSequence(150)) FadeOut(500, EasingTypes.OutQuint); } + + public override void Move(Vector2 pos) + { + if (instantMovement) + { + Position = pos; + instantMovement = false; + } + else + { + MoveTo(pos, 200, EasingTypes.OutQuint); + } + } } } } diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs new file mode 100644 index 0000000000..d2a87d2dd0 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -0,0 +1,114 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +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.Framework.Input; + +namespace osu.Game.Graphics.UserInterface +{ + public class IconButton : ClickableContainer + { + private readonly TextAwesome icon; + private readonly Box hover; + private readonly Container content; + + public FontAwesome Icon + { + get { return icon.Icon; } + set { icon.Icon = value; } + } + + private const float button_size = 30; + private Color4 flashColour; + + public Vector2 IconScale + { + get { return icon.Scale; } + set { icon.Scale = value; } + } + + public IconButton() + { + AutoSizeAxes = Axes.Both; + + Origin = Anchor.Centre; + Anchor = Anchor.Centre; + + Children = new Drawable[] + { + content = new Container + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Size = new Vector2 (button_size), + + CornerRadius = 5, + Masking = true, + EdgeEffect = new EdgeEffect + { + Colour = Color4.Black.Opacity(0.04f), + Type = EdgeEffectType.Shadow, + Radius = 5, + }, + Children = new Drawable[] + { + hover = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + icon = new TextAwesome + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + TextSize = 18, + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hover.Colour = colours.Yellow.Opacity(0.6f); + flashColour = colours.Yellow; + } + + protected override bool OnHover(InputState state) + { + hover.FadeIn(500, EasingTypes.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + hover.FadeOut(500, EasingTypes.OutQuint); + base.OnHoverLost(state); + } + + protected override bool OnClick(InputState state) + { + hover.FlashColour(flashColour, 800, EasingTypes.OutQuint); + return base.OnClick(state); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + content.ScaleTo(0.75f, 2000, EasingTypes.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + content.ScaleTo(1, 1000, EasingTypes.OutElastic); + return base.OnMouseUp(state, args); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 82ede8f079..a5cbc9f53f 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -12,13 +12,12 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface { - public class Nub : CircularContainer, IHasCurrentValue<bool> + public class Nub : CircularContainer, IHasCurrentValue<bool>, IHasAccentColour { public const float COLLAPSED_SIZE = 20; public const float EXPANDED_SIZE = 40; private const float border_width = 3; - private Color4 glowingColour, idleColour; public Nub() { @@ -53,33 +52,41 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - Colour = idleColour = colours.Pink; - glowingColour = colours.PinkLighter; + AccentColour = colours.Pink; + GlowingAccentColour = colours.PinkLighter; + GlowColour = colours.PinkDarker; EdgeEffect = new EdgeEffect { - Colour = colours.PinkDarker, + Colour = GlowColour, Type = EdgeEffectType.Glow, Radius = 10, Roundness = 8, }; + } + protected override void LoadComplete() + { FadeEdgeEffectTo(0); } + private bool glowing; public bool Glowing { + get { return glowing; } set { + glowing = value; + if (value) { - FadeColour(glowingColour, 500, EasingTypes.OutQuint); + FadeColour(GlowingAccentColour, 500, EasingTypes.OutQuint); FadeEdgeEffectTo(1, 500, EasingTypes.OutQuint); } else { FadeEdgeEffectTo(0, 500); - FadeColour(idleColour, 500); + FadeColour(AccentColour, 500); } } } @@ -93,5 +100,43 @@ namespace osu.Game.Graphics.UserInterface } public Bindable<bool> Current { get; } = new Bindable<bool>(); + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + if (!Glowing) + Colour = value; + } + } + + private Color4 glowingAccentColour; + public Color4 GlowingAccentColour + { + get { return glowingAccentColour; } + set + { + glowingAccentColour = value; + if (Glowing) + Colour = value; + } + } + + private Color4 glowColour; + public Color4 GlowColour + { + get { return glowColour; } + set + { + glowColour = value; + + var effect = EdgeEffect; + effect.Colour = value; + EdgeEffect = effect; + } + } } } diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs index 85231ffab9..198a01b5a4 100644 --- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs @@ -51,7 +51,8 @@ namespace osu.Game.Graphics.UserInterface } } - private readonly Nub nub; + protected readonly Nub Nub; + private readonly SpriteText labelSpriteText; private SampleChannel sampleChecked; private SampleChannel sampleUnchecked; @@ -64,7 +65,7 @@ namespace osu.Game.Graphics.UserInterface Children = new Drawable[] { labelSpriteText = new OsuSpriteText(), - nub = new Nub + Nub = new Nub { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -72,7 +73,7 @@ namespace osu.Game.Graphics.UserInterface } }; - nub.Current.BindTo(Current); + Nub.Current.BindTo(Current); Current.ValueChanged += newValue => { @@ -90,15 +91,15 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(InputState state) { - nub.Glowing = true; - nub.Expanded = true; + Nub.Glowing = true; + Nub.Expanded = true; return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - nub.Glowing = false; - nub.Expanded = false; + Nub.Glowing = false; + Nub.Expanded = false; base.OnHoverLost(state); } diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index c8be085b51..2dab952204 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -3,6 +3,7 @@ using System; using OpenTK; +using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -15,14 +16,14 @@ using osu.Framework.Graphics.Cursor; namespace osu.Game.Graphics.UserInterface { - public class OsuSliderBar<T> : SliderBar<T>, IHasTooltip + public class OsuSliderBar<T> : SliderBar<T>, IHasTooltip, IHasAccentColour where T : struct, IEquatable<T> { private SampleChannel sample; private double lastSampleTime; private T lastSampleValue; - private readonly Nub nub; + protected readonly Nub Nub; private readonly Box leftBox; private readonly Box rightBox; @@ -46,6 +47,18 @@ namespace osu.Game.Graphics.UserInterface } } + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + leftBox.Colour = value; + rightBox.Colour = value; + } + } + public OsuSliderBar() { Height = 12; @@ -71,7 +84,7 @@ namespace osu.Game.Graphics.UserInterface Origin = Anchor.CentreRight, Alpha = 0.5f, }, - nub = new Nub + Nub = new Nub { Origin = Anchor.TopCentre, Expanded = true, @@ -88,19 +101,18 @@ namespace osu.Game.Graphics.UserInterface private void load(AudioManager audio, OsuColour colours) { sample = audio.Sample.Get(@"Sliderbar/sliderbar"); - leftBox.Colour = colours.Pink; - rightBox.Colour = colours.Pink; + AccentColour = colours.Pink; } protected override bool OnHover(InputState state) { - nub.Glowing = true; + Nub.Glowing = true; return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - nub.Glowing = false; + Nub.Glowing = false; base.OnHoverLost(state); } @@ -133,13 +145,13 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - nub.Current.Value = true; + Nub.Current.Value = true; return base.OnMouseDown(state, args); } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - nub.Current.Value = false; + Nub.Current.Value = false; return base.OnMouseUp(state, args); } @@ -147,14 +159,14 @@ namespace osu.Game.Graphics.UserInterface { base.UpdateAfterChildren(); leftBox.Scale = new Vector2(MathHelper.Clamp( - nub.DrawPosition.X - nub.DrawWidth / 2, 0, DrawWidth), 1); + Nub.DrawPosition.X - Nub.DrawWidth / 2, 0, DrawWidth), 1); rightBox.Scale = new Vector2(MathHelper.Clamp( - DrawWidth - nub.DrawPosition.X - nub.DrawWidth / 2, 0, DrawWidth), 1); + DrawWidth - Nub.DrawPosition.X - Nub.DrawWidth / 2, 0, DrawWidth), 1); } protected override void UpdateValue(float value) { - nub.MoveToX(RangePadding + UsableWidth * value, 250, EasingTypes.OutQuint); + Nub.MoveToX(RangePadding + UsableWidth * value, 250, EasingTypes.OutQuint); } } } diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 93fd0a8956..01685cc7dc 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Configuration; using osu.Framework.Lists; namespace osu.Game.Online.Chat @@ -25,7 +26,7 @@ namespace osu.Game.Online.Chat public readonly SortedList<Message> Messages = new SortedList<Message>(Comparer<Message>.Default); - //internal bool Joined; + public Bindable<bool> Joined = new Bindable<bool>(); public bool ReadOnly => Name != "#lazer"; diff --git a/osu.Game/Overlays/Chat/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelListItem.cs new file mode 100644 index 0000000000..9aa11cdd4f --- /dev/null +++ b/osu.Game/Overlays/Chat/ChannelListItem.cs @@ -0,0 +1,188 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; + +namespace osu.Game.Overlays.Chat +{ + public class ChannelListItem : ClickableContainer, IFilterable + { + private const float width_padding = 5; + private const float channel_width = 150; + private const float text_size = 15; + private const float transition_duration = 100; + + private readonly Channel channel; + + private readonly Bindable<bool> joinedBind = new Bindable<bool>(); + private readonly OsuSpriteText name; + private readonly OsuSpriteText topic; + private readonly TextAwesome joinedCheckmark; + + private Color4 joinedColour; + private Color4 topicColour; + private Color4 hoverColour; + + public string[] FilterTerms => new[] { channel.Name }; + public bool MatchingFilter + { + set + { + FadeTo(value ? 1f : 0f, 100); + } + } + + public Action<Channel> OnRequestJoin; + public Action<Channel> OnRequestLeave; + + public ChannelListItem(Channel channel) + { + this.channel = channel; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Action = () => { (channel.Joined ? OnRequestLeave : OnRequestJoin)?.Invoke(channel); }; + + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new Container + { + Children = new[] + { + joinedCheckmark = new TextAwesome + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Icon = FontAwesome.fa_check_circle, + TextSize = text_size, + Shadow = false, + Margin = new MarginPadding { Right = 10f }, + Alpha = 0f, + }, + }, + }, + new Container + { + Width = channel_width, + AutoSizeAxes = Axes.Y, + Children = new[] + { + name = new OsuSpriteText + { + Text = channel.ToString(), + TextSize = text_size, + Font = @"Exo2.0-Bold", + Shadow = false, + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.X, + Width = 0.7f, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Left = width_padding }, + Children = new[] + { + topic = new OsuSpriteText + { + Text = channel.Topic, + TextSize = text_size, + Font = @"Exo2.0-SemiBold", + Shadow = false, + Alpha = 0.8f, + }, + }, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Left = width_padding }, + Spacing = new Vector2(3f, 0f), + Children = new Drawable[] + { + new TextAwesome + { + Icon = FontAwesome.fa_user, + TextSize = text_size - 2, + Shadow = false, + Margin = new MarginPadding { Top = 1 }, + }, + new OsuSpriteText + { + Text = @"0", + TextSize = text_size, + Font = @"Exo2.0-SemiBold", + Shadow = false, + }, + }, + }, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + topicColour = colours.Gray9; + joinedColour = colours.Blue; + hoverColour = colours.Yellow; + + joinedBind.ValueChanged += updateColour; + joinedBind.BindTo(channel.Joined); + } + + protected override bool OnHover(InputState state) + { + if (!channel.Joined.Value) + name.FadeColour(hoverColour, 50, EasingTypes.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + if (!channel.Joined.Value) + name.FadeColour(Color4.White, transition_duration); + } + + private void updateColour(bool joined) + { + if (joined) + { + name.FadeColour(Color4.White, transition_duration); + joinedCheckmark.FadeTo(1f, transition_duration); + topic.FadeTo(0.8f, transition_duration); + topic.FadeColour(Color4.White, transition_duration); + FadeColour(joinedColour, transition_duration); + } + else + { + joinedCheckmark.FadeTo(0f, transition_duration); + topic.FadeTo(1f, transition_duration); + topic.FadeColour(topicColour, transition_duration); + FadeColour(Color4.White, transition_duration); + } + } + } +} diff --git a/osu.Game/Overlays/Chat/ChannelSection.cs b/osu.Game/Overlays/Chat/ChannelSection.cs new file mode 100644 index 0000000000..f12ec53605 --- /dev/null +++ b/osu.Game/Overlays/Chat/ChannelSection.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using OpenTK; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; + +namespace osu.Game.Overlays.Chat +{ + public class ChannelSection : Container, IHasFilterableChildren + { + private readonly OsuSpriteText header; + + public readonly FillFlowContainer<ChannelListItem> ChannelFlow; + + public IEnumerable<IFilterable> FilterableChildren => ChannelFlow.Children; + public string[] FilterTerms => new[] { Header }; + public bool MatchingFilter + { + set + { + FadeTo(value ? 1f : 0f, 100); + } + } + + public string Header + { + get { return header.Text; } + set { header.Text = value.ToUpper(); } + } + + public IEnumerable<Channel> Channels + { + set { ChannelFlow.Children = value.Select(c => new ChannelListItem(c)); } + } + + public ChannelSection() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Children = new Drawable[] + { + header = new OsuSpriteText + { + TextSize = 15, + Font = @"Exo2.0-Bold", + }, + ChannelFlow = new FillFlowContainer<ChannelListItem> + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 25 }, + Spacing = new Vector2(0f, 5f), + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs b/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs new file mode 100644 index 0000000000..cd736a5fe9 --- /dev/null +++ b/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs @@ -0,0 +1,184 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +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.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Chat; + +namespace osu.Game.Overlays.Chat +{ + public class ChannelSelectionOverlay : FocusedOverlayContainer + { + public static readonly float WIDTH_PADDING = 170; + + private const float transition_duration = 500; + + private readonly Box bg; + private readonly Triangles triangles; + private readonly Box headerBg; + private readonly SearchTextBox search; + private readonly SearchContainer<ChannelSection> sectionsFlow; + + public Action<Channel> OnRequestJoin; + public Action<Channel> OnRequestLeave; + + public IEnumerable<ChannelSection> Sections + { + set + { + sectionsFlow.Children = value; + + foreach (ChannelSection s in sectionsFlow.Children) + { + foreach (ChannelListItem c in s.ChannelFlow.Children) + { + c.OnRequestJoin = channel => { OnRequestJoin?.Invoke(channel); }; + c.OnRequestLeave = channel => { OnRequestLeave?.Invoke(channel); }; + } + } + } + } + + public ChannelSelectionOverlay() + { + RelativeSizeAxes = Axes.X; + + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Children = new Drawable[] + { + bg = new Box + { + RelativeSizeAxes = Axes.Both, + }, + triangles = new Triangles + { + RelativeSizeAxes = Axes.Both, + TriangleScale = 5, + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 85, Right = WIDTH_PADDING }, + Children = new[] + { + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + Children = new[] + { + sectionsFlow = new SearchContainer<ChannelSection> + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + LayoutDuration = 200, + LayoutEasing = EasingTypes.OutQuint, + Spacing = new Vector2(0f, 20f), + Padding = new MarginPadding { Vertical = 20, Left = WIDTH_PADDING }, + }, + }, + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + headerBg = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0f, 10f), + Padding = new MarginPadding { Top = 10f, Bottom = 10f, Left = WIDTH_PADDING, Right = WIDTH_PADDING }, + Children = new Drawable[] + { + new OsuSpriteText + { + Text = @"Chat Channels", + TextSize = 20, + Shadow = false, + }, + search = new HeaderSearchTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = @"Search", + Exit = Hide, + }, + }, + }, + }, + }, + }; + + search.Current.ValueChanged += newValue => sectionsFlow.SearchTerm = newValue; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + bg.Colour = colours.Gray3; + triangles.ColourDark = colours.Gray3; + triangles.ColourLight = OsuColour.FromHex(@"353535"); + + headerBg.Colour = colours.Gray2.Opacity(0.75f); + } + + protected override void OnFocus(InputState state) + { + InputManager.ChangeFocus(search); + base.OnFocus(state); + } + + protected override void PopIn() + { + if (Alpha == 0) MoveToY(DrawHeight); + + FadeIn(transition_duration, EasingTypes.OutQuint); + MoveToY(0, transition_duration, EasingTypes.OutQuint); + + search.HoldFocus = true; + base.PopIn(); + } + + protected override void PopOut() + { + FadeOut(transition_duration, EasingTypes.InSine); + MoveToY(DrawHeight, transition_duration, EasingTypes.InSine); + + search.HoldFocus = false; + base.PopOut(); + } + + private class HeaderSearchTextBox : SearchTextBox + { + protected override Color4 BackgroundFocused => Color4.Black.Opacity(0.2f); + protected override Color4 BackgroundUnfocused => Color4.Black.Opacity(0.2f); + } + } +} diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index a281cff7db..23ddff9381 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -207,11 +207,15 @@ namespace osu.Game.Overlays.Chat { public override bool Active { - get { return base.Active; } + get { return false; } + // ReSharper disable once ValueParameterNotUsed set { - activeBindable.Value = value; - base.Active = value; + // we basically never want this tab to become active. + // this allows us to become a "toggle" tab. + // is a bit hacky, to say the least. + activeBindable.Value = !activeBindable.Value; + base.Active = false; } } @@ -220,6 +224,9 @@ namespace osu.Game.Overlays.Chat public ChannelSelectorTabItem(Channel value, Bindable<bool> active) : base(value) { activeBindable = active; + activeBindable.ValueChanged += v => selectorUpdateState(); + + Depth = float.MaxValue; Width = 45; @@ -235,6 +242,26 @@ namespace osu.Game.Overlays.Chat backgroundInactive = colour.Gray2; backgroundActive = colour.Gray3; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + selectorUpdateState(); + } + + protected override void OnHoverLost(InputState state) + { + selectorUpdateState(); + } + + private void selectorUpdateState() + { + if (activeBindable.Value) + fadeActive(); + else + fadeInactive(); + } } } } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index f81c0ea922..c32199f881 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -29,6 +29,7 @@ namespace osu.Game.Overlays public class ChatOverlay : FocusedOverlayContainer, IOnlineComponent { private const float textbox_height = 60; + private const float channel_selection_min_height = 0.3f; private ScheduledDelegate messageRequest; @@ -48,16 +49,21 @@ namespace osu.Game.Overlays private readonly ChatTabControl channelTabs; + private readonly Container chatContainer; private readonly Box chatBackground; private readonly Box tabBackground; private Bindable<double> chatHeight; + private readonly Container channelSelectionContainer; + private readonly ChannelSelectionOverlay channelSelection; + + protected override bool InternalContains(Vector2 screenSpacePos) => chatContainer.Contains(screenSpacePos) || channelSelection.State == Visibility.Visible && channelSelection.Contains(screenSpacePos); + public ChatOverlay() { RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; - Size = new Vector2(1, DEFAULT_HEIGHT); Anchor = Anchor.BottomLeft; Origin = Anchor.BottomLeft; @@ -65,74 +71,120 @@ namespace osu.Game.Overlays Children = new Drawable[] { - new Container + channelSelectionContainer = new Container { - Name = @"chat area", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = TAB_AREA_HEIGHT }, - Children = new Drawable[] + Height = 1f - DEFAULT_HEIGHT, + Masking = true, + Children = new[] { - chatBackground = new Box + channelSelection = new ChannelSelectionOverlay { RelativeSizeAxes = Axes.Both, }, - currentChannelContainer = new Container + }, + }, + chatContainer = new Container + { + Name = @"chat container", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Height = DEFAULT_HEIGHT, + Children = new[] + { + new Container { + Name = @"chat area", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding + Padding = new MarginPadding { Top = TAB_AREA_HEIGHT }, + Children = new Drawable[] { - Bottom = textbox_height + padding - }, + chatBackground = new Box + { + RelativeSizeAxes = Axes.Both, + }, + currentChannelContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding + { + Bottom = textbox_height + padding + }, + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = textbox_height, + Padding = new MarginPadding + { + Top = padding * 2, + Bottom = padding * 2, + Left = ChatLine.LEFT_PADDING + padding * 2, + Right = padding * 2, + }, + Children = new Drawable[] + { + inputTextBox = new FocusedTextBox + { + RelativeSizeAxes = Axes.Both, + Height = 1, + PlaceholderText = "type your message", + Exit = () => State = Visibility.Hidden, + OnCommit = postMessage, + ReleaseFocusOnCommit = false, + HoldFocus = true, + } + } + } + } }, new Container { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, + Name = @"tabs area", RelativeSizeAxes = Axes.X, - Height = textbox_height, - Padding = new MarginPadding - { - Top = padding * 2, - Bottom = padding * 2, - Left = ChatLine.LEFT_PADDING + padding * 2, - Right = padding * 2, - }, + Height = TAB_AREA_HEIGHT, Children = new Drawable[] { - inputTextBox = new FocusedTextBox + tabBackground = new Box { RelativeSizeAxes = Axes.Both, - Height = 1, - PlaceholderText = "type your message", - Exit = () => State = Visibility.Hidden, - OnCommit = postMessage, - HoldFocus = true, - } + Colour = Color4.Black, + }, + channelTabs = new ChatTabControl + { + RelativeSizeAxes = Axes.Both, + }, } - } - } - }, - new Container - { - Name = @"tabs area", - RelativeSizeAxes = Axes.X, - Height = TAB_AREA_HEIGHT, - Children = new Drawable[] - { - tabBackground = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, }, - channelTabs = new ChatTabControl - { - RelativeSizeAxes = Axes.Both, - }, - } + }, }, }; channelTabs.Current.ValueChanged += newChannel => CurrentChannel = newChannel; + channelTabs.ChannelSelectorActive.ValueChanged += value => channelSelection.State = value ? Visibility.Visible : Visibility.Hidden; + channelSelection.StateChanged += (overlay, state) => + { + channelTabs.ChannelSelectorActive.Value = state == Visibility.Visible; + + if (state == Visibility.Visible) + { + inputTextBox.HoldFocus = false; + if (1f - chatHeight.Value < channel_selection_min_height) + { + chatContainer.ResizeHeightTo(1f - channel_selection_min_height, 800, EasingTypes.OutQuint); + channelSelectionContainer.ResizeHeightTo(channel_selection_min_height, 800, EasingTypes.OutQuint); + channelSelection.Show(); + chatHeight.Value = 1f - channel_selection_min_height; + } + } + else + { + inputTextBox.HoldFocus = true; + } + }; } private double startDragChatHeight; @@ -205,8 +257,9 @@ namespace osu.Game.Overlays chatHeight = config.GetBindable<double>(OsuSetting.ChatDisplayHeight); chatHeight.ValueChanged += h => { - Height = (float)h; - tabBackground.FadeTo(Height == 1 ? 1 : 0.8f, 200); + chatContainer.Height = (float)h; + channelSelectionContainer.Height = 1f - (float)h; + tabBackground.FadeTo(h == 1 ? 1 : 0.8f, 200); }; chatHeight.TriggerChange(); @@ -243,6 +296,16 @@ namespace osu.Game.Overlays addChannel(channels.Find(c => c.Name == @"#lazer")); addChannel(channels.Find(c => c.Name == @"#osu")); addChannel(channels.Find(c => c.Name == @"#lobby")); + + channelSelection.OnRequestJoin = addChannel; + channelSelection.Sections = new[] + { + new ChannelSection + { + Header = "All Channels", + Channels = channels, + }, + }; }); messageRequest = Scheduler.AddDelayed(fetchNewMessages, 1000, true); @@ -262,9 +325,7 @@ namespace osu.Game.Overlays set { - if (currentChannel == value) return; - - if (channelTabs.ChannelSelectorActive) return; + if (currentChannel == value || value == null) return; currentChannel = value; @@ -316,6 +377,8 @@ namespace osu.Game.Overlays if (CurrentChannel == null) CurrentChannel = channel; + + channel.Joined.Value = true; } private void fetchInitialMessages(Channel channel) diff --git a/osu.Game/Overlays/Music/CollectionsDropdown.cs b/osu.Game/Overlays/Music/CollectionsDropdown.cs new file mode 100644 index 0000000000..fd2ef23b9c --- /dev/null +++ b/osu.Game/Overlays/Music/CollectionsDropdown.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +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.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Music +{ + public class CollectionsDropdown<T> : OsuDropdown<T> + { + protected override DropdownHeader CreateHeader() => new CollectionsHeader { AccentColour = AccentColour }; + protected override Menu CreateMenu() => new CollectionsMenu(); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.Gray6; + } + + private class CollectionsHeader : OsuDropdownHeader + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray4; + } + + public CollectionsHeader() + { + CornerRadius = 5; + Height = 30; + Icon.TextSize = 14; + Icon.Margin = new MarginPadding(0); + Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 10, Right = 10 }; + EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.3f), + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + } + } + + private class CollectionsMenu : OsuMenu + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Background.Colour = colours.Gray4; + } + + public CollectionsMenu() + { + CornerRadius = 5; + EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.3f), + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + } + } + } +} diff --git a/osu.Game/Overlays/Music/FilterControl.cs b/osu.Game/Overlays/Music/FilterControl.cs index 6d8790a9e8..56cd6e864b 100644 --- a/osu.Game/Overlays/Music/FilterControl.cs +++ b/osu.Game/Overlays/Music/FilterControl.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using OpenTK; @@ -74,63 +72,5 @@ namespace osu.Game.Overlays.Music backgroundColour = colours.Gray2; } } - - private class CollectionsDropdown<T> : OsuDropdown<T> - { - protected override DropdownHeader CreateHeader() => new CollectionsHeader { AccentColour = AccentColour }; - protected override Menu CreateMenu() => new CollectionsMenu(); - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - AccentColour = colours.Gray6; - } - - private class CollectionsHeader : OsuDropdownHeader - { - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray4; - } - - public CollectionsHeader() - { - CornerRadius = 5; - Height = 30; - Icon.TextSize = 14; - Icon.Margin = new MarginPadding(0); - Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 10, Right = 10 }; - EdgeEffect = new EdgeEffect - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.3f), - Radius = 3, - Offset = new Vector2(0f, 1f), - }; - } - } - - private class CollectionsMenu : OsuMenu - { - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Background.Colour = colours.Gray4; - } - - public CollectionsMenu() - { - CornerRadius = 5; - EdgeEffect = new EdgeEffect - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.3f), - Radius = 3, - Offset = new Vector2(0f, 1f), - }; - } - } - } } } diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 0618f96cac..789e45adfc 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Music private Color4 artistColour; private TextAwesome handle; - private Paragraph text; + private TextFlowContainer text; private IEnumerable<SpriteText> titleSprites; private UnicodeBindableString titleBind; private UnicodeBindableString artistBind; @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Music Margin = new MarginPadding { Left = 5 }, Padding = new MarginPadding { Top = 2 }, }, - text = new Paragraph + text = new TextFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f1be55801f..bfe10e845e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -22,6 +22,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Threading; using osu.Game.Overlays.Music; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays { @@ -38,8 +39,8 @@ namespace osu.Game.Overlays private Drawable currentBackground; private DragBar progressBar; - private Button playButton; - private Button playlistButton; + private IconButton playButton; + private IconButton playlistButton; private SpriteText title, artist; @@ -143,7 +144,7 @@ namespace osu.Game.Overlays Anchor = Anchor.BottomCentre, Children = new Drawable[] { - new FillFlowContainer<Button> + new FillFlowContainer<IconButton> { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, @@ -152,26 +153,26 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Children = new[] { - new Button + new IconButton { Action = prev, Icon = FontAwesome.fa_step_backward, }, - playButton = new Button + playButton = new IconButton { Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), Action = play, Icon = FontAwesome.fa_play_circle_o, }, - new Button + new IconButton { Action = next, Icon = FontAwesome.fa_step_forward, }, } }, - playlistButton = new Button + playlistButton = new IconButton { Origin = Anchor.Centre, Anchor = Anchor.CentreRight, @@ -415,105 +416,5 @@ namespace osu.Game.Overlays sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); } } - - private class Button : ClickableContainer - { - private readonly TextAwesome icon; - private readonly Box hover; - private readonly Container content; - - public FontAwesome Icon - { - get { return icon.Icon; } - set { icon.Icon = value; } - } - - private const float button_size = 30; - private Color4 flashColour; - - public Vector2 IconScale - { - get { return icon.Scale; } - set { icon.Scale = value; } - } - - public Button() - { - AutoSizeAxes = Axes.Both; - - Origin = Anchor.Centre; - Anchor = Anchor.Centre; - - Children = new Drawable[] - { - content = new Container - { - Size = new Vector2(button_size), - CornerRadius = 5, - Masking = true, - - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - EdgeEffect = new EdgeEffect - { - Colour = Color4.Black.Opacity(0.04f), - Type = EdgeEffectType.Shadow, - Radius = 5, - }, - Children = new Drawable[] - { - hover = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - }, - icon = new TextAwesome - { - TextSize = 18, - Origin = Anchor.Centre, - Anchor = Anchor.Centre - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hover.Colour = colours.Yellow.Opacity(0.6f); - flashColour = colours.Yellow; - } - - protected override bool OnHover(InputState state) - { - hover.FadeIn(500, EasingTypes.OutQuint); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - hover.FadeOut(500, EasingTypes.OutQuint); - base.OnHoverLost(state); - } - - protected override bool OnClick(InputState state) - { - hover.FlashColour(flashColour, 800, EasingTypes.OutQuint); - return base.OnClick(state); - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - content.ScaleTo(0.75f, 2000, EasingTypes.OutQuint); - return base.OnMouseDown(state, args); - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - content.ScaleTo(1, 1000, EasingTypes.OutElastic); - return base.OnMouseUp(state, args); - } - } } } diff --git a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs index 9cf5c42319..311fa072c6 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs @@ -14,14 +14,31 @@ namespace osu.Game.Overlays.Settings.Sections.Input { protected override string Header => "Mouse"; + private readonly BindableBool rawInputToggle = new BindableBool(); + private Bindable<string> activeInputHandlers; + private SensitivitySetting sensitivity; + [BackgroundDependencyLoader] private void load(OsuConfigManager osuConfig, FrameworkConfigManager config) { + activeInputHandlers = config.GetBindable<string>(FrameworkSetting.ActiveInputHandlers); + rawInputToggle.Value = activeInputHandlers.Value.Contains("Raw"); + Children = new Drawable[] { + new SettingsCheckbox + { + LabelText = "Raw Input", + Bindable = rawInputToggle + }, + sensitivity = new SensitivitySetting + { + LabelText = "Cursor Sensitivity", + Bindable = config.GetBindable<double>(FrameworkSetting.CursorSensitivity) + }, new SettingsEnumDropdown<ConfineMouseMode> { - LabelText = "Confine mouse cursor", + LabelText = "Confine mouse cursor to window", Bindable = config.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode), }, new SettingsCheckbox @@ -35,11 +52,82 @@ namespace osu.Game.Overlays.Settings.Sections.Input Bindable = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons) }, }; + + rawInputToggle.ValueChanged += enabled => + { + // this is temporary until we support per-handler settings. + const string raw_mouse_handler = @"OpenTKRawMouseHandler"; + const string standard_mouse_handler = @"OpenTKMouseHandler"; + + activeInputHandlers.Value = enabled ? + activeInputHandlers.Value.Replace(standard_mouse_handler, raw_mouse_handler) : + activeInputHandlers.Value.Replace(raw_mouse_handler, standard_mouse_handler); + + sensitivity.Bindable.Disabled = !enabled; + }; + + rawInputToggle.TriggerChange(); + } + + private class SensitivitySetting : SettingsSlider<double, SensitivitySlider> + { + public override Bindable<double> Bindable + { + get { return ((SensitivitySlider)Control).Sensitivity; } + + set + { + BindableDouble doubleValue = (BindableDouble)value; + + // create a second layer of bindable so we can only handle state changes when not being dragged. + ((SensitivitySlider)Control).Sensitivity = doubleValue; + + // this bindable will still act as the "interactive" bindable displayed during a drag. + base.Bindable = new BindableDouble(doubleValue.Value) + { + MinValue = doubleValue.MinValue, + MaxValue = doubleValue.MaxValue + }; + + // one-way binding to update the sliderbar with changes from external actions. + doubleValue.DisabledChanged += disabled => base.Bindable.Disabled = disabled; + doubleValue.ValueChanged += newValue => base.Bindable.Value = newValue; + } + } } private class SensitivitySlider : OsuSliderBar<double> { - public override string TooltipText => Current.Value.ToString(@"0.##x"); + public Bindable<double> Sensitivity; + + public SensitivitySlider() + { + KeyboardStep = 0.01f; + + Current.ValueChanged += newValue => + { + if (!isDragging && Sensitivity != null) + Sensitivity.Value = newValue; + }; + } + + private bool isDragging; + + protected override bool OnDragStart(InputState state) + { + isDragging = true; + return base.OnDragStart(state); + } + + protected override bool OnDragEnd(InputState state) + { + isDragging = false; + Current.TriggerChange(); + + return base.OnDragEnd(state); + } + + public override string TooltipText => Current.Disabled ? "Enable raw input to adjust sensitivity" : Current.Value.ToString(@"0.##x"); } } -} +} \ No newline at end of file diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 7cddefb755..14b67dd6df 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Settings // hold a reference to the provided bindable so we don't have to in every settings section. private Bindable<T> bindable; - public Bindable<T> Bindable + public virtual Bindable<T> Bindable { get { diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 115611c244..3248495b61 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -7,21 +7,24 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Game.Configuration; +using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play.HUD; +using OpenTK; using OpenTK.Input; namespace osu.Game.Screens.Play { - public abstract class HUDOverlay : Container + public class HUDOverlay : Container { private const int duration = 100; private readonly Container content; + public readonly KeyCounterCollection KeyCounter; public readonly RollingCounter<int> ComboCounter; public readonly ScoreCounter ScoreCounter; @@ -31,18 +34,11 @@ namespace osu.Game.Screens.Play public readonly ModDisplay ModDisplay; private Bindable<bool> showHud; + private bool replayLoaded; private static bool hasShownNotificationOnce; - protected abstract KeyCounterCollection CreateKeyCounter(); - protected abstract RollingCounter<int> CreateComboCounter(); - protected abstract RollingCounter<double> CreateAccuracyCounter(); - protected abstract ScoreCounter CreateScoreCounter(); - protected abstract HealthDisplay CreateHealthDisplay(); - protected abstract SongProgress CreateProgress(); - protected abstract ModDisplay CreateModsContainer(); - - protected HUDOverlay() + public HUDOverlay() { RelativeSizeAxes = Axes.Both; @@ -59,12 +55,13 @@ namespace osu.Game.Screens.Play HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), ModDisplay = CreateModsContainer(), + //ReplaySettingsOverlay = CreateReplaySettingsOverlay(), } }); } [BackgroundDependencyLoader(true)] - private void load(OsuConfigManager config, NotificationManager notificationManager) + private void load(OsuConfigManager config, NotificationManager notificationManager, OsuColour colours) { showHud = config.GetBindable<bool>(OsuSetting.ShowInterface); showHud.ValueChanged += hudVisibility => content.FadeTo(hudVisibility ? 1 : 0, duration); @@ -79,24 +76,32 @@ namespace osu.Game.Screens.Play Text = @"The score overlay is currently disabled. You can toggle this by pressing Shift+Tab." }); } - } - public virtual void BindProcessor(ScoreProcessor processor) - { - ScoreCounter?.Current.BindTo(processor.TotalScore); - AccuracyCounter?.Current.BindTo(processor.Accuracy); - ComboCounter?.Current.BindTo(processor.Combo); - HealthDisplay?.Current.BindTo(processor.Health); + // todo: the stuff below should probably not be in this base implementation, but in each individual class. + ComboCounter.AccentColour = colours.BlueLighter; + AccuracyCounter.AccentColour = colours.BlueLighter; + ScoreCounter.AccentColour = colours.BlueLighter; + + var shd = HealthDisplay as StandardHealthDisplay; + if (shd != null) + { + shd.AccentColour = colours.BlueLighter; + shd.GlowColour = colours.BlueDarker; + } } public virtual void BindHitRenderer(HitRenderer hitRenderer) { hitRenderer.InputManager.Add(KeyCounter.GetReceptor()); + replayLoaded = hitRenderer.HasReplayLoaded; + // in the case a replay isn't loaded, we want some elements to only appear briefly. - if (!hitRenderer.HasReplayLoaded) + if (!replayLoaded) + { using (ModDisplay.BeginDelayedSequence(2000)) ModDisplay.FadeOut(200); + } } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) @@ -115,5 +120,82 @@ namespace osu.Game.Screens.Play return base.OnKeyDown(state, args); } + + protected virtual RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopRight, + Position = new Vector2(0, 35), + TextSize = 20, + Margin = new MarginPadding { Right = 140 }, + }; + + protected virtual RollingCounter<int> CreateComboCounter() => new SimpleComboCounter + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopLeft, + Position = new Vector2(0, 35), + Margin = new MarginPadding { Left = 140 }, + TextSize = 20, + }; + + protected virtual HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay + { + Size = new Vector2(1, 5), + RelativeSizeAxes = Axes.X, + Margin = new MarginPadding { Top = 20 } + }; + + protected virtual KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection + { + IsCounting = true, + FadeTime = 50, + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Margin = new MarginPadding(10), + Y = -TwoLayerButton.SIZE_RETRACTED.Y, + }; + + protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + TextSize = 40, + Position = new Vector2(0, 30), + }; + + protected virtual SongProgress CreateProgress() => new SongProgress + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + }; + + protected virtual ModDisplay CreateModsContainer() => new ModDisplay + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 20, Right = 10 }, + }; + + //protected virtual ReplaySettingsOverlay CreateReplaySettingsOverlay() => new ReplaySettingsOverlay + //{ + // Anchor = Anchor.TopRight, + // Origin = Anchor.TopRight, + // Margin = new MarginPadding { Top = 100, Right = 10 }, + //}; + + public virtual void BindProcessor(ScoreProcessor processor) + { + ScoreCounter?.Current.BindTo(processor.TotalScore); + AccuracyCounter?.Current.BindTo(processor.Accuracy); + ComboCounter?.Current.BindTo(processor.Combo); + HealthDisplay?.Current.BindTo(processor.Health); + + var shd = HealthDisplay as StandardHealthDisplay; + if (shd != null) + processor.NewJudgement += shd.Flash; + } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 707d026e2b..d4b8445ed9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -170,7 +170,7 @@ namespace osu.Game.Screens.Play HitRenderer, } }, - hudOverlay = new StandardHUDOverlay + hudOverlay = new HUDOverlay { Anchor = Anchor.Centre, Origin = Anchor.Centre diff --git a/osu.Game/Screens/Play/ReplaySettings/CollectionSettings.cs b/osu.Game/Screens/Play/ReplaySettings/CollectionSettings.cs new file mode 100644 index 0000000000..482581abca --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettings/CollectionSettings.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Music; +using System.Collections.Generic; + +namespace osu.Game.Screens.Play.ReplaySettings +{ + public class CollectionSettings : ReplayGroup + { + protected override string Title => @"collections"; + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new OsuSpriteText + { + Text = @"Add current song to", + }, + new CollectionsDropdown<PlaylistCollection> + { + RelativeSizeAxes = Axes.X, + Items = new[] { new KeyValuePair<string, PlaylistCollection>(@"All", PlaylistCollection.All) }, + }, + }; + } + } +} diff --git a/osu.Game/Screens/Play/ReplaySettings/DiscussionSettings.cs b/osu.Game/Screens/Play/ReplaySettings/DiscussionSettings.cs new file mode 100644 index 0000000000..9c4fb03517 --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettings/DiscussionSettings.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Play.ReplaySettings +{ + public class DiscussionSettings : ReplayGroup + { + protected override string Title => @"discussions"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new ReplayCheckbox + { + LabelText = "Show floating comments", + Bindable = config.GetBindable<bool>(OsuSetting.FloatingComments) + }, + new FocusedTextBox + { + RelativeSizeAxes = Axes.X, + Height = 30, + PlaceholderText = "Add Comment", + HoldFocus = false, + }, + }; + } + } +} diff --git a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs new file mode 100644 index 0000000000..7f69d3109c --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Configuration; +using osu.Framework.Graphics; + +namespace osu.Game.Screens.Play.ReplaySettings +{ + public class PlaybackSettings : ReplayGroup + { + protected override string Title => @"playback"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new ReplaySliderBar<double>() + { + LabelText = "Playback speed", + Bindable = config.GetBindable<double>(OsuSetting.PlaybackSpeed) + } + }; + } + } +} diff --git a/osu.Game/Screens/Play/ReplaySettings/ReplayCheckbox.cs b/osu.Game/Screens/Play/ReplaySettings/ReplayCheckbox.cs new file mode 100644 index 0000000000..7ad1e4f527 --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettings/ReplayCheckbox.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Play.ReplaySettings +{ + public class ReplayCheckbox : OsuCheckbox + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Nub.AccentColour = colours.Yellow; + Nub.GlowingAccentColour = colours.YellowLighter; + Nub.GlowColour = colours.YellowDarker; + } + } +} diff --git a/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs b/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs new file mode 100644 index 0000000000..3e4c0dca5c --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettings/ReplayGroup.cs @@ -0,0 +1,132 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +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; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Play.ReplaySettings +{ + public abstract class ReplayGroup : Container + { + /// <summary> + /// The title to be displayed in the header of this group. + /// </summary> + protected abstract string Title { get; } + + private const float transition_duration = 250; + private const int container_width = 270; + private const int border_thickness = 2; + private const int header_height = 30; + private const int corner_radius = 5; + + private readonly FillFlowContainer content; + private readonly IconButton button; + + private bool expanded = true; + + private Color4 buttonActiveColour; + + protected ReplayGroup() + { + AutoSizeAxes = Axes.Y; + Width = container_width; + Masking = true; + CornerRadius = corner_radius; + BorderColour = Color4.Black; + BorderThickness = border_thickness; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.5f, + }, + new FillFlowContainer + { + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Container + { + Name = @"Header", + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Height = header_height, + Children = new Drawable[] + { + new OsuSpriteText + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Text = Title.ToUpper(), + TextSize = 17, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Left = 10 }, + }, + button = new IconButton + { + Origin = Anchor.Centre, + Anchor = Anchor.CentreRight, + Position = new Vector2(-15,0), + Icon = FontAwesome.fa_bars, + Scale = new Vector2(0.75f), + Action = toggleContentVisibility, + }, + } + }, + content = new FillFlowContainer + { + Name = @"Content", + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeDuration = transition_duration, + AutoSizeEasing = EasingTypes.OutQuint, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(15), + Spacing = new Vector2(0, 15), + } + } + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + button.Colour = buttonActiveColour = colours.Yellow; + } + + protected override Container<Drawable> Content => content; + + private void toggleContentVisibility() + { + content.ClearTransforms(); + + expanded = !expanded; + + if (expanded) + content.AutoSizeAxes = Axes.Y; + else + { + content.AutoSizeAxes = Axes.None; + content.ResizeHeightTo(0, transition_duration, EasingTypes.OutQuint); + } + + button.FadeColour(expanded ? buttonActiveColour : Color4.White, 200, EasingTypes.OutQuint); + } + } +} diff --git a/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs b/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs new file mode 100644 index 0000000000..4992c3a1e7 --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics.UserInterface; +using System; +using osu.Game.Graphics; +using osu.Framework.Graphics; +using osu.Game.Overlays.Settings; + +namespace osu.Game.Screens.Play.ReplaySettings +{ + public class ReplaySliderBar<T> : SettingsSlider<T> + where T : struct, IEquatable<T> + { + protected override Drawable CreateControl() => new Sliderbar() + { + Margin = new MarginPadding { Top = 5, Bottom = 5 }, + RelativeSizeAxes = Axes.X + }; + + private class Sliderbar : OsuSliderBar<T> + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.Yellow; + Nub.AccentColour = colours.Yellow; + Nub.GlowingAccentColour = colours.YellowLighter; + Nub.GlowColour = colours.YellowDarker; + } + } + } +} diff --git a/osu.Game/Screens/Play/ReplaySettingsOverlay.cs b/osu.Game/Screens/Play/ReplaySettingsOverlay.cs new file mode 100644 index 0000000000..415f70005d --- /dev/null +++ b/osu.Game/Screens/Play/ReplaySettingsOverlay.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Screens.Play.ReplaySettings; +using OpenTK; + +namespace osu.Game.Screens.Play +{ + public class ReplaySettingsOverlay : FillFlowContainer + { + public ReplaySettingsOverlay() + { + Direction = FillDirection.Vertical; + AutoSizeAxes = Axes.Both; + Spacing = new Vector2(0, 20); + + Add(new CollectionSettings()); + Add(new DiscussionSettings()); + Add(new PlaybackSettings()); + } + } +} diff --git a/osu.Game/Screens/Play/StandardHUDOverlay.cs b/osu.Game/Screens/Play/StandardHUDOverlay.cs deleted file mode 100644 index 87fbea6810..0000000000 --- a/osu.Game/Screens/Play/StandardHUDOverlay.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; -using osu.Game.Rulesets.Scoring; -using osu.Game.Screens.Play.HUD; -using OpenTK; - -namespace osu.Game.Screens.Play -{ - public class StandardHUDOverlay : HUDOverlay - { - protected override RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopRight, - Position = new Vector2(0, 35), - TextSize = 20, - Margin = new MarginPadding { Right = 140 }, - }; - - protected override RollingCounter<int> CreateComboCounter() => new SimpleComboCounter - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopLeft, - Position = new Vector2(0, 35), - Margin = new MarginPadding { Left = 140 }, - TextSize = 20, - }; - - protected override HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay - { - Size = new Vector2(1, 5), - RelativeSizeAxes = Axes.X, - Margin = new MarginPadding { Top = 20 } - }; - - protected override KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection - { - IsCounting = true, - FadeTime = 50, - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Margin = new MarginPadding(10), - Y = - TwoLayerButton.SIZE_RETRACTED.Y, - }; - - protected override ScoreCounter CreateScoreCounter() => new ScoreCounter(6) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - TextSize = 40, - Position = new Vector2(0, 30), - }; - - protected override SongProgress CreateProgress() => new SongProgress - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - }; - - protected override ModDisplay CreateModsContainer() => new ModDisplay - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 20, Right = 10 }, - }; - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - ComboCounter.AccentColour = colours.BlueLighter; - AccuracyCounter.AccentColour = colours.BlueLighter; - ScoreCounter.AccentColour = colours.BlueLighter; - - var shd = HealthDisplay as StandardHealthDisplay; - if (shd != null) - { - shd.AccentColour = colours.BlueLighter; - shd.GlowColour = colours.BlueDarker; - } - } - - public override void BindProcessor(ScoreProcessor processor) - { - base.BindProcessor(processor); - - var shd = HealthDisplay as StandardHealthDisplay; - if (shd != null) - processor.NewJudgement += shd.Flash; - } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e90a462db6..98b87608da 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -74,10 +74,12 @@ <Compile Include="Audio\SampleInfoList.cs" /> <Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" /> <Compile Include="Beatmaps\DifficultyCalculator.cs" /> + <Compile Include="Graphics\UserInterface\IconButton.cs" /> <Compile Include="Configuration\SelectionRandomType.cs" /> <Compile Include="Online\API\Requests\PostMessageRequest.cs" /> <Compile Include="Online\Chat\ErrorMessage.cs" /> <Compile Include="Overlays\Chat\ChatTabControl.cs" /> + <Compile Include="Overlays\Music\CollectionsDropdown.cs" /> <Compile Include="Overlays\Music\FilterControl.cs" /> <Compile Include="Overlays\Music\PlaylistItem.cs" /> <Compile Include="Overlays\Music\PlaylistList.cs" /> @@ -244,11 +246,17 @@ <Compile Include="Screens\Charts\ChartInfo.cs" /> <Compile Include="Screens\Edit\Editor.cs" /> <Compile Include="Screens\Play\HotkeyRetryOverlay.cs" /> + <Compile Include="Screens\Play\ReplaySettings\CollectionSettings.cs" /> + <Compile Include="Screens\Play\ReplaySettings\DiscussionSettings.cs" /> + <Compile Include="Screens\Play\ReplaySettings\ReplayGroup.cs" /> + <Compile Include="Screens\Play\ReplaySettingsOverlay.cs" /> + <Compile Include="Screens\Play\ReplaySettings\ReplaySliderBar.cs" /> + <Compile Include="Screens\Play\ReplaySettings\PlaybackSettings.cs" /> + <Compile Include="Screens\Play\ReplaySettings\ReplayCheckbox.cs" /> <Compile Include="Screens\Play\PauseContainer.cs" /> <Compile Include="Screens\Play\SongProgressInfo.cs" /> <Compile Include="Screens\Play\HUD\ModDisplay.cs" /> <Compile Include="Screens\Play\SquareGraph.cs" /> - <Compile Include="Screens\Play\StandardHUDOverlay.cs" /> <Compile Include="Screens\Ranking\ResultsPage.cs" /> <Compile Include="Screens\Ranking\ResultsPageRanking.cs" /> <Compile Include="Screens\Ranking\ResultsPageScore.cs" /> @@ -438,6 +446,9 @@ <Compile Include="Overlays\Music\PlaylistOverlay.cs" /> <Compile Include="Rulesets\Replays\IAutoGenerator.cs" /> <Compile Include="Rulesets\Replays\AutoGenerator.cs" /> + <Compile Include="Overlays\Chat\ChannelSelectionOverlay.cs" /> + <Compile Include="Overlays\Chat\ChannelListItem.cs" /> + <Compile Include="Overlays\Chat\ChannelSection.cs" /> <Compile Include="Screens\Multiplayer\DrawableRoom.cs" /> <Compile Include="Online\Multiplayer\Room.cs" /> <Compile Include="Online\Multiplayer\RoomStatus.cs" />