diff --git a/osu-framework b/osu-framework index 991177da4f..2a3b245da9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 991177da4fbed2dd8260c215f2d341ebc858b03e +Subproject commit 2a3b245da9eff604be09d473203f829690d2808c diff --git a/osu.Game/Beatmaps/IO/OszArchiveReader.cs b/osu.Game/Beatmaps/IO/OszArchiveReader.cs index eb9e740779..a22a5f4cce 100644 --- a/osu.Game/Beatmaps/IO/OszArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/OszArchiveReader.cs @@ -15,7 +15,7 @@ namespace osu.Game.Beatmaps.IO AddReader((storage, path) => { using (var stream = storage.GetStream(path)) - return ZipFile.IsZipFile(stream, false); + return stream != null && ZipFile.IsZipFile(stream, false); }); OsuLegacyDecoder.Register(); } diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index efd5631077..43769f67b5 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -144,7 +144,11 @@ namespace osu.Game.Database public void Import(params string[] paths) { foreach (string p in paths) - Import(p); + { + //In case the file was imported twice and deleted after the first time + if (File.Exists(p)) + Import(p); + } } /// @@ -178,6 +182,8 @@ namespace osu.Game.Database if (existing != null) { + GetChildren(existing); + if (existing.DeletePending) { existing.DeletePending = false; diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index 7608a366dc..44d176f4d9 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -83,6 +83,8 @@ namespace osu.Game.Graphics.Cursor protected override void PopIn() { instantMovement |= !IsPresent; + + ClearTransforms(); FadeIn(500, EasingTypes.OutQuint); } diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index c59a589fba..1756c640b0 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -8,6 +8,8 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Graphics.Effects; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; namespace osu.Game.Overlays.Chat @@ -54,15 +56,6 @@ namespace osu.Game.Overlays.Chat OsuColour.FromHex("992861"), }; - private Color4 getUsernameColour(Message message) - { - if (!string.IsNullOrEmpty(message.Sender?.Colour)) - return OsuColour.FromHex(message.Sender.Colour); - - //todo: use User instead of Message when user_id is correctly populated. - return username_colours[message.UserId % username_colours.Length]; - } - public const float LEFT_PADDING = message_padding + padding * 2; private const float padding = 15; @@ -70,6 +63,7 @@ namespace osu.Game.Overlays.Chat private const float text_size = 20; private UserProfileOverlay profileOverlay; + private Color4 customUsernameColour; public ChatLine(Message message) { @@ -79,13 +73,67 @@ namespace osu.Game.Overlays.Chat AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Left = padding, Right = padding }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + customUsernameColour = colours.ChatBlue; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + bool hasBackground = !string.IsNullOrEmpty(Message.Sender.Colour); + Drawable username = new OsuSpriteText + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + Font = @"Exo2.0-BoldItalic", + Text = $@"{Message.Sender.Username}" + (hasBackground ? "" : ":"), + Colour = hasBackground ? customUsernameColour : username_colours[Message.UserId % username_colours.Length], + TextSize = text_size, + }; + + if (hasBackground) + { + // Background effect + username = username.WithEffect(new EdgeEffect + { + CornerRadius = 4, + Parameters = new EdgeEffectParameters + { + Radius = 1, + Colour = OsuColour.FromHex(Message.Sender.Colour), + Type = EdgeEffectType.Shadow, + } + }, d => + { + d.Padding = new MarginPadding { Left = 3, Right = 3, Bottom = 1, Top = -3 }; + d.Y = 3; + }) + // Drop shadow effect + .WithEffect(new EdgeEffect + { + CornerRadius = 4, + Parameters = new EdgeEffectParameters + { + Roundness = 1, + Offset = new Vector2(0, 3), + Radius = 3, + Colour = Color4.Black.Opacity(0.3f), + Type = EdgeEffectType.Shadow, + } + }); + } Children = new Drawable[] { new Container { Size = new Vector2(message_padding, text_size), - Children = new Drawable[] + Children = new[] { new OsuSpriteText { @@ -102,13 +150,7 @@ namespace osu.Game.Overlays.Chat AutoSizeAxes = Axes.Both, Origin = Anchor.TopRight, Anchor = Anchor.TopRight, - Child = new OsuSpriteText - { - Font = @"Exo2.0-BoldItalic", - Text = $@"{Message.Sender.Username}:", - Colour = getUsernameColour(Message), - TextSize = text_size, - }, + Child = username Action = () => profileOverlay?.ShowUser(Message.Sender), }, } diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index e51f931959..8a2fa95ed1 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -29,6 +29,9 @@ namespace osu.Game.Overlays.Chat scroll = new OsuScrollContainer { RelativeSizeAxes = Axes.Both, + // Some chat lines have effects that slightly protrude to the bottom, + // which we do not want to mask away, hence the padding. + Padding = new MarginPadding { Bottom = 5 }, Children = new Drawable[] { flow = new FillFlowContainer diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 700889ed26..1f9f7e57ca 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -111,7 +111,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { - Bottom = textbox_height + padding + Bottom = textbox_height }, }, new Container diff --git a/osu.Game/Overlays/DragBar.cs b/osu.Game/Overlays/DragBar.cs deleted file mode 100644 index 89bb81c70b..0000000000 --- a/osu.Game/Overlays/DragBar.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Input; -using OpenTK; -using osu.Framework.Graphics.Shapes; - -namespace osu.Game.Overlays -{ - public class DragBar : Container - { - protected readonly Container Fill; - - public Action SeekRequested; - - public bool IsSeeking { get; private set; } - - private bool enabled = true; - public bool IsEnabled - { - get { return enabled; } - set - { - enabled = value; - if (!enabled) - Fill.Width = 0; - } - } - - public DragBar() - { - RelativeSizeAxes = Axes.X; - - Children = new Drawable[] - { - Fill = new Container - { - Name = "FillContainer", - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Both, - Width = 0, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both - } - } - } - }; - } - - public void UpdatePosition(float position) - { - if (IsSeeking || !IsEnabled) return; - - updatePosition(position, false); - } - - private void seek(InputState state) - { - float seekLocation = state.Mouse.Position.X / DrawWidth; - - if (!IsEnabled) return; - - SeekRequested?.Invoke(seekLocation); - updatePosition(seekLocation); - } - - private void updatePosition(float position, bool easing = true) - { - position = MathHelper.Clamp(position, 0, 1); - Fill.TransformTo(position, easing ? 200 : 0, EasingTypes.OutQuint, new TransformSeek()); - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - seek(state); - return true; - } - - protected override bool OnDrag(InputState state) - { - seek(state); - return true; - } - - protected override bool OnDragStart(InputState state) => IsSeeking = true; - - protected override bool OnDragEnd(InputState state) - { - IsSeeking = false; - return true; - } - - private class TransformSeek : TransformFloat - { - public override void Apply(Drawable d) => d.Width = CurrentValue; - public override void ReadIntoStartValue(Drawable d) => StartValue = d.Width; - } - } -} diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index baf58ae26c..0da425652a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -14,6 +14,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Localisation; using osu.Game.Beatmaps; @@ -39,7 +40,7 @@ namespace osu.Game.Overlays private const float bottom_black_area_height = 55; private Drawable currentBackground; - private DragBar progressBar; + private ProgressBar progressBar; private IconButton playButton; private IconButton playlistButton; @@ -187,13 +188,13 @@ namespace osu.Game.Overlays }, } }, - progressBar = new DragBar + progressBar = new ProgressBar { Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, Height = progress_height, - Colour = colours.Yellow, - SeekRequested = seek + FillColour = colours.Yellow, + OnSeek = progress => current?.Track.Seek(progress) } }, }, @@ -228,7 +229,9 @@ namespace osu.Game.Overlays { var track = current.Track; - progressBar.UpdatePosition(track.Length == 0 ? 0 : (float)(track.CurrentTime / track.Length)); + progressBar.EndTime = track.Length; + progressBar.CurrentTime = track.CurrentTime; + playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; if (track.HasCompleted && !track.Looping) next(); @@ -274,13 +277,11 @@ namespace osu.Game.Overlays private void beatmapChanged(WorkingBeatmap beatmap) { - progressBar.IsEnabled = beatmap != null; - TransformDirection direction = TransformDirection.None; if (current != null) { - bool audioEquals = beatmapBacking.Value?.BeatmapInfo?.AudioEquals(current.BeatmapInfo) ?? false; + bool audioEquals = beatmap?.BeatmapInfo?.AudioEquals(current.BeatmapInfo) ?? false; if (audioEquals) direction = TransformDirection.None; @@ -293,15 +294,18 @@ namespace osu.Game.Overlays { //figure out the best direction based on order in playlist. var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo.ID).Count(); - var next = beatmapBacking.Value == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmapBacking.Value.BeatmapSetInfo.ID).Count(); + var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo.ID).Count(); direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } } - current = beatmapBacking.Value; + current = beatmap; + + progressBar.CurrentTime = 0; + + updateDisplay(current, direction); - updateDisplay(beatmapBacking, direction); queuedDirection = null; } @@ -360,12 +364,6 @@ namespace osu.Game.Overlays }); } - private void seek(float position) - { - var track = current?.Track; - track?.Seek(track.Length * position); - } - protected override void PopIn() { base.PopIn(); @@ -426,5 +424,49 @@ namespace osu.Game.Overlays sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); } } + + private class ProgressBar : SliderBar + { + public Action OnSeek; + + private readonly Box fill; + + public Color4 FillColour + { + set { fill.Colour = value; } + } + + public double EndTime + { + set { CurrentNumber.MaxValue = value; } + } + + public double CurrentTime + { + set { CurrentNumber.Value = value; } + } + + public ProgressBar() + { + CurrentNumber.MinValue = 0; + CurrentNumber.MaxValue = 1; + RelativeSizeAxes = Axes.X; + + Children = new Drawable[] + { + fill = new Box + { + RelativeSizeAxes = Axes.Y + } + }; + } + + protected override void UpdateValue(float value) + { + fill.Width = value * UsableWidth; + } + + protected override void OnUserChange() => OnSeek?.Invoke(Current); + } } } diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 5a2e0a7b12..42d435ef88 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -28,6 +28,8 @@ namespace osu.Game.Screens.Menu private readonly BackgroundScreenDefault background; private Screen songSelect; + private readonly MenuSideFlashes sideFlashes; + protected override BackgroundScreen CreateBackground() => background; public MainMenu() @@ -49,10 +51,10 @@ namespace osu.Game.Screens.Menu OnSolo = delegate { Push(consumeSongSelect()); }, OnMulti = delegate { Push(new Lobby()); }, OnExit = delegate { Exit(); }, - }, - new MenuSideFlashes(), + } } - } + }, + sideFlashes = new MenuSideFlashes(), }; } @@ -112,6 +114,8 @@ namespace osu.Game.Screens.Menu Content.FadeOut(length, EasingTypes.InSine); Content.MoveTo(new Vector2(-800, 0), length, EasingTypes.InSine); + + sideFlashes.FadeOut(length / 4, EasingTypes.OutQuint); } protected override void OnResuming(Screen last) @@ -129,6 +133,8 @@ namespace osu.Game.Screens.Menu Content.FadeIn(length, EasingTypes.OutQuint); Content.MoveTo(new Vector2(0, 0), length, EasingTypes.OutQuint); + + sideFlashes.FadeIn(length / 4, EasingTypes.InQuint); } protected override bool OnExiting(Screen next) diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index e5b18292ab..ea91089aa4 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -12,7 +12,6 @@ using System.Linq; using osu.Framework.Timing; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; - namespace osu.Game.Screens.Play { public class SongProgress : OverlayContainer @@ -50,6 +49,9 @@ namespace osu.Game.Screens.Play info.StartTime = firstHitTime; info.EndTime = lastHitTime; + + bar.StartTime = firstHitTime; + bar.EndTime = lastHitTime; } } @@ -89,10 +91,7 @@ namespace osu.Game.Screens.Play Alpha = 0, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - SeekRequested = delegate (float position) - { - OnSeek?.Invoke(firstHitTime + position * (lastHitTime - firstHitTime)); - }, + OnSeek = position => OnSeek?.Invoke(position), }, }; } @@ -144,11 +143,12 @@ namespace osu.Game.Screens.Play if (objects == null) return; - double progress = ((audioClock?.CurrentTime ?? Time.Current) - firstHitTime) / (lastHitTime - firstHitTime); + double position = audioClock?.CurrentTime ?? Time.Current; + double progress = (position - firstHitTime) / (lastHitTime - firstHitTime); if (progress < 1) { - bar.UpdatePosition((float)progress); + bar.CurrentTime = position; graph.Progress = (int)(graph.ColumnCount * progress); } } diff --git a/osu.Game/Screens/Play/SongProgressBar.cs b/osu.Game/Screens/Play/SongProgressBar.cs index 730cf471da..7fabf2e80e 100644 --- a/osu.Game/Screens/Play/SongProgressBar.cs +++ b/osu.Game/Screens/Play/SongProgressBar.cs @@ -1,74 +1,117 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using OpenTK.Graphics; -using osu.Game.Overlays; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; namespace osu.Game.Screens.Play { - public class SongProgressBar : DragBar + public class SongProgressBar : SliderBar { + public Action OnSeek; + + private readonly Box fill; + private readonly Container handleBase; + public Color4 FillColour { - get { return Fill.Colour; } - set { Fill.Colour = value; } + set { fill.Colour = value; } + } + + public double StartTime + { + set { CurrentNumber.MinValue = value; } + } + + public double EndTime + { + set { CurrentNumber.MaxValue = value; } + } + + public double CurrentTime + { + set { CurrentNumber.Value = value; } } public SongProgressBar(float barHeight, float handleBarHeight, Vector2 handleSize) { + CurrentNumber.MinValue = 0; + CurrentNumber.MaxValue = 1; + + RelativeSizeAxes = Axes.X; Height = barHeight + handleBarHeight + handleSize.Y; - Fill.RelativeSizeAxes = Axes.X; - Fill.Height = barHeight; - - Add(new Box + Children = new Drawable[] { - Name = "Background", - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = barHeight, - Colour = Color4.Black, - Alpha = 0.5f, - Depth = 1 - }); - - Fill.Add(new Container - { - Origin = Anchor.BottomRight, - Anchor = Anchor.BottomRight, - Width = 2, - Height = barHeight + handleBarHeight, - Colour = Color4.White, - Position = new Vector2(2, 0), - Children = new Drawable[] + new Box { - new Box + Name = "Background", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = barHeight, + Colour = Color4.Black, + Alpha = 0.5f, + Depth = 1, + }, + fill = new Box + { + Name = "Fill", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Height = barHeight, + }, + handleBase = new Container + { + Name = "HandleBar container", + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Width = 2, + Height = barHeight + handleBarHeight, + Colour = Color4.White, + Position = new Vector2(2, 0), + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - }, - new Container - { - Origin = Anchor.BottomCentre, - Anchor = Anchor.TopCentre, - Size = handleSize, - CornerRadius = 5, - Masking = true, - Children = new Drawable[] + new Box { - new Box + Name = "HandleBar box", + RelativeSizeAxes = Axes.Both, + }, + new Container + { + Name = "Handle container", + Origin = Anchor.BottomCentre, + Anchor = Anchor.TopCentre, + Size = handleSize, + CornerRadius = 5, + Masking = true, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White + new Box + { + Name = "Handle box", + RelativeSizeAxes = Axes.Both, + Colour = Color4.White + } } } } } - }); + }; } + + protected override void UpdateValue(float value) + { + var xFill = value * UsableWidth; + fill.Width = xFill; + handleBase.MoveToX(xFill); + } + + protected override void OnUserChange() => OnSeek?.Invoke(Current); } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 90f18499bf..68f239fb0a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -330,21 +330,19 @@ namespace osu.Game.Screens.Select if (beatmap.Equals(Beatmap?.BeatmapInfo)) return; - bool beatmapSetChange = false; + bool preview = beatmap.BeatmapSetInfoID != Beatmap?.BeatmapInfo.BeatmapSetInfoID; + if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID) sampleChangeDifficulty.Play(); else - { sampleChangeBeatmap.Play(); - beatmapSetChange = true; - } selectionChangeNoBounce = beatmap; selectionChangedDebounce = Scheduler.AddDelayed(delegate { Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); - ensurePlayingSelected(beatmapSetChange); + ensurePlayingSelected(preview); }, 100); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 55b0ee3348..42b5765a6d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -230,7 +230,6 @@ - @@ -539,4 +538,4 @@ --> - \ No newline at end of file +