From 870ce8868cf3955754c266cec0da8fc754a91019 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 16:07:33 +0900 Subject: [PATCH 01/27] Make scrollabletimeline use gridcontainer --- .../Visual/TestCaseEditorComposeTimeline.cs | 3 +- .../Compose/Timeline/ScrollableTimeline.cs | 135 +++++++++--------- 2 files changed, 70 insertions(+), 68 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index d15ee32d8d..0e7ba5c900 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -34,7 +34,8 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(1000, 100) + RelativeSizeAxes = Axes.X, + Size = new Vector2(0.8f, 100) } }; } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c308b2b9f8..9ce4830e5a 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -33,82 +33,90 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("111") }, - new FillFlowContainer + new GridContainer { RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new Drawable[] + Content = new[] { - new Container + new Drawable[] { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] + new Container { - new Box + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222") - }, - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Y, - Width = 160, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 4), - Children = new[] + new Box { - hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, - hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, - waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } + } } } - } - }, - new Container - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] + }, + new Container { - new Box + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("333") - }, - new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Masking = true, - Children = new[] + new Box { - new TimelineButton + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Masking = true, + Children = new[] { - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_plus, - Action = () => timelineContainer.Zoom++ - }, - new TimelineButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_minus, - Action = () => timelineContainer.Zoom-- - }, + new TimelineButton + { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_plus, + // Action = () => timelineContainer.Zoom++ + }, + new TimelineButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_minus, + // Action = () => timelineContainer.Zoom-- + }, + } } } - } + }, + timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Both } }, - timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y } + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed), } } }; @@ -120,12 +128,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline timelineContainer.Beatmap.BindTo(Beatmap); timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); } - - protected override void Update() - { - base.Update(); - - timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); - } } } From e7aa1d9c38c500741ceb1da086a6aa73a5211c07 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 16:12:21 +0900 Subject: [PATCH 02/27] Temporarily remove zoom levels, simplify scrollingtimelinecontainer --- .../Timeline/ScrollingTimelineContainer.cs | 107 +----------------- 1 file changed, 3 insertions(+), 104 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index f71607a6cf..5195a85eac 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -1,12 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -14,8 +11,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ScrollingTimelineContainer : ScrollContainer { - public readonly Bindable HitObjectsVisible = new Bindable(); - public readonly Bindable HitSoundsVisible = new Bindable(); public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); @@ -26,6 +21,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Masking = true; + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + Add(waveform = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, @@ -33,107 +31,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Depth = float.MaxValue }); - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; - - Zoom = 10; - } - - private float minZoom = 1; - /// - /// The minimum zoom level allowed. - /// - public float MinZoom - { - get { return minZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (minZoom == value) - return; - minZoom = value; - - // Update the zoom level - Zoom = Zoom; - } - } - - private float maxZoom = 30; - /// - /// The maximum zoom level allowed. - /// - public float MaxZoom - { - get { return maxZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (maxZoom == value) - return; - maxZoom = value; - - // Update the zoom level - Zoom = Zoom; - } - } - - private float zoom = 1; - /// - /// The current zoom level. - /// - public float Zoom - { - get { return zoom; } - set - { - value = MathHelper.Clamp(value, MinZoom, MaxZoom); - if (zoom == value) - return; - zoom = value; - - // Make the zoom target default to the center of the graph if it hasn't been set - if (relativeContentZoomTarget == null) - relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X; - if (localZoomTarget == null) - localZoomTarget = DrawSize.X / 2; - - Content.ResizeWidthTo(Zoom); - - // Update the scroll position to focus on the zoom target - float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value; - ScrollTo(scrollPos, false); - - relativeContentZoomTarget = null; - localZoomTarget = null; - } - } - - /// - /// Zoom target as a relative position in the space. - /// - private float? relativeContentZoomTarget; - - /// - /// Zoom target as a position in our local space. - /// - private float? localZoomTarget; - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X; - - Zoom += state.Mouse.WheelDelta; - - return true; } private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); From 9bb3e56bb3a22875f746175fee15640489713232 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 17:05:38 +0900 Subject: [PATCH 03/27] Implement half-width overflows --- .../Timeline/ScrollingTimelineContainer.cs | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 5195a85eac..e031e354db 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); + private readonly Container waveformContainer; private readonly BeatmapWaveformGraph waveform; public ScrollingTimelineContainer() @@ -21,20 +22,31 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Masking = true; - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - - Add(waveform = new BeatmapWaveformGraph + Child = waveformContainer = new Container { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue - }); + RelativeSizeAxes = Axes.Y, + Child = waveform = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue + } + }; waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; } + private float zoom = 10; + + protected override void Update() + { + base.Update(); + + waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + waveformContainer.Width = DrawWidth * zoom; + } + private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From e3af32ad2f0f581d56ce09c30849a632e6e830b7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 17:07:41 +0900 Subject: [PATCH 04/27] A bit of cleanup --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index e031e354db..07896d63be 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -34,7 +34,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; waveform.Beatmap.BindTo(Beatmap); - WaveformVisible.ValueChanged += waveformVisibilityChanged; + + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } private float zoom = 10; @@ -46,7 +47,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; waveformContainer.Width = DrawWidth * zoom; } - - private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From 074dee3a83a9d456378a91518f4daa8bb9b26e40 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 18:37:51 +0900 Subject: [PATCH 05/27] Re-implement mousewheel zoom --- .../Timeline/ScrollingTimelineContainer.cs | 73 +++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 07896d63be..e4b19fc2c5 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -4,8 +4,12 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Graphics; +using OpenTK; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { @@ -15,13 +19,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable Beatmap = new Bindable(); private readonly Container waveformContainer; - private readonly BeatmapWaveformGraph waveform; + + private float currentZoom = 10; public ScrollingTimelineContainer() : base(Direction.Horizontal) { Masking = true; + BeatmapWaveformGraph waveform; Child = waveformContainer = new Container { RelativeSizeAxes = Axes.Y, @@ -34,18 +40,75 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; waveform.Beatmap.BindTo(Beatmap); - + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } - private float zoom = 10; - protected override void Update() { base.Update(); waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - waveformContainer.Width = DrawWidth * zoom; + waveformContainer.Width = DrawWidth * currentZoom; + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, waveformContainer.ToLocalSpace(state.Mouse.NativeState.Position).X); + return true; + } + + private float zoomTarget = 10; + private void setZoomTarget(float newZoom, float focusPoint) + { + zoomTarget = MathHelper.Clamp(newZoom, 1, 60); + transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + } + + private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing)); + + private class TransformZoom : Transform + { + private readonly float focusPoint; + private readonly float focusSize; + private readonly float sizeReference; + private readonly float scrollOffset; + + public TransformZoom(float focusPoint, float focusSize, float sizeReference, float scrollOffset) + { + this.focusPoint = focusPoint; + this.focusSize = focusSize; + this.sizeReference = sizeReference; + this.scrollOffset = scrollOffset; + } + + public override string TargetMember => nameof(currentZoom); + + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + protected override void Apply(ScrollingTimelineContainer d, double time) + { + float newZoom = valueAt(time); + + float focusOffset = focusPoint - scrollOffset; + float expectedWidth = sizeReference * newZoom; + float targetOffset = expectedWidth * (focusPoint / focusSize) - focusOffset; + + d.currentZoom = newZoom; + d.ScrollTo(targetOffset, false); + } + + protected override void ReadIntoStartValue(ScrollingTimelineContainer d) => StartValue = d.currentZoom; } } } From eff5eddbe97dac18b954d81aa32542988ab1e822 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 18:41:22 +0900 Subject: [PATCH 06/27] Make zoom an int again --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index e4b19fc2c5..5e68b931a4 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -61,14 +61,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } - private float zoomTarget = 10; - private void setZoomTarget(float newZoom, float focusPoint) + private int zoomTarget = 10; + private void setZoomTarget(int newZoom, float focusPoint) { zoomTarget = MathHelper.Clamp(newZoom, 1, 60); transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); } - private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing)); private class TransformZoom : Transform From 35e116cb1270dce0641d3856db21d7612d34961f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:04:07 +0900 Subject: [PATCH 07/27] Reduce ctor arguments --- .../Timeline/ScrollingTimelineContainer.cs | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 5e68b931a4..a24bf7c909 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -69,21 +69,34 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing)); + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth), newZoom, duration, easing)); private class TransformZoom : Transform { + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// private readonly float focusPoint; - private readonly float focusSize; - private readonly float sizeReference; - private readonly float scrollOffset; - public TransformZoom(float focusPoint, float focusSize, float sizeReference, float scrollOffset) + /// + /// The size of the waveform. + /// + private readonly float waveformSize; + + /// + /// The scroll offset at the start time of the transform/ + /// + private float startScrollOffset; + + /// + /// Transforms to a new value. + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// The size of the waveform. + public TransformZoom(float focusPoint, float waveformSize) { this.focusPoint = focusPoint; - this.focusSize = focusSize; - this.sizeReference = sizeReference; - this.scrollOffset = scrollOffset; + this.waveformSize = waveformSize; } public override string TargetMember => nameof(currentZoom); @@ -100,15 +113,19 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { float newZoom = valueAt(time); - float focusOffset = focusPoint - scrollOffset; - float expectedWidth = sizeReference * newZoom; - float targetOffset = expectedWidth * (focusPoint / focusSize) - focusOffset; + float focusOffset = focusPoint - startScrollOffset; + float expectedWidth = d.DrawWidth * newZoom; + float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; d.currentZoom = newZoom; d.ScrollTo(targetOffset, false); } - protected override void ReadIntoStartValue(ScrollingTimelineContainer d) => StartValue = d.currentZoom; + protected override void ReadIntoStartValue(ScrollingTimelineContainer d) + { + startScrollOffset = d.Current; + StartValue = d.currentZoom; + } } } } From 8da3c2c52aa79ca631fcd12573bc443a61ac9d3a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:05:19 +0900 Subject: [PATCH 08/27] Expose zoom publicly again, re-enable zoom buttons --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 4 ++-- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 9ce4830e5a..31466e960f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_plus, - // Action = () => timelineContainer.Zoom++ + Action = () => timelineContainer.Zoom++ }, new TimelineButton { @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_minus, - // Action = () => timelineContainer.Zoom-- + Action = () => timelineContainer.Zoom-- }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a24bf7c909..2fe5d09788 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -44,6 +44,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } + public int Zoom + { + get => zoomTarget; + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), waveformContainer).X); + } + protected override void Update() { base.Update(); From 0141cbebbab43ab85b11d0377aadae6259483448 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:08:10 +0900 Subject: [PATCH 09/27] waveformContainer -> zoomedContent --- .../Timeline/ScrollingTimelineContainer.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 2fe5d09788..e48b625b8b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - private readonly Container waveformContainer; + private readonly Container zoomedContent; private float currentZoom = 10; @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; BeatmapWaveformGraph waveform; - Child = waveformContainer = new Container + Child = zoomedContent = new Container { RelativeSizeAxes = Axes.Y, Child = waveform = new BeatmapWaveformGraph @@ -44,18 +44,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } + /// + /// Gets or sets the content zoom of this . + /// public int Zoom { get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), waveformContainer).X); + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); } protected override void Update() { base.Update(); - waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - waveformContainer.Width = DrawWidth * currentZoom; + zoomedContent.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + zoomedContent.Width = DrawWidth * currentZoom; } protected override bool OnWheel(InputState state) @@ -63,7 +66,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - setZoomTarget(zoomTarget + state.Mouse.WheelDelta, waveformContainer.ToLocalSpace(state.Mouse.NativeState.Position).X); + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); return true; } @@ -75,7 +78,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth), newZoom, duration, easing)); + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); private class TransformZoom : Transform { From 9a9ed1d630d9aa01ecca4ae03251d3a75124c7b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:30:54 +0900 Subject: [PATCH 10/27] Encapsulate zoom logic into a separate class --- .../Timeline/ScrollingTimelineContainer.cs | 115 ++--------------- .../Timeline/ZoomableScrollContainer.cs | 118 ++++++++++++++++++ 2 files changed, 125 insertions(+), 108 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index e48b625b8b..96dc54f1e9 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -3,40 +3,24 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Input; -using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Graphics; -using OpenTK; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class ScrollingTimelineContainer : ScrollContainer + public class ScrollingTimelineContainer : ZoomableScrollContainer { public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - private readonly Container zoomedContent; - - private float currentZoom = 10; - public ScrollingTimelineContainer() - : base(Direction.Horizontal) { - Masking = true; - BeatmapWaveformGraph waveform; - Child = zoomedContent = new Container + Child = waveform = new BeatmapWaveformGraph { - RelativeSizeAxes = Axes.Y, - Child = waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue - } + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue }; waveform.Beatmap.BindTo(Beatmap); @@ -44,97 +28,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } - /// - /// Gets or sets the content zoom of this . - /// - public int Zoom - { - get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); - } - protected override void Update() { base.Update(); - zoomedContent.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - zoomedContent.Width = DrawWidth * currentZoom; - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); - return true; - } - - private int zoomTarget = 10; - private void setZoomTarget(int newZoom, float focusPoint) - { - zoomTarget = MathHelper.Clamp(newZoom, 1, 60); - transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); - } - - private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); - - private class TransformZoom : Transform - { - /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. - /// - private readonly float focusPoint; - - /// - /// The size of the waveform. - /// - private readonly float waveformSize; - - /// - /// The scroll offset at the start time of the transform/ - /// - private float startScrollOffset; - - /// - /// Transforms to a new value. - /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. - /// The size of the waveform. - public TransformZoom(float focusPoint, float waveformSize) - { - this.focusPoint = focusPoint; - this.waveformSize = waveformSize; - } - - public override string TargetMember => nameof(currentZoom); - - private float valueAt(double time) - { - if (time < StartTime) return StartValue; - if (time >= EndTime) return EndValue; - - return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); - } - - protected override void Apply(ScrollingTimelineContainer d, double time) - { - float newZoom = valueAt(time); - - float focusOffset = focusPoint - startScrollOffset; - float expectedWidth = d.DrawWidth * newZoom; - float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; - - d.currentZoom = newZoom; - d.ScrollTo(targetOffset, false); - } - - protected override void ReadIntoStartValue(ScrollingTimelineContainer d) - { - startScrollOffset = d.Current; - StartValue = d.currentZoom; - } + // We want time = 0 to be at the centre of the container when scrolled to the start + Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs new file mode 100644 index 0000000000..05a2882f31 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Framework.MathUtils; +using OpenTK; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class ZoomableScrollContainer : ScrollContainer + { + private readonly Container zoomedContent; + protected override Container Content => zoomedContent; + + private float currentZoom = 10; + + public ZoomableScrollContainer() + : base(Direction.Horizontal) + { + base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); + } + + /// + /// Gets or sets the content zoom of this . + /// + public int Zoom + { + get => zoomTarget; + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + } + + protected override void Update() + { + base.Update(); + + zoomedContent.Width = DrawWidth * currentZoom; + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); + return true; + } + + private int zoomTarget = 10; + private void setZoomTarget(int newZoom, float focusPoint) + { + zoomTarget = MathHelper.Clamp(newZoom, 1, 60); + transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + } + + private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); + + private class TransformZoom : Transform + { + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// + private readonly float focusPoint; + + /// + /// The size of the waveform. + /// + private readonly float waveformSize; + + /// + /// The scroll offset at the start time of the transform/ + /// + private float startScrollOffset; + + /// + /// Transforms to a new value. + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// The size of the waveform. + public TransformZoom(float focusPoint, float waveformSize) + { + this.focusPoint = focusPoint; + this.waveformSize = waveformSize; + } + + public override string TargetMember => nameof(currentZoom); + + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + protected override void Apply(ZoomableScrollContainer d, double time) + { + float newZoom = valueAt(time); + + float focusOffset = focusPoint - startScrollOffset; + float expectedWidth = d.DrawWidth * newZoom; + float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; + + d.currentZoom = newZoom; + d.ScrollTo(targetOffset, false); + } + + protected override void ReadIntoStartValue(ZoomableScrollContainer d) + { + startScrollOffset = d.Current; + StartValue = d.currentZoom; + } + } + } +} From f41d31e1db2f2a1b2d4e398662cec4bddf8cca97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:32:23 +0900 Subject: [PATCH 11/27] ScrollableTimeline -> TimelineContainer --- .../Visual/TestCaseEditorComposeTimeline.cs | 8 ++++---- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 6 +++--- ...crollableTimeline.cs => TimelineContainer.cs} | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/Timeline/{ScrollableTimeline.cs => TimelineContainer.cs} (90%) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 0e7ba5c900..5323ac44b1 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -16,9 +16,9 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineContainer), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; - private readonly ScrollableTimeline timeline; + private readonly TimelineContainer timelineContainer; public TestCaseEditorComposeTimeline() { @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopCentre, State = Visibility.Visible }, - timeline = new ScrollableTimeline + timelineContainer = new TimelineContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) { - timeline.Beatmap.BindTo(osuGame.Beatmap); + timelineContainer.Beatmap.BindTo(osuGame.Beatmap); } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index 91adc8324a..d04c4c9c0f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { dependencies.Cache(beatDivisor); - ScrollableTimeline timeline; + TimelineContainer timelineContainer; Children = new Drawable[] { new GridContainer @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } + Child = timelineContainer = new TimelineContainer { RelativeSizeAxes = Axes.Both } }, new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } }, @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose }, }; - timeline.Beatmap.BindTo(Beatmap); + timelineContainer.Beatmap.BindTo(Beatmap); var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance(); if (ruleset == null) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs similarity index 90% rename from osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs index 31466e960f..95a8937b9b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs @@ -12,13 +12,13 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class ScrollableTimeline : CompositeDrawable + public class TimelineContainer : CompositeDrawable { public readonly Bindable Beatmap = new Bindable(); - private readonly ScrollingTimelineContainer timelineContainer; + private readonly Timeline timeline; - public ScrollableTimeline() + public TimelineContainer() { Masking = true; CornerRadius = 5; @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_plus, - Action = () => timelineContainer.Zoom++ + Action = () => timeline.Zoom++ }, new TimelineButton { @@ -103,13 +103,13 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_minus, - Action = () => timelineContainer.Zoom-- + Action = () => timeline.Zoom-- }, } } } }, - timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Both } + timeline = new Timeline { RelativeSizeAxes = Axes.Both } }, }, ColumnDimensions = new[] @@ -125,8 +125,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline hitSoundsCheckbox.Current.Value = true; waveformCheckbox.Current.Value = true; - timelineContainer.Beatmap.BindTo(Beatmap); - timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); + timeline.Beatmap.BindTo(Beatmap); + timeline.WaveformVisible.BindTo(waveformCheckbox.Current); } } } From a84536d343be59f40e2905ad947bcdd135fc5054 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:33:47 +0900 Subject: [PATCH 12/27] ScrollingTimelineContainer -> Timeline --- .../Timeline/{ScrollingTimelineContainer.cs => Timeline.cs} | 4 ++-- .../Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/Timeline/{ScrollingTimelineContainer.cs => Timeline.cs} (88%) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs similarity index 88% rename from osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 96dc54f1e9..f1086e2cf6 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -8,12 +8,12 @@ using osu.Game.Graphics; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class ScrollingTimelineContainer : ZoomableScrollContainer + public class Timeline : ZoomableScrollContainer { public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - public ScrollingTimelineContainer() + public Timeline() { BeatmapWaveformGraph waveform; Child = waveform = new BeatmapWaveformGraph diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 05a2882f31..592419b336 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } /// - /// Gets or sets the content zoom of this . + /// Gets or sets the content zoom of this . /// public int Zoom { @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private float startScrollOffset; /// - /// Transforms to a new value. + /// Transforms to a new value. /// /// The focus point in the waveform, in absolute coordinates local to the waveform. /// The size of the waveform. From d9e795fb9f7a8ee7f372e84653ec3eb870b2b92d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:40:03 +0900 Subject: [PATCH 13/27] TimelineContainer -> TimelineArea --- osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs | 8 ++++---- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 6 +++--- .../Timeline/{TimelineContainer.cs => TimelineArea.cs} | 4 ++-- .../Screens/Compose/Timeline/ZoomableScrollContainer.cs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/Timeline/{TimelineContainer.cs => TimelineArea.cs} (96%) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 5323ac44b1..8ffb54f2c7 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -16,9 +16,9 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineContainer), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; - private readonly TimelineContainer timelineContainer; + private readonly TimelineArea timelineArea; public TestCaseEditorComposeTimeline() { @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopCentre, State = Visibility.Visible }, - timelineContainer = new TimelineContainer + timelineArea = new TimelineArea { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) { - timelineContainer.Beatmap.BindTo(osuGame.Beatmap); + timelineArea.Beatmap.BindTo(osuGame.Beatmap); } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index d04c4c9c0f..9306a3394c 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { dependencies.Cache(beatDivisor); - TimelineContainer timelineContainer; + TimelineArea timelineArea; Children = new Drawable[] { new GridContainer @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = timelineContainer = new TimelineContainer { RelativeSizeAxes = Axes.Both } + Child = timelineArea = new TimelineArea { RelativeSizeAxes = Axes.Both } }, new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } }, @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose }, }; - timelineContainer.Beatmap.BindTo(Beatmap); + timelineArea.Beatmap.BindTo(Beatmap); var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance(); if (ruleset == null) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs similarity index 96% rename from osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs index 95a8937b9b..6793c30409 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs @@ -12,13 +12,13 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class TimelineContainer : CompositeDrawable + public class TimelineArea : CompositeDrawable { public readonly Bindable Beatmap = new Bindable(); private readonly Timeline timeline; - public TimelineContainer() + public TimelineArea() { Masking = true; CornerRadius = 5; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 592419b336..a5be41bb9f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private float startScrollOffset; /// - /// Transforms to a new value. + /// Transforms to a new value. /// /// The focus point in the waveform, in absolute coordinates local to the waveform. /// The size of the waveform. From 9b060b1bdf496cb45c742c679b1681297d14d48f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 6 Apr 2018 15:51:40 +0900 Subject: [PATCH 14/27] Fix delay in value retrieval causing offsetting when zooming --- .../Timeline/ZoomableScrollContainer.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index a5be41bb9f..194b689f10 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); private class TransformZoom : Transform { @@ -71,19 +71,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private readonly float waveformSize; /// - /// The scroll offset at the start time of the transform/ + /// The scroll offset at the start of the transform. /// - private float startScrollOffset; + private readonly float scrollOffset; /// /// Transforms to a new value. /// /// The focus point in the waveform, in absolute coordinates local to the waveform. /// The size of the waveform. - public TransformZoom(float focusPoint, float waveformSize) + /// The scroll offset at the start of the transform. + public TransformZoom(float focusPoint, float waveformSize, float scrollOffset) { this.focusPoint = focusPoint; this.waveformSize = waveformSize; + this.scrollOffset = scrollOffset; } public override string TargetMember => nameof(currentZoom); @@ -100,7 +102,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { float newZoom = valueAt(time); - float focusOffset = focusPoint - startScrollOffset; + float focusOffset = focusPoint - scrollOffset; float expectedWidth = d.DrawWidth * newZoom; float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; @@ -108,11 +110,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline d.ScrollTo(targetOffset, false); } - protected override void ReadIntoStartValue(ZoomableScrollContainer d) - { - startScrollOffset = d.Current; - StartValue = d.currentZoom; - } + protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom; } } } From f07928446d59d1199101f522baf4838e29e3c01f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 6 Apr 2018 15:52:39 +0900 Subject: [PATCH 15/27] Remove instances of "waveform" --- .../Compose/Timeline/ZoomableScrollContainer.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 194b689f10..ee5d336419 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -61,14 +61,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private class TransformZoom : Transform { /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// The focus point in absolute coordinates local to the content. /// private readonly float focusPoint; /// - /// The size of the waveform. + /// The size of the content. /// - private readonly float waveformSize; + private readonly float contentSize; /// /// The scroll offset at the start of the transform. @@ -78,13 +78,13 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline /// /// Transforms to a new value. /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. - /// The size of the waveform. + /// The focus point in absolute coordinates local to the content. + /// The size of the content. /// The scroll offset at the start of the transform. - public TransformZoom(float focusPoint, float waveformSize, float scrollOffset) + public TransformZoom(float focusPoint, float contentSize, float scrollOffset) { this.focusPoint = focusPoint; - this.waveformSize = waveformSize; + this.contentSize = contentSize; this.scrollOffset = scrollOffset; } @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline float focusOffset = focusPoint - scrollOffset; float expectedWidth = d.DrawWidth * newZoom; - float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; + float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; d.currentZoom = newZoom; d.ScrollTo(targetOffset, false); From bc3d195aa21361f86490c7bd86f1f099c94fc00b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 13:05:58 +0900 Subject: [PATCH 16/27] Fix line endings --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 78 +++--- .../Screens/Compose/Timeline/TimelineArea.cs | 264 +++++++++--------- .../Timeline/ZoomableScrollContainer.cs | 232 +++++++-------- 3 files changed, 287 insertions(+), 287 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index f1086e2cf6..a9de155df8 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -1,39 +1,39 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Game.Beatmaps; -using osu.Game.Graphics; - -namespace osu.Game.Screens.Edit.Screens.Compose.Timeline -{ - public class Timeline : ZoomableScrollContainer - { - public readonly Bindable WaveformVisible = new Bindable(); - public readonly Bindable Beatmap = new Bindable(); - - public Timeline() - { - BeatmapWaveformGraph waveform; - Child = waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue - }; - - waveform.Beatmap.BindTo(Beatmap); - - WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); - } - - protected override void Update() - { - base.Update(); - - // We want time = 0 to be at the centre of the container when scrolled to the start - Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - } - } -} +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class Timeline : ZoomableScrollContainer + { + public readonly Bindable WaveformVisible = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); + + public Timeline() + { + BeatmapWaveformGraph waveform; + Child = waveform = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue + }; + + waveform.Beatmap.BindTo(Beatmap); + + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); + } + + protected override void Update() + { + base.Update(); + + // We want time = 0 to be at the centre of the container when scrolled to the start + Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs index 6793c30409..9b6b0bd48d 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs @@ -1,132 +1,132 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.Edit.Screens.Compose.Timeline -{ - public class TimelineArea : CompositeDrawable - { - public readonly Bindable Beatmap = new Bindable(); - - private readonly Timeline timeline; - - public TimelineArea() - { - Masking = true; - CornerRadius = 5; - - OsuCheckbox hitObjectsCheckbox; - OsuCheckbox hitSoundsCheckbox; - OsuCheckbox waveformCheckbox; - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("111") - }, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222") - }, - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Y, - Width = 160, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 4), - Children = new[] - { - hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, - hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, - waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } - } - } - } - }, - new Container - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("333") - }, - new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Masking = true, - Children = new[] - { - new TimelineButton - { - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_plus, - Action = () => timeline.Zoom++ - }, - new TimelineButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_minus, - Action = () => timeline.Zoom-- - }, - } - } - } - }, - timeline = new Timeline { RelativeSizeAxes = Axes.Both } - }, - }, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed), - } - } - }; - - hitObjectsCheckbox.Current.Value = true; - hitSoundsCheckbox.Current.Value = true; - waveformCheckbox.Current.Value = true; - - timeline.Beatmap.BindTo(Beatmap); - timeline.WaveformVisible.BindTo(waveformCheckbox.Current); - } - } -} +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class TimelineArea : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly Timeline timeline; + + public TimelineArea() + { + Masking = true; + CornerRadius = 5; + + OsuCheckbox hitObjectsCheckbox; + OsuCheckbox hitSoundsCheckbox; + OsuCheckbox waveformCheckbox; + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } + } + } + } + }, + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Masking = true, + Children = new[] + { + new TimelineButton + { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_plus, + Action = () => timeline.Zoom++ + }, + new TimelineButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_minus, + Action = () => timeline.Zoom-- + }, + } + } + } + }, + timeline = new Timeline { RelativeSizeAxes = Axes.Both } + }, + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed), + } + } + }; + + hitObjectsCheckbox.Current.Value = true; + hitSoundsCheckbox.Current.Value = true; + waveformCheckbox.Current.Value = true; + + timeline.Beatmap.BindTo(Beatmap); + timeline.WaveformVisible.BindTo(waveformCheckbox.Current); + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index ee5d336419..545caf5166 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -1,116 +1,116 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Input; -using osu.Framework.MathUtils; -using OpenTK; - -namespace osu.Game.Screens.Edit.Screens.Compose.Timeline -{ - public class ZoomableScrollContainer : ScrollContainer - { - private readonly Container zoomedContent; - protected override Container Content => zoomedContent; - - private float currentZoom = 10; - - public ZoomableScrollContainer() - : base(Direction.Horizontal) - { - base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); - } - - /// - /// Gets or sets the content zoom of this . - /// - public int Zoom - { - get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); - } - - protected override void Update() - { - base.Update(); - - zoomedContent.Width = DrawWidth * currentZoom; - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); - return true; - } - - private int zoomTarget = 10; - private void setZoomTarget(int newZoom, float focusPoint) - { - zoomTarget = MathHelper.Clamp(newZoom, 1, 60); - transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); - } - - private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); - - private class TransformZoom : Transform - { - /// - /// The focus point in absolute coordinates local to the content. - /// - private readonly float focusPoint; - - /// - /// The size of the content. - /// - private readonly float contentSize; - - /// - /// The scroll offset at the start of the transform. - /// - private readonly float scrollOffset; - - /// - /// Transforms to a new value. - /// - /// The focus point in absolute coordinates local to the content. - /// The size of the content. - /// The scroll offset at the start of the transform. - public TransformZoom(float focusPoint, float contentSize, float scrollOffset) - { - this.focusPoint = focusPoint; - this.contentSize = contentSize; - this.scrollOffset = scrollOffset; - } - - public override string TargetMember => nameof(currentZoom); - - private float valueAt(double time) - { - if (time < StartTime) return StartValue; - if (time >= EndTime) return EndValue; - - return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); - } - - protected override void Apply(ZoomableScrollContainer d, double time) - { - float newZoom = valueAt(time); - - float focusOffset = focusPoint - scrollOffset; - float expectedWidth = d.DrawWidth * newZoom; - float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; - - d.currentZoom = newZoom; - d.ScrollTo(targetOffset, false); - } - - protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom; - } - } -} +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Framework.MathUtils; +using OpenTK; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class ZoomableScrollContainer : ScrollContainer + { + private readonly Container zoomedContent; + protected override Container Content => zoomedContent; + + private float currentZoom = 10; + + public ZoomableScrollContainer() + : base(Direction.Horizontal) + { + base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); + } + + /// + /// Gets or sets the content zoom of this . + /// + public int Zoom + { + get => zoomTarget; + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + } + + protected override void Update() + { + base.Update(); + + zoomedContent.Width = DrawWidth * currentZoom; + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); + return true; + } + + private int zoomTarget = 10; + private void setZoomTarget(int newZoom, float focusPoint) + { + zoomTarget = MathHelper.Clamp(newZoom, 1, 60); + transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + } + + private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); + + private class TransformZoom : Transform + { + /// + /// The focus point in absolute coordinates local to the content. + /// + private readonly float focusPoint; + + /// + /// The size of the content. + /// + private readonly float contentSize; + + /// + /// The scroll offset at the start of the transform. + /// + private readonly float scrollOffset; + + /// + /// Transforms to a new value. + /// + /// The focus point in absolute coordinates local to the content. + /// The size of the content. + /// The scroll offset at the start of the transform. + public TransformZoom(float focusPoint, float contentSize, float scrollOffset) + { + this.focusPoint = focusPoint; + this.contentSize = contentSize; + this.scrollOffset = scrollOffset; + } + + public override string TargetMember => nameof(currentZoom); + + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + protected override void Apply(ZoomableScrollContainer d, double time) + { + float newZoom = valueAt(time); + + float focusOffset = focusPoint - scrollOffset; + float expectedWidth = d.DrawWidth * newZoom; + float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; + + d.currentZoom = newZoom; + d.ScrollTo(targetOffset, false); + } + + protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom; + } + } +} From 82607b3eb302f6c1689e84c3de226adf1bd679f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 17:53:09 +0900 Subject: [PATCH 17/27] Expose properties to control zoom --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 4 ++ .../Timeline/ZoomableScrollContainer.cs | 70 +++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index a9de155df8..9801ba12a1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -15,6 +15,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public Timeline() { + ZoomDuration = 200; + ZoomEasing = Easing.OutQuint; + Zoom = 10; + BeatmapWaveformGraph waveform; Child = waveform = new BeatmapWaveformGraph { diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 545caf5166..72faf657ce 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.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 osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; @@ -12,10 +13,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ZoomableScrollContainer : ScrollContainer { + /// + /// The time to zoom into/out of a point. + /// All user scroll input will be overwritten during the zoom transform. + /// + public double ZoomDuration; + + /// + /// The easing with which to transform the zoom. + /// + public Easing ZoomEasing; + private readonly Container zoomedContent; protected override Container Content => zoomedContent; - private float currentZoom = 10; + private float currentZoom = 1; public ZoomableScrollContainer() : base(Direction.Horizontal) @@ -23,13 +35,59 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); } + private int minZoom = 1; + /// - /// Gets or sets the content zoom of this . + /// The minimum zoom level allowed. + /// + public int MinZoom + { + get => minZoom; + set + { + if (value < 1) + throw new ArgumentException($"{nameof(MinZoom)} must be >= 1.", nameof(value)); + minZoom = value; + + if (Zoom < value) + Zoom = value; + } + } + + private int maxZoom = 60; + + /// + /// The maximum zoom level allowed. + /// + public int MaxZoom + { + get => maxZoom; + set + { + if (value < 1) + throw new ArgumentException($"{nameof(MaxZoom)} must be >= 1.", nameof(value)); + maxZoom = value; + + if (Zoom > value) + Zoom = value; + } + } + + /// + /// Gets or sets the content zoom level of this . /// public int Zoom { get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + + if (IsLoaded) + setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + else + currentZoom = zoomTarget = value; + } } protected override void Update() @@ -48,11 +106,11 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } - private int zoomTarget = 10; + private int zoomTarget = 1; private void setZoomTarget(int newZoom, float focusPoint) { - zoomTarget = MathHelper.Clamp(newZoom, 1, 60); - transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + zoomTarget = MathHelper.Clamp(newZoom, MinZoom, MaxZoom); + transformZoomTo(zoomTarget, focusPoint, ZoomDuration, ZoomEasing); } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) From 757f89871819a1164e778ae544c3d6d81d7e79e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 17:53:19 +0900 Subject: [PATCH 18/27] Add testcase for zoomable scroll container --- .../Visual/TestCaseZoomableScrollContainer.cs | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs new file mode 100644 index 0000000000..06ec9ec63c --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; +using osu.Game.Graphics; +using osu.Game.Graphics.Cursor; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; +using OpenTK; +using OpenTK.Graphics; +using OpenTK.Input; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseZoomableScrollContainer : ManualInputManagerTestCase + { + private readonly ZoomableScrollContainer scrollContainer; + private readonly Drawable innerBox; + + public TestCaseZoomableScrollContainer() + { + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = 250, + Width = 0.75f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(30) + }, + scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both } + } + }, + new MenuCursor() + }; + + scrollContainer.Add(innerBox = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(new Color4(0.8f, 0.6f, 0.4f, 1f), new Color4(0.4f, 0.6f, 0.8f, 1f)) + }); + } + + [Test] + public void TestZoom0() + { + reset(); + AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + AddAssert("Box width = 1x", () => Precision.AlmostEquals(boxQuad.Size, scrollQuad.Size)); + } + + [Test] + public void TestZoom10() + { + reset(); + AddStep("Set zoom = 10", () => scrollContainer.Zoom = 10); + AddAssert("Box at 1/2", () => Precision.AlmostEquals(boxQuad.Centre, scrollQuad.Centre)); + AddAssert("Box width = 10x", () => Precision.AlmostEquals(boxQuad.Size.X, 10 * scrollQuad.Size.X)); + } + + [Test] + public void TestMouseZoomInOnceOutOnce() + { + reset(); + + // Scroll in at 0.25 + AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by 3", () => InputManager.ScrollBy(3)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X)); + + // Scroll out at 0.25 + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by -3", () => InputManager.ScrollBy(-3)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X)); + } + + [Test] + public void TestMouseZoomInTwiceOutTwice() + { + reset(); + + // Scroll in at 0.25 + AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by 1", () => InputManager.ScrollBy(1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + + // Scroll in at 0.6 + AddStep("Move mouse to 0.75x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.75f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by 1", () => InputManager.ScrollBy(1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + + // Very hard to determine actual position, so approximate + AddAssert("Box at correct position (1)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X)); + AddAssert("Box at correct position (2)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.3f * boxQuad.Size.X)); + AddAssert("Box at correct position (3)", () => Precision.DefinitelyBigger(boxQuad.TopLeft.X + 0.6f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X)); + + // Scroll out at 0.6 + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by -1", () => InputManager.ScrollBy(-1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + + // Scroll out at 0.25 + AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by -1", () => InputManager.ScrollBy(-1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + } + + private void reset() + { + AddStep("Reset", () => + { + scrollContainer.Zoom = 0; + scrollContainer.ScrollTo(0, false); + }); + } + + private Quad scrollQuad => scrollContainer.ScreenSpaceDrawQuad; + private Quad boxQuad => innerBox.ScreenSpaceDrawQuad; + } +} From f50c1c78a25a719f1b1c1cf4ac072a991013d8f0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 18:14:12 +0900 Subject: [PATCH 19/27] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index fac688633b..8f007de13e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fac688633b8fcf34ae5d0514c26b03e217161eb4 +Subproject commit 8f007de13e4a1aed46cb35e5018448f809bd5e88 From 35678237591c8ff22cb479c9f0c32130471e16cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 14:18:38 +0900 Subject: [PATCH 20/27] Reverse order of exposed objects in HitObjectContainer Closes #2740. --- osu.Game.Rulesets.Mania/UI/Column.cs | 9 +++++++-- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 4 +--- osu.Game/Rulesets/Mods/ModHidden.cs | 3 +-- osu.Game/Rulesets/UI/HitObjectContainer.cs | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 28cd1b6b39..ff1b8e506a 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -265,8 +265,13 @@ namespace osu.Game.Rulesets.Mania.UI if (action != Action) return false; - var hitObject = HitObjects.Objects.LastOrDefault(h => h.HitObject.StartTime > Time.Current) ?? HitObjects.Objects.FirstOrDefault(); - hitObject?.PlaySamples(); + var nextObject = + HitObjects.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? + // fallback to non-alive objects to find next off-screen object + HitObjects.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? + HitObjects.Objects.LastOrDefault(); + + nextObject?.PlaySamples(); return true; } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index b63f85623e..f2d5631e93 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -64,9 +64,7 @@ namespace osu.Game.Rulesets.Osu.UI public override void PostProcess() { - connectionLayer.HitObjects = HitObjects.Objects - .Select(d => d.HitObject) - .OrderBy(h => h.StartTime).OfType(); + connectionLayer.HitObjects = HitObjects.Objects.Select(d => d.HitObject).OfType(); } private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 45da628ce8..9b09f0bd6d 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -27,8 +27,7 @@ namespace osu.Game.Rulesets.Mods public virtual void ApplyToDrawableHitObjects(IEnumerable drawables) { - // todo: fix ordering of objects so we don't have to do this (#2740). - foreach (var d in drawables.Reverse().Skip(IncreaseFirstObjectVisibility ? 1 : 0)) + foreach (var d in drawables.Skip(IncreaseFirstObjectVisibility ? 1 : 0)) d.ApplyCustomUpdateState += ApplyHiddenState; } diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs index 1b6841c9bd..af18d98561 100644 --- a/osu.Game/Rulesets/UI/HitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -11,8 +11,8 @@ namespace osu.Game.Rulesets.UI { public class HitObjectContainer : CompositeDrawable { - public virtual IEnumerable Objects => InternalChildren.Cast(); - public virtual IEnumerable AliveObjects => AliveInternalChildren.Cast(); + public IEnumerable Objects => InternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); + public IEnumerable AliveObjects => AliveInternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject); public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject); From 0b4f5af52e31c5088fa1edba366bbb931d830e8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 03:17:12 +0900 Subject: [PATCH 21/27] Add setting to toggle standardised or exponential scoring display Also adjusts exponential scoring to be closer to stable. Log wasn't cutting it. --- osu.Game/Configuration/OsuConfigManager.cs | 6 +++++- .../Settings/Sections/Gameplay/GeneralSettings.cs | 6 ++++++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 11 ++++++++--- osu.Game/Screens/Play/Player.cs | 1 + 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 597960c352..f7fe424aa9 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -5,6 +5,7 @@ using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Platform; using osu.Game.Overlays; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select; namespace osu.Game.Configuration @@ -80,6 +81,8 @@ namespace osu.Game.Configuration Set(OsuSetting.FloatingComments, false); + Set(OsuSetting.ScoreDisplayMode, ScoringMode.Standardised); + Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential); Set(OsuSetting.IncreaseFirstObjectVisibility, true); @@ -147,6 +150,7 @@ namespace osu.Game.Configuration SongSelectRightMouseScroll, BeatmapSkins, BeatmapHitsounds, - IncreaseFirstObjectVisibility + IncreaseFirstObjectVisibility, + ScoreDisplayMode } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 647395cf69..9c8f5e2643 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Overlays.Settings.Sections.Gameplay { @@ -38,6 +39,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Always show key overlay", Bindable = config.GetBindable(OsuSetting.KeyOverlay) }, + new SettingsEnumDropdown + { + LabelText = "Score display mode", + Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) + } }; } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 345930ed04..0568101aa7 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -65,6 +65,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt HighestCombo = new BindableInt(); + /// + /// The used to calculate scores. + /// + public readonly Bindable Mode = new Bindable(); + /// /// Whether all s have been processed. /// @@ -169,8 +174,6 @@ namespace osu.Game.Rulesets.Scoring private const double combo_portion = 0.7; private const double max_score = 1000000; - public readonly Bindable Mode = new Bindable(); - protected sealed override bool HasCompleted => JudgedHits == MaxHits; protected int MaxHits { get; private set; } @@ -202,6 +205,8 @@ namespace osu.Game.Rulesets.Scoring Mode.Value = ScoringMode.Exponential; Mode.Disabled = true; } + + Mode.ValueChanged += _ => updateScore(); } /// @@ -296,7 +301,7 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; case ScoringMode.Exponential: - TotalScore.Value = (baseScore + bonusScore) * Math.Log(HighestCombo + 1, 2); + TotalScore.Value = (baseScore + bonusScore) * Math.Max(0, HighestCombo - 1) / 25f; break; } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fe77f85a50..94d03be3c8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -158,6 +158,7 @@ namespace osu.Game.Screens.Play userAudioOffset.TriggerChange(); ScoreProcessor = RulesetContainer.CreateScoreProcessor(); + ScoreProcessor.Mode.BindTo(config.GetBindable(OsuSetting.ScoreDisplayMode)); Children = new Drawable[] { From 8cc31aca541db1a002177a1467f5e30a6ebe0a78 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 11:41:54 +0900 Subject: [PATCH 22/27] Reorganise API requests and response classes They were previously breaking the two-class-per-file rule. --- .../Visual/TestCaseBeatmapScoresContainer.cs | 30 ++--- .../TestCaseUserProfileRecentSection.cs | 37 +++--- .../API/Requests/GetBeatmapDetailsRequest.cs | 28 +--- .../API/Requests/GetBeatmapSetRequest.cs | 4 +- .../Online/API/Requests/GetScoresRequest.cs | 121 +----------------- .../API/Requests/GetUserBeatmapsRequest.cs | 3 +- .../GetUserMostPlayedBeatmapsRequest.cs | 30 +---- .../GetUserRecentActivitiesRequest.cs | 87 +------------ .../API/Requests/GetUserScoresRequest.cs | 3 +- .../Online/API/Requests/GetUsersRequest.cs | 11 +- .../Requests/Responses/APIBeatmapMetrics.cs | 29 +++++ .../APIBeatmapSet.cs} | 6 +- .../Requests/Responses/APIRecentActivity.cs | 89 +++++++++++++ .../Online/API/Requests/Responses/APIScore.cs | 117 +++++++++++++++++ .../API/Requests/Responses/APIScores.cs | 14 ++ .../Online/API/Requests/Responses/APIUser.cs | 14 ++ .../Responses/APIUserMostPlayedBeatmap.cs | 30 +++++ .../API/Requests/SearchBeatmapSetsRequest.cs | 3 +- .../BeatmapSet/Scores/DrawableScore.cs | 4 +- .../BeatmapSet/Scores/DrawableTopScore.cs | 6 +- .../BeatmapSet/Scores/ScoresContainer.cs | 5 +- .../Sections/Ranks/PaginatedScoreContainer.cs | 3 +- .../Sections/Recent/DrawableRecentActivity.cs | 5 +- .../PaginatedRecentActivityContainer.cs | 3 +- 24 files changed, 366 insertions(+), 316 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs rename osu.Game/Online/API/Requests/{APIResponseBeatmapSet.cs => Responses/APIBeatmapSet.cs} (97%) create mode 100644 osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIScore.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIScores.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIUser.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 5be7386238..3f63bacfa6 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Game.Graphics; -using osu.Game.Online.API.Requests; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; @@ -15,6 +14,7 @@ using osu.Game.Users; using System.Collections.Generic; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual @@ -22,9 +22,9 @@ namespace osu.Game.Tests.Visual [System.ComponentModel.Description("in BeatmapOverlay")] public class TestCaseBeatmapScoresContainer : OsuTestCase { - private readonly IEnumerable scores; - private readonly IEnumerable anotherScores; - private readonly OnlineScore topScore; + private readonly IEnumerable scores; + private readonly IEnumerable anotherScores; + private readonly APIScore topScore; private readonly Box background; public TestCaseBeatmapScoresContainer() @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual scores = new[] { - new OnlineScore + new APIScore { User = new User { @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234567890, Accuracy = 1, }, - new OnlineScore + new APIScore { User = new User { @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234789, Accuracy = 0.9997, }, - new OnlineScore + new APIScore { User = new User { @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual TotalScore = 12345678, Accuracy = 0.9854, }, - new OnlineScore + new APIScore { User = new User { @@ -143,7 +143,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234567, Accuracy = 0.8765, }, - new OnlineScore + new APIScore { User = new User { @@ -169,7 +169,7 @@ namespace osu.Game.Tests.Visual anotherScores = new[] { - new OnlineScore + new APIScore { User = new User { @@ -191,7 +191,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234789, Accuracy = 0.9997, }, - new OnlineScore + new APIScore { User = new User { @@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234567890, Accuracy = 1, }, - new OnlineScore + new APIScore { User = new User { @@ -230,7 +230,7 @@ namespace osu.Game.Tests.Visual TotalScore = 123456, Accuracy = 0.6543, }, - new OnlineScore + new APIScore { User = new User { @@ -251,7 +251,7 @@ namespace osu.Game.Tests.Visual TotalScore = 12345678, Accuracy = 0.9854, }, - new OnlineScore + new APIScore { User = new User { @@ -279,7 +279,7 @@ namespace osu.Game.Tests.Visual s.Statistics.Add(HitResult.Meh, RNG.Next(2000)); } - topScore = new OnlineScore + topScore = new APIScore { User = new User { diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs index f625bc0150..b14606780d 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs @@ -12,6 +12,7 @@ using osu.Game.Overlays.Profile.Sections.Recent; using System; using System.Collections.Generic; using System.Linq; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Tests.Visual { @@ -49,15 +50,15 @@ namespace osu.Game.Tests.Visual }; } - private IEnumerable createDummyActivities() + private IEnumerable createDummyActivities() { - var dummyBeatmap = new RecentActivity.RecentActivityBeatmap + var dummyBeatmap = new APIRecentActivity.RecentActivityBeatmap { Title = @"Dummy beatmap", Url = "/b/1337", }; - var dummyUser = new RecentActivity.RecentActivityUser + var dummyUser = new APIRecentActivity.RecentActivityUser { Username = "DummyReborn", Url = "/u/666", @@ -66,61 +67,61 @@ namespace osu.Game.Tests.Visual return new[] { - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.Achievement, - Achievement = new RecentActivity.RecentActivityAchievement + Achievement = new APIRecentActivity.RecentActivityAchievement { Name = @"Feelin' It", Slug = @"all-secret-feelinit", }, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapPlaycount, Count = 1337, Beatmap = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetApprove, Approval = BeatmapApproval.Qualified, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetDelete, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetRevive, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetRevive, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetUpdate, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetUpload, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.Rank, @@ -128,29 +129,29 @@ namespace osu.Game.Tests.Visual Mode = "osu!", Beatmap = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.RankLost, Mode = "osu!", Beatmap = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UsernameChange, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UserSupportAgain, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UserSupportFirst, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UserSupportGift, diff --git a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs index b853da7e76..ab840d054f 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using Newtonsoft.Json; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetBeatmapDetailsRequest : APIRequest + public class GetBeatmapDetailsRequest : APIRequest { private readonly BeatmapInfo beatmap; @@ -19,28 +19,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $@"beatmaps/{lookupString}"; } - - public class GetBeatmapDetailsResponse : BeatmapMetrics - { - //the online API returns some metrics as a nested object. - [JsonProperty(@"failtimes")] - private BeatmapMetrics failTimes - { - set - { - Fails = value.Fails; - Retries = value.Retries; - } - } - - //and other metrics in the beatmap set. - [JsonProperty(@"beatmapset")] - private BeatmapMetrics beatmapSet - { - set - { - Ratings = value.Ratings; - } - } - } } diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs index 37dd77af46..d04e069cd6 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs @@ -1,9 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Online.API.Requests.Responses; + namespace osu.Game.Online.API.Requests { - public class GetBeatmapSetRequest : APIRequest + public class GetBeatmapSetRequest : APIRequest { private readonly int id; private readonly BeatmapSetLookupType type; diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index cff6fd4ea5..3be5b91a0d 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -2,20 +2,15 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Users; -using osu.Game.Rulesets.Replays; -using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select.Leaderboards; using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetScoresRequest : APIRequest + public class GetScoresRequest : APIRequest { private readonly BeatmapInfo beatmap; private readonly LeaderboardScope scope; @@ -36,9 +31,9 @@ namespace osu.Game.Online.API.Requests Success += onSuccess; } - private void onSuccess(GetScoresResponse r) + private void onSuccess(APIScores r) { - foreach (OnlineScore score in r.Scores) + foreach (APIScore score in r.Scores) score.ApplyBeatmap(beatmap); } @@ -55,112 +50,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores"; } - - public class GetScoresResponse - { - [JsonProperty(@"scores")] - public IEnumerable Scores; - } - - public class OnlineScore : Score - { - [JsonProperty(@"score")] - private double totalScore - { - set { TotalScore = value; } - } - - [JsonProperty(@"max_combo")] - private int maxCombo - { - set { MaxCombo = value; } - } - - [JsonProperty(@"user")] - private User user - { - set { User = value; } - } - - [JsonProperty(@"replay_data")] - private Replay replay - { - set { Replay = value; } - } - - [JsonProperty(@"mode_int")] - public int OnlineRulesetID { get; set; } - - [JsonProperty(@"score_id")] - private long onlineScoreID - { - set { OnlineScoreID = value; } - } - - [JsonProperty(@"created_at")] - private DateTimeOffset date - { - set { Date = value; } - } - - [JsonProperty(@"beatmap")] - private BeatmapInfo beatmap - { - set { Beatmap = value; } - } - - [JsonProperty(@"beatmapset")] - private BeatmapMetadata metadata - { - set { Beatmap.Metadata = value; } - } - - [JsonProperty(@"statistics")] - private Dictionary jsonStats - { - set - { - foreach (var kvp in value) - { - HitResult newKey; - switch (kvp.Key) - { - case @"count_300": - newKey = HitResult.Great; - break; - case @"count_100": - newKey = HitResult.Good; - break; - case @"count_50": - newKey = HitResult.Meh; - break; - case @"count_miss": - newKey = HitResult.Miss; - break; - default: - continue; - } - - Statistics.Add(newKey, kvp.Value); - } - } - } - - [JsonProperty(@"mods")] - private string[] modStrings { get; set; } - - public void ApplyBeatmap(BeatmapInfo beatmap) - { - Beatmap = beatmap; - ApplyRuleset(beatmap.Ruleset); - } - - public void ApplyRuleset(RulesetInfo ruleset) - { - Ruleset = ruleset; - - // Evaluate the mod string - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - } - } } diff --git a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs index 48e9babd97..b847a954f6 100644 --- a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs @@ -3,10 +3,11 @@ using Humanizer; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserBeatmapsRequest : APIRequest> + public class GetUserBeatmapsRequest : APIRequest> { private readonly long userId; private readonly int offset; diff --git a/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs index 106f3d4fb1..9a54aafa82 100644 --- a/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs @@ -1,14 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using Newtonsoft.Json; -using osu.Game.Beatmaps; -using osu.Game.Rulesets; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserMostPlayedBeatmapsRequest : APIRequest> + public class GetUserMostPlayedBeatmapsRequest : APIRequest> { private readonly long userId; private readonly int offset; @@ -21,28 +19,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $@"users/{userId}/beatmapsets/most_played?offset={offset}"; } - - public class MostPlayedBeatmap - { - [JsonProperty("beatmap_id")] - public int BeatmapID; - - [JsonProperty("count")] - public int PlayCount; - - [JsonProperty] - private BeatmapInfo beatmap; - - [JsonProperty] - private APIResponseBeatmapSet beatmapSet; - - public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) - { - BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); - beatmap.BeatmapSet = setInfo; - beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID; - beatmap.Metadata = setInfo.Metadata; - return beatmap; - } - } } diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index ded0e4f80d..e1cad1a532 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -1,15 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using Newtonsoft.Json; -using osu.Game.Rulesets.Scoring; -using Humanizer; -using System; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserRecentActivitiesRequest : APIRequest> + public class GetUserRecentActivitiesRequest : APIRequest> { private readonly long userId; private readonly int offset; @@ -23,86 +20,6 @@ namespace osu.Game.Online.API.Requests protected override string Target => $"users/{userId}/recent_activity?offset={offset}"; } - public class RecentActivity - { - [JsonProperty("id")] - public int ID; - - [JsonProperty("createdAt")] - public DateTimeOffset CreatedAt; - - [JsonProperty] - private string type - { - set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize()); - } - - public RecentActivityType Type; - - [JsonProperty] - private string scoreRank - { - set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value); - } - - public ScoreRank ScoreRank; - - [JsonProperty("rank")] - public int Rank; - - [JsonProperty("approval")] - public BeatmapApproval Approval; - - [JsonProperty("count")] - public int Count; - - [JsonProperty("mode")] - public string Mode; - - [JsonProperty("beatmap")] - public RecentActivityBeatmap Beatmap; - - [JsonProperty("beatmapset")] - public RecentActivityBeatmap Beatmapset; - - [JsonProperty("user")] - public RecentActivityUser User; - - [JsonProperty("achievement")] - public RecentActivityAchievement Achievement; - - public class RecentActivityBeatmap - { - [JsonProperty("title")] - public string Title; - - [JsonProperty("url")] - public string Url; - } - - public class RecentActivityUser - { - [JsonProperty("username")] - public string Username; - - [JsonProperty("url")] - public string Url; - - [JsonProperty("previousUsername")] - public string PreviousUsername; - } - - public class RecentActivityAchievement - { - [JsonProperty("slug")] - public string Slug; - - [JsonProperty("name")] - public string Name; - } - - } - public enum RecentActivityType { Achievement, diff --git a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs index 7757f529e0..ea14135a61 100644 --- a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs @@ -2,10 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserScoresRequest : APIRequest> + public class GetUserScoresRequest : APIRequest> { private readonly long userId; private readonly ScoreType type; diff --git a/osu.Game/Online/API/Requests/GetUsersRequest.cs b/osu.Game/Online/API/Requests/GetUsersRequest.cs index 575d0464aa..17dd9263c9 100644 --- a/osu.Game/Online/API/Requests/GetUsersRequest.cs +++ b/osu.Game/Online/API/Requests/GetUsersRequest.cs @@ -2,19 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using Newtonsoft.Json; -using osu.Game.Users; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUsersRequest : APIRequest> + public class GetUsersRequest : APIRequest> { protected override string Target => @"rankings/osu/performance"; } - - public class RankingEntry - { - [JsonProperty] - public User User; - } } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs new file mode 100644 index 0000000000..e67c60cb91 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Beatmaps; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIBeatmapMetrics : BeatmapMetrics + { + //the online API returns some metrics as a nested object. + [JsonProperty(@"failtimes")] + private BeatmapMetrics failTimes + { + set + { + Fails = value.Fails; + Retries = value.Retries; + } + } + + //and other metrics in the beatmap set. + [JsonProperty(@"beatmapset")] + private BeatmapMetrics beatmapSet + { + set => Ratings = value.Ratings; + } + } +} diff --git a/osu.Game/Online/API/Requests/APIResponseBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs similarity index 97% rename from osu.Game/Online/API/Requests/APIResponseBeatmapSet.cs rename to osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 44c1216959..cbe3b929fd 100644 --- a/osu.Game/Online/API/Requests/APIResponseBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -1,16 +1,16 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using System; -namespace osu.Game.Online.API.Requests +namespace osu.Game.Online.API.Requests.Responses { - public class APIResponseBeatmapSet : BeatmapMetadata // todo: this is a bit wrong... + public class APIBeatmapSet : BeatmapMetadata // todo: this is a bit wrong... { [JsonProperty(@"covers")] private BeatmapSetOnlineCovers covers { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs new file mode 100644 index 0000000000..2c65a37cf8 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -0,0 +1,89 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using Humanizer; +using Newtonsoft.Json; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIRecentActivity + { + [JsonProperty("id")] + public int ID; + + [JsonProperty("createdAt")] + public DateTimeOffset CreatedAt; + + [JsonProperty] + private string type + { + set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize()); + } + + public RecentActivityType Type; + + [JsonProperty] + private string scoreRank + { + set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value); + } + + public ScoreRank ScoreRank; + + [JsonProperty("rank")] + public int Rank; + + [JsonProperty("approval")] + public BeatmapApproval Approval; + + [JsonProperty("count")] + public int Count; + + [JsonProperty("mode")] + public string Mode; + + [JsonProperty("beatmap")] + public RecentActivityBeatmap Beatmap; + + [JsonProperty("beatmapset")] + public RecentActivityBeatmap Beatmapset; + + [JsonProperty("user")] + public RecentActivityUser User; + + [JsonProperty("achievement")] + public RecentActivityAchievement Achievement; + + public class RecentActivityBeatmap + { + [JsonProperty("title")] + public string Title; + + [JsonProperty("url")] + public string Url; + } + + public class RecentActivityUser + { + [JsonProperty("username")] + public string Username; + + [JsonProperty("url")] + public string Url; + + [JsonProperty("previousUsername")] + public string PreviousUsername; + } + + public class RecentActivityAchievement + { + [JsonProperty("slug")] + public string Slug; + + [JsonProperty("name")] + public string Name; + } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIScore.cs b/osu.Game/Online/API/Requests/Responses/APIScore.cs new file mode 100644 index 0000000000..a398bf46ee --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIScore.cs @@ -0,0 +1,117 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Scoring; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIScore : Score + { + [JsonProperty(@"score")] + private double totalScore + { + set => TotalScore = value; + } + + [JsonProperty(@"max_combo")] + private int maxCombo + { + set => MaxCombo = value; + } + + [JsonProperty(@"user")] + private User user + { + set => User = value; + } + + [JsonProperty(@"replay_data")] + private Replay replay + { + set => Replay = value; + } + + [JsonProperty(@"mode_int")] + public int OnlineRulesetID { get; set; } + + [JsonProperty(@"score_id")] + private long onlineScoreID + { + set => OnlineScoreID = value; + } + + [JsonProperty(@"created_at")] + private DateTimeOffset date + { + set => Date = value; + } + + [JsonProperty(@"beatmap")] + private BeatmapInfo beatmap + { + set => Beatmap = value; + } + + [JsonProperty(@"beatmapset")] + private BeatmapMetadata metadata + { + set => Beatmap.Metadata = value; + } + + [JsonProperty(@"statistics")] + private Dictionary jsonStats + { + set + { + foreach (var kvp in value) + { + HitResult newKey; + switch (kvp.Key) + { + case @"count_300": + newKey = HitResult.Great; + break; + case @"count_100": + newKey = HitResult.Good; + break; + case @"count_50": + newKey = HitResult.Meh; + break; + case @"count_miss": + newKey = HitResult.Miss; + break; + default: + continue; + } + + Statistics.Add(newKey, kvp.Value); + } + } + } + + [JsonProperty(@"mods")] + private string[] modStrings { get; set; } + + public void ApplyBeatmap(BeatmapInfo beatmap) + { + Beatmap = beatmap; + ApplyRuleset(beatmap.Ruleset); + } + + public void ApplyRuleset(RulesetInfo ruleset) + { + Ruleset = ruleset; + + // Evaluate the mod string + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIScores.cs b/osu.Game/Online/API/Requests/Responses/APIScores.cs new file mode 100644 index 0000000000..b4213db253 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIScores.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIScores + { + [JsonProperty(@"scores")] + public IEnumerable Scores; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs new file mode 100644 index 0000000000..54c8451456 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIUser + { + [JsonProperty] + public User User; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs new file mode 100644 index 0000000000..26f80321bc --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIUserMostPlayedBeatmap + { + [JsonProperty("beatmap_id")] + public int BeatmapID; + + [JsonProperty("count")] + public int PlayCount; + + [JsonProperty] + private BeatmapInfo beatmap; + + [JsonProperty] + private APIBeatmapSet beatmapSet; + + public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) + { + BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); + beatmap.BeatmapSet = setInfo; + beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID; + beatmap.Metadata = setInfo.Metadata; + return beatmap; + } + } +} diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index d68314f8fc..2a154d1230 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -3,13 +3,14 @@ using System.Collections.Generic; using System.ComponentModel; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Direct; using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { - public class SearchBeatmapSetsRequest : APIRequest> + public class SearchBeatmapSetsRequest : APIRequest> { private readonly string query; private readonly RulesetInfo ruleset; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 10e689698d..fc8b3a6800 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly Box background; - public DrawableScore(int index, OnlineScore score) + public DrawableScore(int index, APIScore score) { ScoreModsContainer modsContainer; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 8ac79eabb4..b3ceffd35e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -42,8 +42,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly InfoColumn statistics; private readonly ScoreModsContainer modsContainer; - private OnlineScore score; - public OnlineScore Score + private APIScore score; + public APIScore Score { get { return score; } set diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 185282bec9..626de14c98 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -11,6 +11,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -28,10 +29,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration); } - private IEnumerable scores; + private IEnumerable scores; private BeatmapInfo beatmap; - public IEnumerable Scores + public IEnumerable Scores { get { return scores; } set diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 87df84e2e5..707de0a10f 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -8,6 +8,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Users; using System; using System.Linq; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -49,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks MissingText.Hide(); - foreach (OnlineScore score in scores) + foreach (APIScore score in scores) { DrawableProfileScore drawableScore; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 721cc30b61..046c1b1a33 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -8,6 +8,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Screens.Select.Leaderboards; @@ -17,11 +18,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { private APIAccess api; - private readonly RecentActivity activity; + private readonly APIRecentActivity activity; private LinkFlowContainer content; - public DrawableRecentActivity(RecentActivity activity) + public DrawableRecentActivity(APIRecentActivity activity) { this.activity = activity; } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 8c1108b115..ee2f2f5973 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Game.Users; using System.Linq; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -36,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent MissingText.Hide(); - foreach (RecentActivity activity in activities) + foreach (APIRecentActivity activity in activities) { ItemsContainer.Add(new DrawableRecentActivity(activity)); } From 1716975a37c53baa661e34b306bee0b5d6102a5d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 12:04:33 +0900 Subject: [PATCH 23/27] Move out APIBeatmap --- .../API/Requests/Responses/APIBeatmap.cs | 78 +++++++++++++++++++ .../API/Requests/Responses/APIBeatmapSet.cs | 74 +----------------- 2 files changed, 81 insertions(+), 71 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIBeatmap.cs diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs new file mode 100644 index 0000000000..f75d320a46 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -0,0 +1,78 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIBeatmap : BeatmapMetadata + { + [JsonProperty(@"id")] + private int onlineBeatmapID { get; set; } + + [JsonProperty(@"playcount")] + private int playCount { get; set; } + + [JsonProperty(@"passcount")] + private int passCount { get; set; } + + [JsonProperty(@"mode_int")] + private int ruleset { get; set; } + + [JsonProperty(@"difficulty_rating")] + private double starDifficulty { get; set; } + + [JsonProperty(@"drain")] + private float drainRate { get; set; } + + [JsonProperty(@"cs")] + private float circleSize { get; set; } + + [JsonProperty(@"ar")] + private float approachRate { get; set; } + + [JsonProperty(@"accuracy")] + private float overallDifficulty { get; set; } + + [JsonProperty(@"total_length")] + private double length { get; set; } + + [JsonProperty(@"count_circles")] + private int circleCount { get; set; } + + [JsonProperty(@"count_sliders")] + private int sliderCount { get; set; } + + [JsonProperty(@"version")] + private string version { get; set; } + + public BeatmapInfo ToBeatmap(RulesetStore rulesets) + { + return new BeatmapInfo + { + Metadata = this, + Ruleset = rulesets.GetRuleset(ruleset), + StarDifficulty = starDifficulty, + OnlineBeatmapID = onlineBeatmapID, + Version = version, + BaseDifficulty = new BeatmapDifficulty + { + DrainRate = drainRate, + CircleSize = circleSize, + ApproachRate = approachRate, + OverallDifficulty = overallDifficulty, + }, + OnlineInfo = new BeatmapOnlineInfo + { + PlayCount = playCount, + PassCount = passCount, + Length = length, + CircleCount = circleCount, + SliderCount = sliderCount, + }, + }; + } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index cbe3b929fd..f57de016a2 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -46,12 +46,13 @@ namespace osu.Game.Online.API.Requests.Responses private DateTimeOffset lastUpdated { get; set; } [JsonProperty(@"user_id")] - private long creatorId { + private long creatorId + { set { Author.Id = value; } } [JsonProperty(@"beatmaps")] - private IEnumerable beatmaps { get; set; } + private IEnumerable beatmaps { get; set; } public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets) { @@ -76,74 +77,5 @@ namespace osu.Game.Online.API.Requests.Responses Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(), }; } - - private class APIResponseBeatmap : BeatmapMetadata - { - [JsonProperty(@"id")] - private int onlineBeatmapID { get; set; } - - [JsonProperty(@"playcount")] - private int playCount { get; set; } - - [JsonProperty(@"passcount")] - private int passCount { get; set; } - - [JsonProperty(@"mode_int")] - private int ruleset { get; set; } - - [JsonProperty(@"difficulty_rating")] - private double starDifficulty { get; set; } - - [JsonProperty(@"drain")] - private float drainRate { get; set; } - - [JsonProperty(@"cs")] - private float circleSize { get; set; } - - [JsonProperty(@"ar")] - private float approachRate { get; set; } - - [JsonProperty(@"accuracy")] - private float overallDifficulty { get; set; } - - [JsonProperty(@"total_length")] - private double length { get; set; } - - [JsonProperty(@"count_circles")] - private int circleCount { get; set; } - - [JsonProperty(@"count_sliders")] - private int sliderCount { get; set; } - - [JsonProperty(@"version")] - private string version { get; set; } - - public BeatmapInfo ToBeatmap(RulesetStore rulesets) - { - return new BeatmapInfo - { - Metadata = this, - Ruleset = rulesets.GetRuleset(ruleset), - StarDifficulty = starDifficulty, - OnlineBeatmapID = onlineBeatmapID, - Version = version, - BaseDifficulty = new BeatmapDifficulty - { - DrainRate = drainRate, - CircleSize = circleSize, - ApproachRate = approachRate, - OverallDifficulty = overallDifficulty, - }, - OnlineInfo = new BeatmapOnlineInfo - { - PlayCount = playCount, - PassCount = passCount, - Length = length, - CircleCount = circleCount, - SliderCount = sliderCount, - }, - }; - } - } } } From b45354ce97c5944bce29cfc35294f9e10ceae70d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 12:06:58 +0900 Subject: [PATCH 24/27] Add missing header --- .../API/Requests/Responses/APIUserMostPlayedBeatmap.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs index 26f80321bc..d49613eab7 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -1,4 +1,7 @@ -using Newtonsoft.Json; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; From cc37a355d26836cf655c911f3953e1b30f2d614d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 10 Jun 2018 01:44:46 +0900 Subject: [PATCH 25/27] Add comment about matching stable scoring Also updated equation to be close to what is expected --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 0568101aa7..b6ec0617f2 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -301,7 +301,8 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; case ScoringMode.Exponential: - TotalScore.Value = (baseScore + bonusScore) * Math.Max(0, HighestCombo - 1) / 25f; + // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) + TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25); break; } } From 86fb9666b250f52e07a84b8248c98ab1c3560370 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 10 Jun 2018 01:45:05 +0900 Subject: [PATCH 26/27] Rename "Exponential" to "Classic" --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b6ec0617f2..dd4120f2fb 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -202,7 +202,7 @@ namespace osu.Game.Rulesets.Scoring if (maxBaseScore == 0 || maxHighestCombo == 0) { - Mode.Value = ScoringMode.Exponential; + Mode.Value = ScoringMode.Classic; Mode.Disabled = true; } @@ -213,7 +213,7 @@ namespace osu.Game.Rulesets.Scoring /// Simulates an autoplay of s that will be judged by this /// by adding s for each in the . /// - /// This is required for to work, otherwise will be used. + /// This is required for to work, otherwise will be used. /// /// /// The containing the s that will be judged by this . @@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Scoring case ScoringMode.Standardised: TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; - case ScoringMode.Exponential: + case ScoringMode.Classic: // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25); break; @@ -328,6 +328,6 @@ namespace osu.Game.Rulesets.Scoring public enum ScoringMode { Standardised, - Exponential + Classic } } From b9391b3c6bb8f84426767e7233d499cb633959f3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 18:18:24 +0900 Subject: [PATCH 27/27] Fix bindable not working under non-debug due to weak references --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 94d03be3c8..04148cd558 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Play userAudioOffset.TriggerChange(); ScoreProcessor = RulesetContainer.CreateScoreProcessor(); - ScoreProcessor.Mode.BindTo(config.GetBindable(OsuSetting.ScoreDisplayMode)); + config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); Children = new Drawable[] {