From 4aea18b673a752afe24b83be4e3d2560010c2ef2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 1 May 2017 17:00:41 +0900 Subject: [PATCH 01/15] Add initial column design. --- .../Tests/TestCaseManiaPlayfield.cs | 217 ++++++++++++++++++ .../osu.Desktop.VisualTests.csproj | 1 + 2 files changed, 218 insertions(+) create mode 100644 osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs new file mode 100644 index 0000000000..5932d0d7eb --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -0,0 +1,217 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Framework.Graphics.Primitives; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseManiaPlayfield : TestCase + { + public override string Description => @"Mania playfield"; + + public override void Reset() + { + base.Reset(); + + Add(new Column + { + AccentColour = new Color4(187, 17, 119, 255) + }); + } + } + + public class Column : Container, IHasAccentColour + { + private const float key_size = 50; + + private const float key_icon_size = 10; + private const float key_icon_corner_radius = 3; + private const float key_icon_border_radius = 2; + + private const float hit_target_height = 10; + private const float hit_target_bar_height = 2; + + private const float column_width = 45; + private const float special_column_width = 70; + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + if (accentColour == value) + return; + accentColour = value; + + setAccentColour(); + } + } + + private bool isSpecialColumn; + public bool IsSpecialColumn + { + get { return isSpecialColumn; } + set + { + isSpecialColumn = value; + Width = isSpecialColumn ? special_column_width : column_width; + } + } + + private Box foreground; + private Container hitTargetBar; + private Container keyIcon; + + public Column() + { + RelativeSizeAxes = Axes.Y; + Width = column_width; + + Children = new Drawable[] + { + new Box + { + Name = "Background", + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 1, Right = 1 }, + Children = new[] + { + foreground = new Box + { + Name = "Foreground", + RelativeSizeAxes = Axes.Both, + Alpha = 0.2f + }, + } + }, + new FillFlowContainer + { + Name = "Key + hit target", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new[] + { + new Container + { + Name = "Key", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = key_size, + Children = new Drawable[] + { + new Box + { + Name = "Key gradient", + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientVertical(Color4.Black, Color4.Black.Opacity(0)), + Alpha = 0.5f + }, + new Box + { + Name = "Key down foreground", + Alpha = 0f, + }, + keyIcon = new Container + { + Name = "Key icon", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(key_icon_size), + Masking = true, + CornerRadius = key_icon_corner_radius, + BorderThickness = 2, + BorderColour = Color4.White, // Not true + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + } + } + }, + new Container + { + Name = "Hit target", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = hit_target_height, + Children = new Drawable[] + { + new Box + { + Name = "Background", + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + hitTargetBar = new Container + { + Name = "Bar", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = hit_target_bar_height, + Masking = true, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both + } + } + } + } + } + } + } + }; + } + + private void setAccentColour() + { + foreground.Colour = AccentColour; + + hitTargetBar.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = AccentColour.Opacity(0.5f), + }; + + keyIcon.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = AccentColour.Opacity(0.5f), + }; + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 135e4596c7..6a5d082aa3 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -190,6 +190,7 @@ + From 82cbb63af5dfab171f96f721ec08e4501f01a8f9 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 1 May 2017 17:24:35 +0900 Subject: [PATCH 02/15] Add column generation + put spacing one level up. --- .../Tests/TestCaseManiaPlayfield.cs | 73 ++++++++++++++----- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 5932d0d7eb..65978a030c 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -23,14 +23,63 @@ namespace osu.Desktop.VisualTests.Tests { public override string Description => @"Mania playfield"; + private FlowContainer columns; + public override void Reset() { base.Reset(); - Add(new Column + Add(new Container { - AccentColour = new Color4(187, 17, 119, 255) + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + columns = new FillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Left = 1, Right = 1 }, + Spacing = new Vector2(1, 0) + } + } }); + + var colours = new Color4[] + { + new Color4(187, 17, 119, 255), + new Color4(96, 204, 0, 255), + new Color4(17, 136, 170, 255) + }; + + int num_columns = 7; + int half_columns = num_columns / 2; + + for (int i = 0; i < num_columns; i++) + columns.Add(new Column()); + + for (int i = 0; i < half_columns; i++) + { + Color4 accent = colours[i % 2]; + columns.Children.ElementAt(i).AccentColour = accent; + columns.Children.ElementAt(num_columns - 1 - i).AccentColour = accent; + } + + bool hasSpecial = half_columns * 2 < num_columns; + if (hasSpecial) + { + Column specialColumn = columns.Children.ElementAt(half_columns); + specialColumn.IsSpecialColumn = true; + specialColumn.AccentColour = colours[2]; + } } } @@ -84,25 +133,11 @@ namespace osu.Desktop.VisualTests.Tests Children = new Drawable[] { - new Box + foreground = new Box { - Name = "Background", + Name = "Foreground", RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 1, Right = 1 }, - Children = new[] - { - foreground = new Box - { - Name = "Foreground", - RelativeSizeAxes = Axes.Both, - Alpha = 0.2f - }, - } + Alpha = 0.2f }, new FillFlowContainer { From 80ebd04e856487b3c3bdb5e71be5631ab3979165 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 1 May 2017 20:48:43 +0900 Subject: [PATCH 03/15] Add keys to columns and add key down transformations. --- .../Tests/TestCaseManiaPlayfield.cs | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 65978a030c..9ee09883aa 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -16,6 +16,8 @@ using System.Threading.Tasks; using osu.Framework.Testing; using osu.Game.Graphics; using osu.Framework.Graphics.Primitives; +using osu.Framework.Input; +using OpenTK.Input; namespace osu.Desktop.VisualTests.Tests { @@ -60,11 +62,18 @@ namespace osu.Desktop.VisualTests.Tests new Color4(17, 136, 170, 255) }; + var keys = new Key[] { Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L }; + int num_columns = 7; int half_columns = num_columns / 2; for (int i = 0; i < num_columns; i++) - columns.Add(new Column()); + { + columns.Add(new Column + { + Key = keys[i] + }); + } for (int i = 0; i < half_columns; i++) { @@ -122,7 +131,9 @@ namespace osu.Desktop.VisualTests.Tests } } - private Box foreground; + public Key Key; + + private Box background; private Container hitTargetBar; private Container keyIcon; @@ -133,7 +144,7 @@ namespace osu.Desktop.VisualTests.Tests Children = new Drawable[] { - foreground = new Box + background = new Box { Name = "Foreground", RelativeSizeAxes = Axes.Both, @@ -165,11 +176,6 @@ namespace osu.Desktop.VisualTests.Tests ColourInfo = ColourInfo.GradientVertical(Color4.Black, Color4.Black.Opacity(0)), Alpha = 0.5f }, - new Box - { - Name = "Key down foreground", - Alpha = 0f, - }, keyIcon = new Container { Name = "Key icon", @@ -232,7 +238,7 @@ namespace osu.Desktop.VisualTests.Tests private void setAccentColour() { - foreground.Colour = AccentColour; + background.Colour = AccentColour; hitTargetBar.EdgeEffect = new EdgeEffect { @@ -248,5 +254,27 @@ namespace osu.Desktop.VisualTests.Tests Colour = AccentColour.Opacity(0.5f), }; } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Key == Key && !args.Repeat) + { + background.FadeTo(background.Alpha + 0.2f, 50, EasingTypes.OutQuint); + keyIcon.ScaleTo(1.4f, 50, EasingTypes.OutQuint); + } + + return false; + } + + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + { + if (args.Key == Key) + { + background.FadeTo(0.2f, 800, EasingTypes.OutQuart); + keyIcon.ScaleTo(1f, 400, EasingTypes.OutQuart); + } + + return false; + } } } From b4052a099f3d27bab3597a2e4ea068ae3f5c26fe Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 12:30:03 +0900 Subject: [PATCH 04/15] Create ManiaPlayfield, support up to 9 columns, improve testcase automation. --- .../Tests/TestCaseManiaPlayfield.cs | 147 ++++++++++++------ 1 file changed, 100 insertions(+), 47 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 9ee09883aa..89d4d5cc22 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -18,6 +18,9 @@ using osu.Game.Graphics; using osu.Framework.Graphics.Primitives; using osu.Framework.Input; using OpenTK.Input; +using osu.Game.Rulesets.UI; +using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Desktop.VisualTests.Tests { @@ -25,69 +28,119 @@ namespace osu.Desktop.VisualTests.Tests { public override string Description => @"Mania playfield"; - private FlowContainer columns; + protected override double TimePerAction => 200; public override void Reset() { base.Reset(); - Add(new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black - }, - columns = new FillFlowContainer - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Direction = FillDirection.Horizontal, - Padding = new MarginPadding { Left = 1, Right = 1 }, - Spacing = new Vector2(1, 0) - } - } - }); + int max_columns = 9; - var colours = new Color4[] + for (int i = 1; i <= max_columns; i++) { - new Color4(187, 17, 119, 255), - new Color4(96, 204, 0, 255), - new Color4(17, 136, 170, 255) + int tempI = i; + + AddStep($@"{i} column" + (i > 1 ? "s" : ""), () => + { + Clear(); + Add(new ManiaPlayfield(tempI) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }); + }); + + AddStep($"Trigger keys down", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyDown)); + AddStep($"Trigger keys up", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyUp)); + } + } + + private void triggerKeyDown(Column column) + { + column.TriggerKeyDown(new InputState(), new KeyDownEventArgs + { + Key = column.Key, + Repeat = false + }); + } + + private void triggerKeyUp(Column column) + { + column.TriggerKeyUp(new InputState(), new KeyUpEventArgs + { + Key = column.Key + }); + } + } + + public class ManiaPlayfield : Container + { + public readonly FlowContainer Columns; + + public ManiaPlayfield(int columnCount) + { + if (columnCount > 9) + throw new ArgumentException($@"{columnCount} columns is not supported."); + if (columnCount <= 0) + throw new ArgumentException($@"Can't have zero or fewer columns."); + + RelativeSizeAxes = Axes.Y; + AutoSizeAxes = Axes.X; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + Columns = new FillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Left = 1, Right = 1 }, + Spacing = new Vector2(1, 0) + } }; - var keys = new Key[] { Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L }; + for (int i = 0; i < columnCount; i++) + Columns.Add(new Column()); + } - int num_columns = 7; - int half_columns = num_columns / 2; - - for (int i = 0; i < num_columns; i++) + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + var columnColours = new Color4[] { - columns.Add(new Column - { - Key = keys[i] - }); + colours.RedDark, + colours.GreenDark, + colours.BlueDark // Special column + }; + + int columnCount = Columns.Children.Count(); + int halfColumns = columnCount / 2; + + var keys = new Key[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; + + for (int i = 0; i < halfColumns; i++) + { + Column leftColumn = Columns.Children.ElementAt(i); + Column rightColumn = Columns.Children.ElementAt(columnCount - 1 - i); + + Color4 accent = columnColours[i % 2]; + leftColumn.AccentColour = rightColumn.AccentColour = accent; + leftColumn.Key = keys[keys.Length / 2 - halfColumns + i]; + rightColumn.Key = keys[keys.Length / 2 + halfColumns - i]; } - for (int i = 0; i < half_columns; i++) - { - Color4 accent = colours[i % 2]; - columns.Children.ElementAt(i).AccentColour = accent; - columns.Children.ElementAt(num_columns - 1 - i).AccentColour = accent; - } - - bool hasSpecial = half_columns * 2 < num_columns; + bool hasSpecial = halfColumns * 2 < columnCount; if (hasSpecial) { - Column specialColumn = columns.Children.ElementAt(half_columns); + Column specialColumn = Columns.Children.ElementAt(halfColumns); specialColumn.IsSpecialColumn = true; - specialColumn.AccentColour = colours[2]; + specialColumn.AccentColour = columnColours[2]; + specialColumn.Key = keys[keys.Length / 2]; } } } From 71acf1c57dd0439796ebdb22bd983c7788f26190 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 12:37:47 +0900 Subject: [PATCH 05/15] Move classes out of test case. --- .../Tests/TestCaseManiaPlayfield.cs | 259 +----------------- osu.Game.Rulesets.Mania/UI/Column.cs | 204 ++++++++++++++ osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 89 +++++- .../osu.Game.Rulesets.Mania.csproj | 1 + 4 files changed, 282 insertions(+), 271 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/UI/Column.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 89d4d5cc22..62abc865a1 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -21,6 +21,7 @@ using OpenTK.Input; using osu.Game.Rulesets.UI; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Rulesets.Mania.UI; namespace osu.Desktop.VisualTests.Tests { @@ -72,262 +73,4 @@ namespace osu.Desktop.VisualTests.Tests }); } } - - public class ManiaPlayfield : Container - { - public readonly FlowContainer Columns; - - public ManiaPlayfield(int columnCount) - { - if (columnCount > 9) - throw new ArgumentException($@"{columnCount} columns is not supported."); - if (columnCount <= 0) - throw new ArgumentException($@"Can't have zero or fewer columns."); - - RelativeSizeAxes = Axes.Y; - AutoSizeAxes = Axes.X; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black - }, - Columns = new FillFlowContainer - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Direction = FillDirection.Horizontal, - Padding = new MarginPadding { Left = 1, Right = 1 }, - Spacing = new Vector2(1, 0) - } - }; - - for (int i = 0; i < columnCount; i++) - Columns.Add(new Column()); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - var columnColours = new Color4[] - { - colours.RedDark, - colours.GreenDark, - colours.BlueDark // Special column - }; - - int columnCount = Columns.Children.Count(); - int halfColumns = columnCount / 2; - - var keys = new Key[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; - - for (int i = 0; i < halfColumns; i++) - { - Column leftColumn = Columns.Children.ElementAt(i); - Column rightColumn = Columns.Children.ElementAt(columnCount - 1 - i); - - Color4 accent = columnColours[i % 2]; - leftColumn.AccentColour = rightColumn.AccentColour = accent; - leftColumn.Key = keys[keys.Length / 2 - halfColumns + i]; - rightColumn.Key = keys[keys.Length / 2 + halfColumns - i]; - } - - bool hasSpecial = halfColumns * 2 < columnCount; - if (hasSpecial) - { - Column specialColumn = Columns.Children.ElementAt(halfColumns); - specialColumn.IsSpecialColumn = true; - specialColumn.AccentColour = columnColours[2]; - specialColumn.Key = keys[keys.Length / 2]; - } - } - } - - public class Column : Container, IHasAccentColour - { - private const float key_size = 50; - - private const float key_icon_size = 10; - private const float key_icon_corner_radius = 3; - private const float key_icon_border_radius = 2; - - private const float hit_target_height = 10; - private const float hit_target_bar_height = 2; - - private const float column_width = 45; - private const float special_column_width = 70; - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - if (accentColour == value) - return; - accentColour = value; - - setAccentColour(); - } - } - - private bool isSpecialColumn; - public bool IsSpecialColumn - { - get { return isSpecialColumn; } - set - { - isSpecialColumn = value; - Width = isSpecialColumn ? special_column_width : column_width; - } - } - - public Key Key; - - private Box background; - private Container hitTargetBar; - private Container keyIcon; - - public Column() - { - RelativeSizeAxes = Axes.Y; - Width = column_width; - - Children = new Drawable[] - { - background = new Box - { - Name = "Foreground", - RelativeSizeAxes = Axes.Both, - Alpha = 0.2f - }, - new FillFlowContainer - { - Name = "Key + hit target", - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new[] - { - new Container - { - Name = "Key", - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = key_size, - Children = new Drawable[] - { - new Box - { - Name = "Key gradient", - RelativeSizeAxes = Axes.Both, - ColourInfo = ColourInfo.GradientVertical(Color4.Black, Color4.Black.Opacity(0)), - Alpha = 0.5f - }, - keyIcon = new Container - { - Name = "Key icon", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(key_icon_size), - Masking = true, - CornerRadius = key_icon_corner_radius, - BorderThickness = 2, - BorderColour = Color4.White, // Not true - Children = new[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } - } - } - } - }, - new Container - { - Name = "Hit target", - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = hit_target_height, - Children = new Drawable[] - { - new Box - { - Name = "Background", - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black - }, - hitTargetBar = new Container - { - Name = "Bar", - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = hit_target_bar_height, - Masking = true, - Children = new[] - { - new Box - { - RelativeSizeAxes = Axes.Both - } - } - } - } - } - } - } - }; - } - - private void setAccentColour() - { - background.Colour = AccentColour; - - hitTargetBar.EdgeEffect = new EdgeEffect - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = AccentColour.Opacity(0.5f), - }; - - keyIcon.EdgeEffect = new EdgeEffect - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = AccentColour.Opacity(0.5f), - }; - } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (args.Key == Key && !args.Repeat) - { - background.FadeTo(background.Alpha + 0.2f, 50, EasingTypes.OutQuint); - keyIcon.ScaleTo(1.4f, 50, EasingTypes.OutQuint); - } - - return false; - } - - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) - { - if (args.Key == Key) - { - background.FadeTo(0.2f, 800, EasingTypes.OutQuart); - keyIcon.ScaleTo(1f, 400, EasingTypes.OutQuart); - } - - return false; - } - } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs new file mode 100644 index 0000000000..584dfdd09c --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -0,0 +1,204 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + + +using OpenTK; +using OpenTK.Graphics; +using OpenTK.Input; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Colour; +using osu.Framework.Input; +using osu.Game.Graphics; + +namespace osu.Game.Rulesets.Mania.UI +{ + public class Column : Container, IHasAccentColour + { + private const float key_size = 50; + + private const float key_icon_size = 10; + private const float key_icon_corner_radius = 3; + private const float key_icon_border_radius = 2; + + private const float hit_target_height = 10; + private const float hit_target_bar_height = 2; + + private const float column_width = 45; + private const float special_column_width = 70; + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + if (accentColour == value) + return; + accentColour = value; + + setAccentColour(); + } + } + + private bool isSpecialColumn; + public bool IsSpecialColumn + { + get { return isSpecialColumn; } + set + { + isSpecialColumn = value; + Width = isSpecialColumn ? special_column_width : column_width; + } + } + + public Key Key; + + private Box background; + private Container hitTargetBar; + private Container keyIcon; + + public Column() + { + RelativeSizeAxes = Axes.Y; + Width = column_width; + + Children = new Drawable[] + { + background = new Box + { + Name = "Foreground", + RelativeSizeAxes = Axes.Both, + Alpha = 0.2f + }, + new FillFlowContainer + { + Name = "Key + hit target", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new[] + { + new Container + { + Name = "Key", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = key_size, + Children = new Drawable[] + { + new Box + { + Name = "Key gradient", + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientVertical(Color4.Black, Color4.Black.Opacity(0)), + Alpha = 0.5f + }, + keyIcon = new Container + { + Name = "Key icon", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(key_icon_size), + Masking = true, + CornerRadius = key_icon_corner_radius, + BorderThickness = 2, + BorderColour = Color4.White, // Not true + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + } + } + }, + new Container + { + Name = "Hit target", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = hit_target_height, + Children = new Drawable[] + { + new Box + { + Name = "Background", + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + hitTargetBar = new Container + { + Name = "Bar", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = hit_target_bar_height, + Masking = true, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both + } + } + } + } + } + } + } + }; + } + + private void setAccentColour() + { + background.Colour = AccentColour; + + hitTargetBar.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = AccentColour.Opacity(0.5f), + }; + + keyIcon.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = AccentColour.Opacity(0.5f), + }; + } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Key == Key && !args.Repeat) + { + background.FadeTo(background.Alpha + 0.2f, 50, EasingTypes.OutQuint); + keyIcon.ScaleTo(1.4f, 50, EasingTypes.OutQuint); + } + + return false; + } + + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + { + if (args.Key == Key) + { + background.FadeTo(0.2f, 800, EasingTypes.OutQuart); + keyIcon.ScaleTo(1f, 400, EasingTypes.OutQuart); + } + + return false; + } + } + +} diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 5eea3d70c0..0b7b1df06d 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -8,29 +8,92 @@ using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; using osu.Game.Rulesets.Mania.Judgements; +using osu.Framework.Graphics.Containers; +using System; +using osu.Framework.Graphics.Primitives; +using osu.Game.Graphics; +using osu.Framework.Allocation; +using OpenTK.Input; +using System.Linq; namespace osu.Game.Rulesets.Mania.UI { public class ManiaPlayfield : Playfield { + public readonly FlowContainer Columns; + public ManiaPlayfield(int columns) { - Size = new Vector2(0.8f, 1f); - Anchor = Anchor.BottomCentre; - Origin = Anchor.BottomCentre; + if (columns > 9) + throw new ArgumentException($@"{columns} columns is not supported."); + if (columns <= 0) + throw new ArgumentException($@"Can't have zero or fewer columns."); - Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f }); + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + Columns = new FillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Left = 1, Right = 1 }, + Spacing = new Vector2(1, 0) + } + } + } + }; for (int i = 0; i < columns; i++) - Add(new Box - { - RelativeSizeAxes = Axes.Y, - Size = new Vector2(2, 1), - RelativePositionAxes = Axes.Both, - Position = new Vector2((float)i / columns, 0), - Alpha = 0.5f, - Colour = Color4.Black - }); + Columns.Add(new Column()); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + var columnColours = new Color4[] + { + colours.RedDark, + colours.GreenDark, + colours.BlueDark // Special column + }; + + int columnCount = Columns.Children.Count(); + int halfColumns = columnCount / 2; + + var keys = new Key[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; + + for (int i = 0; i < halfColumns; i++) + { + Column leftColumn = Columns.Children.ElementAt(i); + Column rightColumn = Columns.Children.ElementAt(columnCount - 1 - i); + + Color4 accent = columnColours[i % 2]; + leftColumn.AccentColour = rightColumn.AccentColour = accent; + leftColumn.Key = keys[keys.Length / 2 - halfColumns + i]; + rightColumn.Key = keys[keys.Length / 2 + halfColumns - i]; + } + + bool hasSpecial = halfColumns * 2 < columnCount; + if (hasSpecial) + { + Column specialColumn = Columns.Children.ElementAt(halfColumns); + specialColumn.IsSpecialColumn = true; + specialColumn.AccentColour = columnColours[2]; + specialColumn.Key = keys[keys.Length / 2]; + } } } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index facffa757c..18ea1de13a 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -56,6 +56,7 @@ + From 7de36b7aa27db5c0c07a75d8516019839c820698 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 12:58:46 +0900 Subject: [PATCH 06/15] CI cleanups. --- .../Tests/TestCaseManiaPlayfield.cs | 31 +++++-------------- osu.Game.Rulesets.Mania/UI/Column.cs | 6 ++-- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 8 ++--- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 62abc865a1..4c7433ff5a 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -1,27 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using osu.Framework.Testing; -using osu.Game.Graphics; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Input; -using OpenTK.Input; -using osu.Game.Rulesets.UI; -using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Input; +using osu.Framework.Testing; +using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.UI; +using System.Linq; namespace osu.Desktop.VisualTests.Tests { @@ -35,13 +20,13 @@ namespace osu.Desktop.VisualTests.Tests { base.Reset(); - int max_columns = 9; + const int max_columns = 9; for (int i = 1; i <= max_columns; i++) { int tempI = i; - AddStep($@"{i} column" + (i > 1 ? "s" : ""), () => + AddStep($"{i} column" + (i > 1 ? "s" : ""), () => { Clear(); Add(new ManiaPlayfield(tempI) @@ -51,8 +36,8 @@ namespace osu.Desktop.VisualTests.Tests }); }); - AddStep($"Trigger keys down", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyDown)); - AddStep($"Trigger keys up", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyUp)); + AddStep("Trigger keys down", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyDown)); + AddStep("Trigger keys up", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyUp)); } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 584dfdd09c..75ae529c4c 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -56,9 +56,9 @@ namespace osu.Game.Rulesets.Mania.UI public Key Key; - private Box background; - private Container hitTargetBar; - private Container keyIcon; + private readonly Box background; + private readonly Container hitTargetBar; + private readonly Container keyIcon; public Column() { diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 0b7b1df06d..08ac4c4a3b 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -25,9 +25,9 @@ namespace osu.Game.Rulesets.Mania.UI public ManiaPlayfield(int columns) { if (columns > 9) - throw new ArgumentException($@"{columns} columns is not supported."); + throw new ArgumentException($"{columns} columns is not supported."); if (columns <= 0) - throw new ArgumentException($@"Can't have zero or fewer columns."); + throw new ArgumentException("Can't have zero or fewer columns."); Children = new Drawable[] { @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load(OsuColour colours) { - var columnColours = new Color4[] + Color4[] columnColours = new[] { colours.RedDark, colours.GreenDark, @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI int columnCount = Columns.Children.Count(); int halfColumns = columnCount / 2; - var keys = new Key[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; + Key[] keys = new[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; for (int i = 0; i < halfColumns; i++) { From d21c3358b9839086d863fb7c22d2c5890b195524 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 3 May 2017 13:03:46 +0900 Subject: [PATCH 07/15] Less array explicivity. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 08ac4c4a3b..112f91181d 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load(OsuColour colours) { - Color4[] columnColours = new[] + var columnColours = new[] { colours.RedDark, colours.GreenDark, @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI int columnCount = Columns.Children.Count(); int halfColumns = columnCount / 2; - Key[] keys = new[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; + var keys = new[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; for (int i = 0; i < halfColumns; i++) { @@ -96,4 +96,4 @@ namespace osu.Game.Rulesets.Mania.UI } } } -} \ No newline at end of file +} From 06e014708a92f66ef906d555ce0c1525e9ddccfe Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 15:56:54 +0900 Subject: [PATCH 08/15] Defer virtual method to load(). --- osu.Game/Rulesets/UI/HitRenderer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/HitRenderer.cs b/osu.Game/Rulesets/UI/HitRenderer.cs index 25d8bae205..69e0e73664 100644 --- a/osu.Game/Rulesets/UI/HitRenderer.cs +++ b/osu.Game/Rulesets/UI/HitRenderer.cs @@ -202,8 +202,6 @@ namespace osu.Game.Rulesets.UI protected HitRenderer(WorkingBeatmap beatmap) : base(beatmap) { - KeyConversionInputManager.Add(Playfield = CreatePlayfield()); - InputManager.Add(content = new Container { RelativeSizeAxes = Axes.Both, @@ -216,6 +214,8 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load() { + KeyConversionInputManager.Add(Playfield = CreatePlayfield()); + loadObjects(); if (InputManager?.ReplayInputHandler != null) From 14e4714f08209fabd8f548967bd19493d4189e7e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 19:38:15 +0900 Subject: [PATCH 09/15] Rewrite a lot of ManiaPlayfield/Column to support left/right special styles and arbitrary number of columns. --- .../Tests/TestCaseManiaPlayfield.cs | 4 +- osu.Game.Rulesets.Mania/UI/Column.cs | 74 ++++++----- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 118 ++++++++++++++---- .../UI/SpecialColumnStyle.cs | 21 ++++ .../osu.Game.Rulesets.Mania.csproj | 1 + 5 files changed, 155 insertions(+), 63 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 4c7433ff5a..9573ab154e 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -20,7 +20,7 @@ namespace osu.Desktop.VisualTests.Tests { base.Reset(); - const int max_columns = 9; + const int max_columns = 10; for (int i = 1; i <= max_columns; i++) { @@ -38,6 +38,8 @@ namespace osu.Desktop.VisualTests.Tests AddStep("Trigger keys down", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyDown)); AddStep("Trigger keys up", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyUp)); + AddStep("Left special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Left); + AddStep("Right special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Right); } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 75ae529c4c..d2fccb2c58 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -29,31 +29,6 @@ namespace osu.Game.Rulesets.Mania.UI private const float column_width = 45; private const float special_column_width = 70; - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - if (accentColour == value) - return; - accentColour = value; - - setAccentColour(); - } - } - - private bool isSpecialColumn; - public bool IsSpecialColumn - { - get { return isSpecialColumn; } - set - { - isSpecialColumn = value; - Width = isSpecialColumn ? special_column_width : column_width; - } - } - public Key Key; private readonly Box background; @@ -159,23 +134,46 @@ namespace osu.Game.Rulesets.Mania.UI }; } - private void setAccentColour() + private bool isSpecial; + public bool IsSpecial { - background.Colour = AccentColour; - - hitTargetBar.EdgeEffect = new EdgeEffect + get { return isSpecial; } + set { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = AccentColour.Opacity(0.5f), - }; + if (isSpecial == value) + return; + isSpecial = value; - keyIcon.EdgeEffect = new EdgeEffect + Width = isSpecial ? special_column_width : column_width; + } + } + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = AccentColour.Opacity(0.5f), - }; + if (accentColour == value) + return; + accentColour = value; + + background.Colour = accentColour; + + hitTargetBar.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Opacity(0.5f), + }; + + keyIcon.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Opacity(0.5f), + }; + } } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 112f91181d..471051e3f9 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -15,18 +15,50 @@ using osu.Game.Graphics; using osu.Framework.Allocation; using OpenTK.Input; using System.Linq; +using System.Collections.Generic; namespace osu.Game.Rulesets.Mania.UI { public class ManiaPlayfield : Playfield { + /// + /// Default column keys, expanding outwards from the middle as more column are added. + /// E.g. 2 columns use FJ, 4 columns use DFJK, 6 use SDFJKL, etc... + /// + private static readonly Key[] default_keys = new[] { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; + + private SpecialColumnStyle specialColumnStyle; + /// + /// The style to use for the special column. + /// + public SpecialColumnStyle SpecialColumnStyle + { + get { return specialColumnStyle; } + set + { + if (specialColumnStyle == value) + return; + specialColumnStyle = value; + + if (!IsLoaded) + return; + + updateColumnStyle(); + } + } + public readonly FlowContainer Columns; - public ManiaPlayfield(int columns) + private List normalColumnColours = new List(); + private Color4 specialColumnColour; + + private readonly int columnCount; + + public ManiaPlayfield(int columnCount) { - if (columns > 9) - throw new ArgumentException($"{columns} columns is not supported."); - if (columns <= 0) + this.columnCount = columnCount; + + if (columnCount <= 0) throw new ArgumentException("Can't have zero or fewer columns."); Children = new Drawable[] @@ -56,43 +88,81 @@ namespace osu.Game.Rulesets.Mania.UI } }; - for (int i = 0; i < columns; i++) + for (int i = 0; i < columnCount; i++) Columns.Add(new Column()); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - var columnColours = new[] + normalColumnColours = new List { colours.RedDark, - colours.GreenDark, - colours.BlueDark // Special column + colours.GreenDark }; - int columnCount = Columns.Children.Count(); - int halfColumns = columnCount / 2; + specialColumnColour = colours.BlueDark; - var keys = new[] { Key.A, Key.S, Key.D, Key.F, Key.Space, Key.J, Key.K, Key.L, Key.Semicolon }; + updateColumnStyle(); + } - for (int i = 0; i < halfColumns; i++) + /// + /// Updates the column style (special style/colours) + keys. + /// + private void updateColumnStyle() + { + // Set the special column + colour + key + for (int i = 0; i < columnCount; i++) { - Column leftColumn = Columns.Children.ElementAt(i); - Column rightColumn = Columns.Children.ElementAt(columnCount - 1 - i); + Column column = Columns.Children.ElementAt(i); + column.IsSpecial = isSpecialColumn(i); - Color4 accent = columnColours[i % 2]; - leftColumn.AccentColour = rightColumn.AccentColour = accent; - leftColumn.Key = keys[keys.Length / 2 - halfColumns + i]; - rightColumn.Key = keys[keys.Length / 2 + halfColumns - i]; + if (!column.IsSpecial) + continue; + + column.Key = Key.Space; + column.AccentColour = specialColumnColour; } - bool hasSpecial = halfColumns * 2 < columnCount; - if (hasSpecial) + var nonSpecialColumns = Columns.Children.Where(c => !c.IsSpecial).ToList(); + + // We'll set the colours of the non-special columns in a separate loop, because the non-special + // column colours are mirrored across their centre and special styles mess with this + for (int i = 0; i < Math.Ceiling(nonSpecialColumns.Count / 2f); i++) { - Column specialColumn = Columns.Children.ElementAt(halfColumns); - specialColumn.IsSpecialColumn = true; - specialColumn.AccentColour = columnColours[2]; - specialColumn.Key = keys[keys.Length / 2]; + Color4 colour = normalColumnColours[i % normalColumnColours.Count]; + nonSpecialColumns[i].AccentColour = colour; + nonSpecialColumns[nonSpecialColumns.Count - 1 - i].AccentColour = colour; + } + + // We'll set the keys for non-special columns in another separate loop because it's not mirrored like the above colours + // Todo: This needs to go when we get to bindings and use Button1, ..., ButtonN instead + for (int i = 0; i < nonSpecialColumns.Count; i++) + { + Column column = nonSpecialColumns[i]; + + int keyOffset = default_keys.Length / 2 - nonSpecialColumns.Count / 2 + i; + if (keyOffset >= 0 && keyOffset < default_keys.Length) + column.Key = default_keys[keyOffset]; + } + } + + /// + /// Whether the column index is a special column for this playfield. + /// + /// The 0-based column index. + /// Whether the column is a special column. + private bool isSpecialColumn(int column) + { + switch (SpecialColumnStyle) + { + default: + case SpecialColumnStyle.Normal: + return columnCount % 2 == 1 && column == columnCount / 2; + case SpecialColumnStyle.Left: + return column == 0; + case SpecialColumnStyle.Right: + return column == columnCount - 1; } } } diff --git a/osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs b/osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs new file mode 100644 index 0000000000..5acb147312 --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.UI +{ + public enum SpecialColumnStyle + { + /// + /// The special column will lie in the center of the columns. + /// + Normal, + /// + /// The special column will lie to the left of the columns. + /// + Left, + /// + /// The special column will lie to the right of the columns. + /// + Right + } +} diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 18ea1de13a..0a781aa30d 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -61,6 +61,7 @@ + From 8d82a52942c03ffccd48af1790f5bfe8b96f806c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 19:38:27 +0900 Subject: [PATCH 10/15] Add revert to normal special style after all steps. --- osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 9573ab154e..259dd6b4eb 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -41,6 +41,8 @@ namespace osu.Desktop.VisualTests.Tests AddStep("Left special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Left); AddStep("Right special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Right); } + + AddStep("Normal special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Normal); } private void triggerKeyDown(Column column) From 8aa6bb636c2f8eec8125aa4d76023eaf27edb822 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 3 May 2017 19:42:20 +0900 Subject: [PATCH 11/15] Reset column key when it can't be set. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 471051e3f9..947b067b02 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -144,6 +144,10 @@ namespace osu.Game.Rulesets.Mania.UI int keyOffset = default_keys.Length / 2 - nonSpecialColumns.Count / 2 + i; if (keyOffset >= 0 && keyOffset < default_keys.Length) column.Key = default_keys[keyOffset]; + else + // There is no default key defined for this column. Let's set this to Unknown for now + // however note that this will be gone after bindings are in place + column.Key = Key.Unknown; } } From 5024a7419289dc7932a74671397e3ae2237dd52c Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 3 May 2017 20:11:24 +0900 Subject: [PATCH 12/15] Update ManiaPlayfield.cs --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 947b067b02..000a3e47ad 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.UI /// Default column keys, expanding outwards from the middle as more column are added. /// E.g. 2 columns use FJ, 4 columns use DFJK, 6 use SDFJKL, etc... /// - private static readonly Key[] default_keys = new[] { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; + private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; private SpecialColumnStyle specialColumnStyle; /// From a2bdd020e5b86c06a436127c28ac9fbe3e475cdf Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 4 May 2017 14:46:10 +0900 Subject: [PATCH 13/15] ColumnStyle -> ColumnPosition. --- .../Tests/TestCaseManiaPlayfield.cs | 6 +++--- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 18 +++++++++--------- ...ColumnStyle.cs => SpecialColumnPosition.cs} | 2 +- .../osu.Game.Rulesets.Mania.csproj | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) rename osu.Game.Rulesets.Mania/UI/{SpecialColumnStyle.cs => SpecialColumnPosition.cs} (90%) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 259dd6b4eb..7e5a564da6 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -38,11 +38,11 @@ namespace osu.Desktop.VisualTests.Tests AddStep("Trigger keys down", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyDown)); AddStep("Trigger keys up", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyUp)); - AddStep("Left special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Left); - AddStep("Right special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Right); + AddStep("Left special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnPosition = SpecialColumnPosition.Left); + AddStep("Right special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnPosition = SpecialColumnPosition.Right); } - AddStep("Normal special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnStyle = SpecialColumnStyle.Normal); + AddStep("Normal special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnPosition = SpecialColumnPosition.Normal); } private void triggerKeyDown(Column column) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 000a3e47ad..d084326f5b 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -27,18 +27,18 @@ namespace osu.Game.Rulesets.Mania.UI /// private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; - private SpecialColumnStyle specialColumnStyle; + private SpecialColumnPosition specialColumnPosition; /// /// The style to use for the special column. /// - public SpecialColumnStyle SpecialColumnStyle + public SpecialColumnPosition SpecialColumnPosition { - get { return specialColumnStyle; } + get { return specialColumnPosition; } set { - if (specialColumnStyle == value) + if (specialColumnPosition == value) return; - specialColumnStyle = value; + specialColumnPosition = value; if (!IsLoaded) return; @@ -158,14 +158,14 @@ namespace osu.Game.Rulesets.Mania.UI /// Whether the column is a special column. private bool isSpecialColumn(int column) { - switch (SpecialColumnStyle) + switch (SpecialColumnPosition) { default: - case SpecialColumnStyle.Normal: + case SpecialColumnPosition.Normal: return columnCount % 2 == 1 && column == columnCount / 2; - case SpecialColumnStyle.Left: + case SpecialColumnPosition.Left: return column == 0; - case SpecialColumnStyle.Right: + case SpecialColumnPosition.Right: return column == columnCount - 1; } } diff --git a/osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs b/osu.Game.Rulesets.Mania/UI/SpecialColumnPosition.cs similarity index 90% rename from osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs rename to osu.Game.Rulesets.Mania/UI/SpecialColumnPosition.cs index 5acb147312..7fd30e7d0d 100644 --- a/osu.Game.Rulesets.Mania/UI/SpecialColumnStyle.cs +++ b/osu.Game.Rulesets.Mania/UI/SpecialColumnPosition.cs @@ -3,7 +3,7 @@ namespace osu.Game.Rulesets.Mania.UI { - public enum SpecialColumnStyle + public enum SpecialColumnPosition { /// /// The special column will lie in the center of the columns. diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 0a781aa30d..e2c6ad9a9f 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -61,7 +61,7 @@ - + From e307b6d563d24bf224909d4af05789ca4f0f2134 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 4 May 2017 15:12:32 +0900 Subject: [PATCH 14/15] Make SpecialColumnPosition only have an effect during load(). --- .../Tests/TestCaseManiaPlayfield.cs | 29 +++++++++++-------- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 25 +--------------- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs index 7e5a564da6..2d4414d19f 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseManiaPlayfield.cs @@ -7,6 +7,7 @@ using osu.Framework.Testing; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.UI; using System.Linq; +using System; namespace osu.Desktop.VisualTests.Tests { @@ -22,27 +23,31 @@ namespace osu.Desktop.VisualTests.Tests const int max_columns = 10; + Action createPlayfield = (cols, pos) => + { + Clear(); + Add(new ManiaPlayfield(cols) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + SpecialColumnPosition = pos + }); + }; + for (int i = 1; i <= max_columns; i++) { int tempI = i; - AddStep($"{i} column" + (i > 1 ? "s" : ""), () => - { - Clear(); - Add(new ManiaPlayfield(tempI) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }); - }); + AddStep($"{i} column" + (i > 1 ? "s" : ""), () => createPlayfield(tempI, SpecialColumnPosition.Normal)); AddStep("Trigger keys down", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyDown)); AddStep("Trigger keys up", () => ((ManiaPlayfield)Children.First()).Columns.Children.ForEach(triggerKeyUp)); - AddStep("Left special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnPosition = SpecialColumnPosition.Left); - AddStep("Right special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnPosition = SpecialColumnPosition.Right); + + AddStep("Left special style", () => createPlayfield(tempI, SpecialColumnPosition.Left)); + AddStep("Right special style", () => createPlayfield(tempI, SpecialColumnPosition.Right)); } - AddStep("Normal special style", () => ((ManiaPlayfield)Children.First()).SpecialColumnPosition = SpecialColumnPosition.Normal); + AddStep("Normal special style", () => createPlayfield(max_columns, SpecialColumnPosition.Normal)); } private void triggerKeyDown(Column column) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index d084326f5b..7b6c134ede 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -27,25 +27,10 @@ namespace osu.Game.Rulesets.Mania.UI /// private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; - private SpecialColumnPosition specialColumnPosition; /// /// The style to use for the special column. /// - public SpecialColumnPosition SpecialColumnPosition - { - get { return specialColumnPosition; } - set - { - if (specialColumnPosition == value) - return; - specialColumnPosition = value; - - if (!IsLoaded) - return; - - updateColumnStyle(); - } - } + public SpecialColumnPosition SpecialColumnPosition; public readonly FlowContainer Columns; @@ -103,14 +88,6 @@ namespace osu.Game.Rulesets.Mania.UI specialColumnColour = colours.BlueDark; - updateColumnStyle(); - } - - /// - /// Updates the column style (special style/colours) + keys. - /// - private void updateColumnStyle() - { // Set the special column + colour + key for (int i = 0; i < columnCount; i++) { From 72b2467e74ba27fedf4d6ea483de4cdb0d89fe60 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 4 May 2017 15:18:20 +0900 Subject: [PATCH 15/15] Throw exception if SpecialColumnPosition is set after IsLoaded. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 7b6c134ede..fa55768382 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -27,10 +27,20 @@ namespace osu.Game.Rulesets.Mania.UI /// private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; + private SpecialColumnPosition specialColumnPosition; /// /// The style to use for the special column. /// - public SpecialColumnPosition SpecialColumnPosition; + public SpecialColumnPosition SpecialColumnPosition + { + get { return specialColumnPosition; } + set + { + if (IsLoaded) + throw new InvalidOperationException($"Setting {nameof(SpecialColumnPosition)} after the playfield is loaded requires re-creating the playfield."); + specialColumnPosition = value; + } + } public readonly FlowContainer Columns;