diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 983b302de8..4bd50f29f6 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable private void load() { // todo: this should come from the skin. - AccentColour = colourForRrepesentation(HitObject.VisualRepresentation); + AccentColour = colourForRepresentation(HitObject.VisualRepresentation); InternalChildren = new[] { @@ -275,7 +275,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable border.Alpha = (float)MathHelper.Clamp((HitObject.StartTime - Time.Current) / 500, 0, 1); } - private Color4 colourForRrepesentation(FruitVisualRepresentation representation) + private Color4 colourForRepresentation(FruitVisualRepresentation representation) { switch (representation) { diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestCase.cs b/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestCase.cs new file mode 100644 index 0000000000..8c5299e1a2 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestCase.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Timing; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests +{ + public abstract class ManiaSelectionBlueprintTestCase : SelectionBlueprintTestCase + { + [Cached(Type = typeof(IAdjustableClock))] + private readonly IAdjustableClock clock = new StopwatchClock(); + } +} diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs index 993f7520e8..756031a463 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests { - public class TestCaseHoldNoteSelectionBlueprint : SelectionBlueprintTestCase + public class TestCaseHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase { private readonly DrawableHoldNote drawableObject; diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs index 67370be66c..4023f97eb3 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Tests { - public class TestCaseNoteSelectionBlueprint : SelectionBlueprintTestCase + public class TestCaseNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase { private readonly DrawableNote drawableObject; diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs index afeb0a585e..4b78dd68cb 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs @@ -49,7 +49,6 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints base.Update(); Size = HitObject.DrawSize + new Vector2(0, HitObject.Tail.DrawHeight); - Position = Parent.ToLocalSpace(HitObject.ScreenSpaceDrawQuad.TopLeft); // This is a side-effect of not matching the hitobject's anchors/origins, which is kinda hard to do // When scrolling upwards our origin is already at the top of the head note (which is the intended location), diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs index 53f9dd8752..97817d5414 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs @@ -1,23 +1,79 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input.Events; +using osu.Framework.Timing; using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI.Scrolling; +using osuTK; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { public class ManiaSelectionBlueprint : SelectionBlueprint { + protected new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject; + + protected IClock EditorClock { get; private set; } + + [Resolved] + private IScrollingInfo scrollingInfo { get; set; } + public ManiaSelectionBlueprint(DrawableHitObject hitObject) : base(hitObject) { RelativeSizeAxes = Axes.None; } + [BackgroundDependencyLoader] + private void load(IAdjustableClock clock) + { + EditorClock = clock; + } + + protected override void Update() + { + base.Update(); + + Position = Parent.ToLocalSpace(HitObject.ToScreenSpace(Vector2.Zero)); + } + public override void AdjustPosition(DragEvent dragEvent) { + var objectParent = HitObject.Parent; + + // Using the hitobject position is required since AdjustPosition can be invoked multiple times per frame + // without the position having been updated by the parenting ScrollingHitObjectContainer + HitObject.Y += dragEvent.Delta.Y; + + float targetPosition; + + // If we're scrolling downwards, a position of 0 is actually further away from the hit target + // so we need to flip the vertical coordinate in the hitobject container's space + if (scrollingInfo.Direction.Value == ScrollingDirection.Down) + targetPosition = -HitObject.Position.Y; + else + targetPosition = HitObject.Position.Y; + + HitObject.HitObject.StartTime = scrollingInfo.Algorithm.TimeAt(targetPosition, + EditorClock.CurrentTime, + scrollingInfo.TimeRange.Value, + objectParent.DrawHeight); + } + + public override void Show() + { + HitObject.AlwaysAlive = true; + base.Show(); + } + + public override void Hide() + { + HitObject.AlwaysAlive = false; + base.Hide(); } } } diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs index 7df7924c51..440a539412 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs @@ -20,7 +20,6 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints base.Update(); Size = HitObject.DrawSize; - Position = Parent.ToLocalSpace(HitObject.ScreenSpaceDrawQuad.TopLeft); } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 8c96c6dfe7..70ff7b4124 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -12,6 +12,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { public abstract class DrawableManiaHitObject : DrawableHitObject { + /// + /// Whether this should always remain alive. + /// + internal bool AlwaysAlive; + /// /// The which causes this to be hit. /// @@ -34,6 +39,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Direction.BindValueChanged(OnDirectionChanged, true); } + protected override bool ShouldBeAlive => AlwaysAlive || base.ShouldBeAlive; + protected virtual void OnDirectionChanged(ScrollingDirection direction) { Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 2f456f7479..1813501b54 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -137,6 +137,13 @@ namespace osu.Game.Rulesets.Mania.UI HitObjectContainer.Add(hitObject); } + public override void Remove(DrawableHitObject h) + { + h.OnNewResult -= OnNewResult; + + HitObjectContainer.Remove(h); + } + internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result) { if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 85d1c0c4b0..9a816ce7f1 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -52,6 +52,8 @@ namespace osu.Game.Rulesets.Mania.UI public override void Add(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Add(h); + public override void Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h); + public void Add(BarLine barline) => stages.ForEach(s => s.Add(barline)); private ManiaStage getStageByColumn(int column) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs index 73c080ffba..42b292d50b 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs @@ -157,6 +157,15 @@ namespace osu.Game.Rulesets.Mania.UI h.OnNewResult += OnNewResult; } + public override void Remove(DrawableHitObject h) + { + var maniaObject = (ManiaHitObject)h.HitObject; + int columnIndex = maniaObject.Column - firstColumnIndex; + Columns.ElementAt(columnIndex).Remove(h); + + h.OnNewResult -= OnNewResult; + } + public void Add(BarLine barline) => base.Add(new DrawableBarLine(barline)); internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result) diff --git a/osu.Game.Tests/Visual/TestCaseChatLink.cs b/osu.Game.Tests/Visual/TestCaseChatLink.cs index c9bfdea9c4..61c2f47e7d 100644 --- a/osu.Game.Tests/Visual/TestCaseChatLink.cs +++ b/osu.Game.Tests/Visual/TestCaseChatLink.cs @@ -24,6 +24,7 @@ namespace osu.Game.Tests.Visual public class TestCaseChatLink : OsuTestCase { private readonly TestChatLineContainer textContainer; + private readonly DialogOverlay dialogOverlay; private Color4 linkColour; public override IReadOnlyList RequiredTypes => new[] @@ -38,6 +39,7 @@ namespace osu.Game.Tests.Visual public TestCaseChatLink() { + Add(dialogOverlay = new DialogOverlay { Depth = float.MinValue }); Add(textContainer = new TestChatLineContainer { Padding = new MarginPadding { Left = 20, Right = 20 }, @@ -59,6 +61,7 @@ namespace osu.Game.Tests.Visual Dependencies.Cache(chatManager); Dependencies.Cache(new ChatOverlay()); + Dependencies.Cache(dialogOverlay); testLinksGeneral(); testEcho(); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 9ac2cabe9f..8975ab8a0e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -42,6 +42,8 @@ namespace osu.Game.Configuration if (!val) Set(OsuSetting.SavePassword, false); }; + Set(OsuSetting.ExternalLinkWarning, true); + // Audio Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01); @@ -148,6 +150,7 @@ namespace osu.Game.Configuration BeatmapSkins, BeatmapHitsounds, IncreaseFirstObjectVisibility, - ScoreDisplayMode + ScoreDisplayMode, + ExternalLinkWarning } } diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 5c8fddc342..54a2ea47f9 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; using System.Collections.Generic; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -24,14 +23,12 @@ namespace osu.Game.Graphics.Containers private OsuGame game; private ChannelManager channelManager; private Action showNotImplementedError; - private GameHost host; [BackgroundDependencyLoader(true)] - private void load(OsuGame game, NotificationOverlay notifications, GameHost host, ChannelManager channelManager) + private void load(OsuGame game, NotificationOverlay notifications, ChannelManager channelManager) { // will be null in tests this.game = game; - this.host = host; this.channelManager = channelManager; showNotImplementedError = () => notifications?.Post(new SimpleNotification @@ -98,7 +95,7 @@ namespace osu.Game.Graphics.Containers showNotImplementedError?.Invoke(); break; case LinkAction.External: - host.OpenUrlExternally(url); + game?.OpenUrlExternally(url); break; case LinkAction.OpenUserProfile: if (long.TryParse(linkArgument, out long userId)) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a275f99994..29f971078b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -274,11 +274,13 @@ namespace osu.Game.Online.Chat { Channel found = null; - var available = AvailableChannels.FirstOrDefault(c => c.Id == lookup.Id); + bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : lookup.Name == ch.Name; + + var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) found = available; - var joined = JoinedChannels.FirstOrDefault(c => c.Id == lookup.Id); + var joined = JoinedChannels.FirstOrDefault(lookupCondition); if (found == null && joined != null) found = joined; diff --git a/osu.Game/Online/Chat/ExternalLinkOpener.cs b/osu.Game/Online/Chat/ExternalLinkOpener.cs new file mode 100644 index 0000000000..d8b8adbbad --- /dev/null +++ b/osu.Game/Online/Chat/ExternalLinkOpener.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Platform; +using osu.Game.Configuration; +using osu.Game.Overlays; +using osu.Game.Overlays.Chat; + +namespace osu.Game.Online.Chat +{ + public class ExternalLinkOpener : Component + { + private GameHost host; + private DialogOverlay dialogOverlay; + private Bindable externalLinkWarning; + + [BackgroundDependencyLoader(true)] + private void load(GameHost host, DialogOverlay dialogOverlay, OsuConfigManager config) + { + this.host = host; + this.dialogOverlay = dialogOverlay; + externalLinkWarning = config.GetBindable(OsuSetting.ExternalLinkWarning); + } + + public void OpenUrlExternally(string url) + { + if (externalLinkWarning) + dialogOverlay.Push(new ExternalLinkDialog(url, () => host.OpenUrlExternally(url))); + else + host.OpenUrlExternally(url); + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4a358da227..1b0a0b2210 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -50,7 +50,9 @@ namespace osu.Game { public Toolbar Toolbar; - private ChatOverlay chat; + private ChatOverlay chatOverlay; + + private ChannelManager channelManager; private MusicController musicController; @@ -179,6 +181,9 @@ namespace osu.Game LocalConfig.BindWith(OsuSetting.VolumeInactive, inactiveVolumeAdjust); } + private ExternalLinkOpener externalLinkOpener; + public void OpenUrlExternally(string url) => externalLinkOpener.OpenUrlExternally(url); + private ScheduledDelegate scoreLoad; /// @@ -338,12 +343,8 @@ namespace osu.Game //overlay elements loadComponentSingleFile(direct = new DirectOverlay { Depth = -1 }, mainContent.Add); loadComponentSingleFile(social = new SocialOverlay { Depth = -1 }, mainContent.Add); - loadComponentSingleFile(new ChannelManager(), channelManager => - { - dependencies.Cache(channelManager); - AddInternal(channelManager); - }); - loadComponentSingleFile(chat = new ChatOverlay { Depth = -1 }, mainContent.Add); + loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal); + loadComponentSingleFile(chatOverlay = new ChatOverlay { Depth = -1 }, mainContent.Add); loadComponentSingleFile(settings = new MainSettings { GetToolbarHeight = () => ToolbarOffset, @@ -376,13 +377,16 @@ namespace osu.Game dependencies.Cache(onscreenDisplay); dependencies.Cache(social); dependencies.Cache(direct); - dependencies.Cache(chat); + dependencies.Cache(chatOverlay); + dependencies.Cache(channelManager); dependencies.Cache(userProfile); dependencies.Cache(musicController); dependencies.Cache(beatmapSetOverlay); dependencies.Cache(notifications); dependencies.Cache(dialogOverlay); + Add(externalLinkOpener = new ExternalLinkOpener()); + var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications }; overlays.AddRange(singleDisplaySideOverlays); @@ -409,7 +413,7 @@ namespace osu.Game } // ensure only one of these overlays are open at once. - var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct }; + var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, social, direct }; overlays.AddRange(singleDisplayOverlays); foreach (var overlay in singleDisplayOverlays) @@ -534,7 +538,7 @@ namespace osu.Game switch (action) { case GlobalAction.ToggleChat: - chat.ToggleVisibility(); + chatOverlay.ToggleVisibility(); return true; case GlobalAction.ToggleSocial: social.ToggleVisibility(); diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 5aff50a68a..6294851415 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -139,7 +139,7 @@ namespace osu.Game.Overlays var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); req.Success += res => { - ShowBeatmapSet(res.ToBeatmapSet(rulesets)); + BeatmapSet = res.ToBeatmapSet(rulesets); header.Picker.Beatmap.Value = header.BeatmapSet.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId); }; api.Queue(req); @@ -150,7 +150,7 @@ namespace osu.Game.Overlays { BeatmapSet = null; var req = new GetBeatmapSetRequest(beatmapSetId); - req.Success += res => ShowBeatmapSet(res.ToBeatmapSet(rulesets)); + req.Success += res => BeatmapSet = res.ToBeatmapSet(rulesets); api.Queue(req); Show(); } diff --git a/osu.Game/Overlays/Chat/ExternalLinkDialog.cs b/osu.Game/Overlays/Chat/ExternalLinkDialog.cs new file mode 100644 index 0000000000..b3f7b282a9 --- /dev/null +++ b/osu.Game/Overlays/Chat/ExternalLinkDialog.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Overlays.Chat +{ + public class ExternalLinkDialog : PopupDialog + { + public ExternalLinkDialog(string url, Action openExternalLinkAction) + { + HeaderText = "Just checking..."; + BodyText = $"You are about to leave osu! and open the following link in a web browser:\n\n{url}"; + + Icon = FontAwesome.fa_warning; + + Buttons = new PopupDialogButton[] + { + new PopupDialogOkButton + { + Text = @"Yes. Go for it.", + Action = openExternalLinkAction + }, + new PopupDialogCancelButton + { + Text = @"No! Abort mission!" + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 3100266c6f..ca921b7882 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -7,12 +7,10 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; using osuTK; using osuTK.Graphics; @@ -35,7 +33,7 @@ namespace osu.Game.Overlays.Dialog private readonly Container ring; private readonly FillFlowContainer buttonsContainer; private readonly SpriteIcon icon; - private readonly SpriteText header; + private readonly TextFlowContainer header; private readonly TextFlowContainer body; private bool actionInvoked; @@ -46,10 +44,19 @@ namespace osu.Game.Overlays.Dialog set => icon.Icon = value; } + private string text; + public string HeaderText { - get => header.Text; - set => header.Text = value; + get => text; + set + { + if (text == value) + return; + text = value; + + header.Text = value; + } } public string BodyText @@ -164,18 +171,20 @@ namespace osu.Game.Overlays.Dialog }, }, }, - header = new OsuSpriteText + header = new OsuTextFlowContainer(t => t.TextSize = 25) { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - TextSize = 25, - Shadow = true, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(15), + TextAnchor = Anchor.TopCentre, }, body = new OsuTextFlowContainer(t => t.TextSize = 18) { - Padding = new MarginPadding(15), RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(15), TextAnchor = Anchor.TopCentre, }, }, diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index dfac007ed9..58e03bd0cd 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -406,6 +406,10 @@ namespace osu.Game.Overlays { base.PopOut(); + // This is here mostly as a performance fix. + // If the playlist is not hidden it will update children even when the music controller is hidden (due to AlwaysPresent). + playlist.State = Visibility.Hidden; + this.FadeOut(transition_length, Easing.OutQuint); dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint); } diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs new file mode 100644 index 0000000000..62e307f323 --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// 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; + +namespace osu.Game.Overlays.Settings.Sections.Online +{ + public class WebSettings : SettingsSubsection + { + protected override string Header => "Web"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new SettingsCheckbox + { + LabelText = "Warn about opening external links", + Bindable = config.GetBindable(OsuSetting.ExternalLinkWarning) + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs index 28cb503288..3a2e52d2eb 100644 --- a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs +++ b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Overlays.Settings.Sections.Online; namespace osu.Game.Overlays.Settings.Sections { @@ -15,6 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections { Children = new Drawable[] { + new WebSettings() }; } } diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index c249651f98..c67ed5b845 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -228,15 +228,19 @@ namespace osu.Game.Overlays.Volume public void Decrease(double amount = 1, bool isPrecise = false) => adjust(-amount, isPrecise); // because volume precision is set to 0.01, this local is required to keep track of more precise adjustments and only apply when possible. - private double adjustAccumulator; + private double scrollAccumulation; private void adjust(double delta, bool isPrecise) { - adjustAccumulator += delta * adjust_step * (isPrecise ? 0.1 : 1); - if (Math.Abs(adjustAccumulator) < Bindable.Precision) - return; - Volume += adjustAccumulator; - adjustAccumulator = 0; + scrollAccumulation += delta * adjust_step * (isPrecise ? 0.1 : 1); + + var precision = Bindable.Precision; + + while (Math.Abs(scrollAccumulation) > precision) + { + Volume += Math.Sign(scrollAccumulation) * precision; + scrollAccumulation = scrollAccumulation < 0 ? Math.Min(0, scrollAccumulation + precision) : Math.Max(0, scrollAccumulation - precision); + } } protected override bool OnScroll(ScrollEvent e) diff --git a/osu.Game/Rulesets/Edit/EditRulesetContainer.cs b/osu.Game/Rulesets/Edit/EditRulesetContainer.cs index bc54c907ab..8bb174c65c 100644 --- a/osu.Game/Rulesets/Edit/EditRulesetContainer.cs +++ b/osu.Game/Rulesets/Edit/EditRulesetContainer.cs @@ -91,8 +91,8 @@ namespace osu.Game.Rulesets.Edit // Process the beatmap var processor = ruleset.CreateBeatmapProcessor(beatmap); - processor.PreProcess(); - processor.PostProcess(); + processor?.PreProcess(); + processor?.PostProcess(); // Remove visual representation var drawableObject = Playfield.AllHitObjects.Single(d => d.HitObject == hitObject); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 0be15de7f4..c4fb9dc419 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osuTK.Graphics; using osu.Framework.Screens; using osu.Game.Screens.Backgrounds; @@ -181,12 +182,24 @@ namespace osu.Game.Screens.Edit LoadComponentAsync(currentScreen, screenContainer.Add); } + private double scrollAccumulation; + protected override bool OnScroll(ScrollEvent e) { - if (e.ScrollDelta.X + e.ScrollDelta.Y > 0) - clock.SeekBackward(!clock.IsRunning); - else - clock.SeekForward(!clock.IsRunning); + scrollAccumulation += (e.ScrollDelta.X + e.ScrollDelta.Y) * (e.IsPrecise ? 0.1 : 1); + + const int precision = 1; + + while (Math.Abs(scrollAccumulation) > precision) + { + if (scrollAccumulation > 0) + clock.SeekBackward(!clock.IsRunning); + else + clock.SeekForward(!clock.IsRunning); + + scrollAccumulation = scrollAccumulation < 0 ? Math.Min(0, scrollAccumulation + precision) : Math.Max(0, scrollAccumulation - precision); + } + return true; } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 4a677001a0..0748f68dca 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -310,9 +310,9 @@ namespace osu.Game.Screens.Select.Leaderboards currentPlaceholder = placeholder; } - protected override void Update() + protected override void UpdateAfterChildren() { - base.Update(); + base.UpdateAfterChildren(); var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight; diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 345400305c..d6882282e6 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -43,7 +43,7 @@ WARNING DO_NOT_SHOW WARNING - WARNING + HINT HINT HINT ERROR