From ae68dcd962090efe418228f4c11c09d166a12af1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 16:33:22 +0900 Subject: [PATCH 1/7] Add ternary toggle buttons to editor toolbox selection --- .../Edit/OsuHitObjectComposer.cs | 11 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 14 +-- .../TernaryButtons/DrawableTernaryButton.cs | 112 ++++++++++++++++++ .../TernaryButtons/TernaryButton.cs | 44 +++++++ .../Components/ComposeBlueprintContainer.cs | 29 ++--- .../Compose/Components/SelectionHandler.cs | 22 ++-- 6 files changed, 194 insertions(+), 38 deletions(-) create mode 100644 osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs create mode 100644 osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 0d0a139a8a..49af80dd63 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -9,7 +9,9 @@ using osu.Framework.Bindables; using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; @@ -17,6 +19,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; @@ -39,11 +42,11 @@ namespace osu.Game.Rulesets.Osu.Edit new SpinnerCompositionTool() }; - private readonly BindableBool distanceSnapToggle = new BindableBool(true) { Description = "Distance Snap" }; + private readonly Bindable distanceSnapToggle = new Bindable(); - protected override IEnumerable> Toggles => base.Toggles.Concat(new[] + protected override IEnumerable Toggles => base.Toggles.Concat(new[] { - distanceSnapToggle + new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler }) }); private BindableList selectedHitObjects; @@ -156,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Edit distanceSnapGridCache.Invalidate(); distanceSnapGrid = null; - if (!distanceSnapToggle.Value) + if (distanceSnapToggle.Value != TernaryState.True) return; switch (BlueprintContainer.CurrentTool) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index b2d7c40a22..afef542e36 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -14,7 +14,6 @@ using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; @@ -24,6 +23,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Components.RadioButtons; +using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; using osuTK; @@ -124,11 +124,7 @@ namespace osu.Game.Rulesets.Edit new ToolboxGroup("toolbox") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } }, togglesCollection = new ToolboxGroup("toggles") { - ChildrenEnumerable = Toggles.Select(b => new SettingsCheckbox - { - Bindable = b, - LabelText = b?.Description ?? "unknown" - }) + ChildrenEnumerable = Toggles.Select(b => new DrawableTernaryButton(b)) } } }, @@ -170,7 +166,7 @@ namespace osu.Game.Rulesets.Edit /// A collection of toggles which will be displayed to the user. /// The display name will be decided by . /// - protected virtual IEnumerable> Toggles => BlueprintContainer.Toggles; + protected virtual IEnumerable Toggles => BlueprintContainer.Toggles; /// /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. @@ -212,9 +208,9 @@ namespace osu.Game.Rulesets.Edit { var item = togglesCollection.Children[rightIndex]; - if (item is SettingsCheckbox checkbox) + if (item is DrawableTernaryButton button) { - checkbox.Bindable.Value = !checkbox.Bindable.Value; + button.Button.Toggle(); return true; } } diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs new file mode 100644 index 0000000000..c72fff5c91 --- /dev/null +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs @@ -0,0 +1,112 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Edit.Components.TernaryButtons +{ + internal class DrawableTernaryButton : TriangleButton + { + private Color4 defaultBackgroundColour; + private Color4 defaultBubbleColour; + private Color4 selectedBackgroundColour; + private Color4 selectedBubbleColour; + + private Drawable icon; + + public readonly TernaryButton Button; + + public DrawableTernaryButton(TernaryButton button) + { + Button = button; + + Text = button.Description; + + RelativeSizeAxes = Axes.X; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + defaultBackgroundColour = colours.Gray3; + defaultBubbleColour = defaultBackgroundColour.Darken(0.5f); + selectedBackgroundColour = colours.BlueDark; + selectedBubbleColour = selectedBackgroundColour.Lighten(0.5f); + + Triangles.Alpha = 0; + + Content.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = 2, + Offset = new Vector2(0, 1), + Colour = Color4.Black.Opacity(0.5f) + }; + + Add(icon = (Button.CreateIcon?.Invoke() ?? new Circle()).With(b => + { + b.Blending = BlendingParameters.Additive; + b.Anchor = Anchor.CentreLeft; + b.Origin = Anchor.CentreLeft; + b.Size = new Vector2(20); + b.X = 10; + })); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Button.Bindable.BindValueChanged(selected => updateSelectionState(), true); + + Action = onAction; + } + + private void onAction() + { + Button.Toggle(); + } + + private void updateSelectionState() + { + if (!IsLoaded) + return; + + switch (Button.Bindable.Value) + { + case TernaryState.Indeterminate: + icon.Colour = selectedBubbleColour.Darken(0.5f); + BackgroundColour = selectedBackgroundColour.Darken(0.5f); + break; + + case TernaryState.False: + icon.Colour = defaultBubbleColour; + BackgroundColour = defaultBackgroundColour; + break; + + case TernaryState.True: + icon.Colour = selectedBubbleColour; + BackgroundColour = selectedBackgroundColour; + break; + } + } + + protected override SpriteText CreateText() => new OsuSpriteText + { + Depth = -1, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + X = 40f + }; + } +} diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs new file mode 100644 index 0000000000..7f64695bde --- /dev/null +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs @@ -0,0 +1,44 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Components.TernaryButtons +{ + public class TernaryButton + { + public readonly Bindable Bindable; + + public readonly string Description; + + /// + /// A function which creates a drawable icon to represent this item. If null, a sane default should be used. + /// + public readonly Func CreateIcon; + + public TernaryButton(Bindable bindable, string description, Func createIcon = null) + { + Bindable = bindable; + Description = description; + CreateIcon = createIcon; + } + + public void Toggle() + { + switch (Bindable.Value) + { + case TernaryState.False: + case TernaryState.Indeterminate: + Bindable.Value = TernaryState.True; + break; + + case TernaryState.True: + Bindable.Value = TernaryState.False; + break; + } + } + } +} diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 6f66c1bd6f..91eab18acb 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -7,12 +7,16 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Screens.Edit.Components.TernaryButtons; using osuTK; namespace osu.Game.Screens.Edit.Compose.Components @@ -57,35 +61,26 @@ namespace osu.Game.Screens.Edit.Compose.Components inputManager = GetContainingInputManager(); - Beatmap.SelectedHitObjects.CollectionChanged += (_, __) => updateTogglesFromSelection(); - - // the updated object may be in the selection - Beatmap.HitObjectUpdated += _ => updateTogglesFromSelection(); + // updates to selected are handled for us by SelectionHandler. + NewCombo.BindTo(SelectionHandler.SelectionNewComboState); + // we are responsible for current placement blueprint updated based on state changes. NewCombo.ValueChanged += combo => { - if (Beatmap.SelectedHitObjects.Count > 0) + if (currentPlacement != null) { - SelectionHandler.SetNewCombo(combo.NewValue); - } - else if (currentPlacement != null) - { - // update placement object from toggle if (currentPlacement.HitObject is IHasComboInformation c) - c.NewCombo = combo.NewValue; + c.NewCombo = combo.NewValue == TernaryState.True; } }; } - private void updateTogglesFromSelection() => - NewCombo.Value = Beatmap.SelectedHitObjects.OfType().All(c => c.NewCombo); + public readonly Bindable NewCombo = new Bindable { Description = "New Combo" }; - public readonly Bindable NewCombo = new Bindable { Description = "New Combo" }; - - public virtual IEnumerable> Toggles => new[] + public virtual IEnumerable Toggles => new[] { //TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects. - NewCombo + new TernaryButton(NewCombo, "New combo", () => new SpriteIcon { Icon = FontAwesome.Regular.DotCircle }) }; #region Placement diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index a316f34ad0..ed956357b6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -316,9 +316,15 @@ namespace osu.Game.Screens.Edit.Compose.Components #region Selection State - private readonly Bindable selectionNewComboState = new Bindable(); + /// + /// The state of "new combo" for all selected hitobjects. + /// + public readonly Bindable SelectionNewComboState = new Bindable(); - private readonly Dictionary> selectionSampleStates = new Dictionary>(); + /// + /// The state of each sample type for all selected hitobjects. Keys match with constant specifications. + /// + public readonly Dictionary> SelectionSampleStates = new Dictionary>(); /// /// Set up ternary state bindables and bind them to selection/hitobject changes (in both directions) @@ -349,11 +355,11 @@ namespace osu.Game.Screens.Edit.Compose.Components } }; - selectionSampleStates[sampleName] = bindable; + SelectionSampleStates[sampleName] = bindable; } // new combo - selectionNewComboState.ValueChanged += state => + SelectionNewComboState.ValueChanged += state => { switch (state.NewValue) { @@ -377,9 +383,9 @@ namespace osu.Game.Screens.Edit.Compose.Components /// protected virtual void UpdateTernaryStates() { - selectionNewComboState.Value = GetStateFromSelection(SelectedHitObjects.OfType(), h => h.NewCombo); + SelectionNewComboState.Value = GetStateFromSelection(SelectedHitObjects.OfType(), h => h.NewCombo); - foreach (var (sampleName, bindable) in selectionSampleStates) + foreach (var (sampleName, bindable) in SelectionSampleStates) { bindable.Value = GetStateFromSelection(SelectedHitObjects, h => h.Samples.Any(s => s.Name == sampleName)); } @@ -413,7 +419,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (selectedBlueprints.All(b => b.HitObject is IHasComboInformation)) { - items.Add(new TernaryStateMenuItem("New combo") { State = { BindTarget = selectionNewComboState } }); + items.Add(new TernaryStateMenuItem("New combo") { State = { BindTarget = SelectionNewComboState } }); } if (selectedBlueprints.Count == 1) @@ -423,7 +429,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { new OsuMenuItem("Sound") { - Items = selectionSampleStates.Select(kvp => + Items = SelectionSampleStates.Select(kvp => new TernaryStateMenuItem(kvp.Value.Description) { State = { BindTarget = kvp.Value } }).ToArray() }, new OsuMenuItem("Delete", MenuItemType.Destructive, deleteSelected), From a6298c60eb30d5c7f0bf5dc8422148f531c315ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 16:44:37 +0900 Subject: [PATCH 2/7] Fix button spacing --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index afef542e36..f823d37060 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Edit private RadioButtonCollection toolboxCollection; - private ToolboxGroup togglesCollection; + private FillFlowContainer togglesCollection; protected HitObjectComposer(Ruleset ruleset) { @@ -121,10 +121,20 @@ namespace osu.Game.Rulesets.Edit Spacing = new Vector2(10), Children = new Drawable[] { - new ToolboxGroup("toolbox") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } }, - togglesCollection = new ToolboxGroup("toggles") + new ToolboxGroup("toolbox") { - ChildrenEnumerable = Toggles.Select(b => new DrawableTernaryButton(b)) + Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } + }, + new ToolboxGroup("toggles") + { + Child = togglesCollection = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + ChildrenEnumerable = Toggles.Select(b => new DrawableTernaryButton(b)) + }, } } }, From da820c815e5fc97a350669e9904d2700c25fbe44 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 16:46:06 +0900 Subject: [PATCH 3/7] Add shortcut keys to toolbox gorup titles --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index f823d37060..a592500a87 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -121,11 +121,11 @@ namespace osu.Game.Rulesets.Edit Spacing = new Vector2(10), Children = new Drawable[] { - new ToolboxGroup("toolbox") + new ToolboxGroup("toolbox (1-9)") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } }, - new ToolboxGroup("toggles") + new ToolboxGroup("toggles (Q~P)") { Child = togglesCollection = new FillFlowContainer { From 98c6027352deb80fd0d80e9bc5abcb12ead00552 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 17:07:58 +0900 Subject: [PATCH 4/7] Remove unused using --- .../Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 91eab18acb..cab277f10b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; From b8e9f19b92195f8c6e270540c9d77f8a17b5e2c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 17:30:31 +0900 Subject: [PATCH 5/7] Move common HitSampleInfo lookup to static method --- osu.Game/Audio/HitSampleInfo.cs | 5 +++++ osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index f6b0107bd2..8b1f5a366a 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -17,6 +17,11 @@ namespace osu.Game.Audio public const string HIT_NORMAL = @"hitnormal"; public const string HIT_CLAP = @"hitclap"; + /// + /// All valid sample addition constants. + /// + public static IEnumerable AllAdditions => new[] { HIT_WHISTLE, HIT_CLAP, HIT_FINISH }; + /// /// The bank to load the sample from. /// diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index ed956357b6..6ca85fe026 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -331,10 +331,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// private void createStateBindables() { - // hit samples - var sampleTypes = new[] { HitSampleInfo.HIT_WHISTLE, HitSampleInfo.HIT_CLAP, HitSampleInfo.HIT_FINISH }; - - foreach (var sampleName in sampleTypes) + foreach (var sampleName in HitSampleInfo.AllAdditions) { var bindable = new Bindable { From 22511c36c3b0d306418b55adbb61376796f85187 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 17:40:43 +0900 Subject: [PATCH 6/7] Ensure toggles are not instantiated more than once for safety --- .../Edit/OsuHitObjectComposer.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 8 ++++++-- .../Components/ComposeBlueprintContainer.cs | 19 +++++++++++-------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 49af80dd63..a4dd463ea5 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Edit private readonly Bindable distanceSnapToggle = new Bindable(); - protected override IEnumerable Toggles => base.Toggles.Concat(new[] + protected override IEnumerable CreateToggles() => base.CreateToggles().Concat(new[] { new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler }) }); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index a592500a87..e692f8d606 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -133,7 +133,6 @@ namespace osu.Game.Rulesets.Edit AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 5), - ChildrenEnumerable = Toggles.Select(b => new DrawableTernaryButton(b)) }, } } @@ -145,6 +144,9 @@ namespace osu.Game.Rulesets.Edit .Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon)) .ToList(); + Toggles = CreateToggles().ToArray(); + togglesCollection.AddRange(Toggles.Select(b => new DrawableTernaryButton(b))); + setSelectTool(); EditorBeatmap.SelectedHitObjects.CollectionChanged += selectionChanged; @@ -176,7 +178,9 @@ namespace osu.Game.Rulesets.Edit /// A collection of toggles which will be displayed to the user. /// The display name will be decided by . /// - protected virtual IEnumerable Toggles => BlueprintContainer.Toggles; + public TernaryButton[] Toggles { get; private set; } + + protected virtual IEnumerable CreateToggles() => BlueprintContainer.Toggles; /// /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index cab277f10b..0f4bab8b33 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -51,6 +51,8 @@ namespace osu.Game.Screens.Edit.Compose.Components [BackgroundDependencyLoader] private void load() { + Toggles = CreateToggles().ToArray(); + AddInternal(placementBlueprintContainer); } @@ -66,21 +68,22 @@ namespace osu.Game.Screens.Edit.Compose.Components // we are responsible for current placement blueprint updated based on state changes. NewCombo.ValueChanged += combo => { - if (currentPlacement != null) - { - if (currentPlacement.HitObject is IHasComboInformation c) - c.NewCombo = combo.NewValue == TernaryState.True; - } + if (currentPlacement == null) return; + + if (currentPlacement.HitObject is IHasComboInformation c) + c.NewCombo = combo.NewValue == TernaryState.True; }; } public readonly Bindable NewCombo = new Bindable { Description = "New Combo" }; - public virtual IEnumerable Toggles => new[] + public TernaryButton[] Toggles { get; private set; } + + protected virtual IEnumerable CreateToggles() { //TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects. - new TernaryButton(NewCombo, "New combo", () => new SpriteIcon { Icon = FontAwesome.Regular.DotCircle }) - }; + yield return new TernaryButton(NewCombo, "New combo", () => new SpriteIcon { Icon = FontAwesome.Regular.DotCircle }); + } #region Placement From 346d14d40bfc09d0da125c0850dafe587eccb376 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Sep 2020 17:45:19 +0900 Subject: [PATCH 7/7] Rename variables to match --- .../Edit/OsuHitObjectComposer.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 15 ++++++++------- .../Components/ComposeBlueprintContainer.cs | 12 +++++++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index a4dd463ea5..912a705d16 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Edit private readonly Bindable distanceSnapToggle = new Bindable(); - protected override IEnumerable CreateToggles() => base.CreateToggles().Concat(new[] + protected override IEnumerable CreateTernaryButtons() => base.CreateTernaryButtons().Concat(new[] { new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler }) }); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e692f8d606..3ad2394420 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -144,8 +143,8 @@ namespace osu.Game.Rulesets.Edit .Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon)) .ToList(); - Toggles = CreateToggles().ToArray(); - togglesCollection.AddRange(Toggles.Select(b => new DrawableTernaryButton(b))); + TernaryStates = CreateTernaryButtons().ToArray(); + togglesCollection.AddRange(TernaryStates.Select(b => new DrawableTernaryButton(b))); setSelectTool(); @@ -175,12 +174,14 @@ namespace osu.Game.Rulesets.Edit protected abstract IReadOnlyList CompositionTools { get; } /// - /// A collection of toggles which will be displayed to the user. - /// The display name will be decided by . + /// A collection of states which will be displayed to the user in the toolbox. /// - public TernaryButton[] Toggles { get; private set; } + public TernaryButton[] TernaryStates { get; private set; } - protected virtual IEnumerable CreateToggles() => BlueprintContainer.Toggles; + /// + /// Create all ternary states required to be displayed to the user. + /// + protected virtual IEnumerable CreateTernaryButtons() => BlueprintContainer.TernaryStates; /// /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 0f4bab8b33..88c3170c34 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Compose.Components [BackgroundDependencyLoader] private void load() { - Toggles = CreateToggles().ToArray(); + TernaryStates = CreateTernaryButtons().ToArray(); AddInternal(placementBlueprintContainer); } @@ -77,9 +77,15 @@ namespace osu.Game.Screens.Edit.Compose.Components public readonly Bindable NewCombo = new Bindable { Description = "New Combo" }; - public TernaryButton[] Toggles { get; private set; } + /// + /// A collection of states which will be displayed to the user in the toolbox. + /// + public TernaryButton[] TernaryStates { get; private set; } - protected virtual IEnumerable CreateToggles() + /// + /// Create all ternary states required to be displayed to the user. + /// + protected virtual IEnumerable CreateTernaryButtons() { //TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects. yield return new TernaryButton(NewCombo, "New combo", () => new SpriteIcon { Icon = FontAwesome.Regular.DotCircle });