From e9cbef88f17021032a5cce26d6a616b4648c5a6b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Nov 2017 19:49:55 +0900 Subject: [PATCH] Improve selection/deselection behaviour of RadioButtonCollections --- .../TestCaseEditorComposeRadioButtons.cs | 10 ++- .../RadioButtons/DrawableRadioButton.cs | 72 ++++++++++--------- .../Compose/RadioButtons/RadioButton.cs | 31 ++++++-- .../RadioButtons/RadioButtonCollection.cs | 26 +++++-- 4 files changed, 93 insertions(+), 46 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeRadioButtons.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeRadioButtons.cs index 8c2a07b536..f8669cde4b 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeRadioButtons.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeRadioButtons.cs @@ -14,7 +14,8 @@ namespace osu.Game.Tests.Visual public TestCaseEditorComposeRadioButtons() { - Add(new RadioButtonCollection + RadioButtonCollection collection; + Add(collection = new RadioButtonCollection { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -28,6 +29,13 @@ namespace osu.Game.Tests.Visual new RadioButton("Item 5", () => { }) } }); + + for (int i = 0; i < collection.Items.Count; i++) + { + int l = i; + AddStep($"Select item {l + 1}", () => collection.Items[l].Select()); + AddStep($"Deselect item {l + 1}", () => collection.Items[l].Deselect()); + } } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/DrawableRadioButton.cs b/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/DrawableRadioButton.cs index b3c9983db9..a6c0f48f1f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/DrawableRadioButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/DrawableRadioButton.cs @@ -27,16 +27,34 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons /// /// Invoked when this has been selected. /// - public Action Selected; + public Action Selected; private Drawable bubble; + private readonly RadioButton button; + public DrawableRadioButton(RadioButton button) { + this.button = button; + Text = button.Text; Action = button.Action; RelativeSizeAxes = Axes.X; + + bubble = new CircularContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Scale = new Vector2(0.5f), + X = 10, + Masking = true, + Colour = default_bubble_colour, + Blending = BlendingMode.Additive, + Child = new Box { RelativeSizeAxes = Axes.Both } + }; } [BackgroundDependencyLoader] @@ -53,53 +71,41 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons Colour = Color4.Black.Opacity(0.5f) }; - Add(bubble = new CircularContainer + Add(bubble); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + button.Selected.ValueChanged += v => { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit, - Scale = new Vector2(0.5f), - X = 10, - Masking = true, - Colour = default_bubble_colour, - Blending = BlendingMode.Additive, - Child = new Box { RelativeSizeAxes = Axes.Both } - }); + updateSelectionState(); + if (v) + Selected?.Invoke(button); + }; + + updateSelectionState(); } - private bool isSelected; - - public void Deselect() + private void updateSelectionState() { - if (!isSelected) + if (!IsLoaded) return; - isSelected = false; - BackgroundColour = default_background_colour; - bubble.Colour = default_bubble_colour; - } - - public void Select() - { - if (isSelected) - return; - isSelected = true; - Selected?.Invoke(this); - - BackgroundColour = selected_background_colour; - bubble.Colour = selected_bubble_colour; + BackgroundColour = button.Selected ? selected_background_colour : default_background_colour; + bubble.Colour = button.Selected ? selected_bubble_colour : default_bubble_colour; } protected override bool OnClick(InputState state) { - if (isSelected) + if (button.Selected) return true; if (!Enabled) return true; - Select(); + button.Selected.Value = true; return base.OnClick(state); } diff --git a/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButton.cs b/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButton.cs index bec2d1903d..055362d9e1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButton.cs @@ -2,11 +2,18 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Configuration; namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons { - public struct RadioButton + public class RadioButton { + /// + /// Whether this is selected. + /// + /// + public readonly BindableBool Selected; + /// /// The text that should be displayed in this button. /// @@ -17,16 +24,28 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons /// public Action Action; + public RadioButton(string text, Action action) + { + Text = text; + Action = action; + Selected = new BindableBool(); + } + public RadioButton(string text) + : this(text, null) { Text = text; Action = null; } - public RadioButton(string text, Action action) - { - Text = text; - Action = action; - } + /// + /// Selects this . + /// + public void Select() => Selected.Value = true; + + /// + /// Deselects this . + /// + public void Deselect() => Selected.Value = false; } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButtonCollection.cs b/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButtonCollection.cs index 8a3194b72e..ad24a1da52 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButtonCollection.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/RadioButtons/RadioButtonCollection.cs @@ -11,10 +11,16 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons { public class RadioButtonCollection : CompositeDrawable { + private IReadOnlyList items; public IReadOnlyList Items { + get { return items; } set { + if (items == value) + return; + items = value; + buttonContainer.Clear(); value.ForEach(addButton); } @@ -35,13 +41,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons }; } - private void addButton(RadioButton button) => buttonContainer.Add(new DrawableRadioButton(button) { Selected = buttonSelected }); - - private DrawableRadioButton currentlySelected; - private void buttonSelected(DrawableRadioButton drawableButton) + private RadioButton currentlySelected; + private void addButton(RadioButton button) { - currentlySelected?.Deselect(); - currentlySelected = drawableButton; + button.Selected.ValueChanged += v => + { + if (v) + { + currentlySelected?.Deselect(); + currentlySelected = button; + } + else + currentlySelected = null; + }; + + buttonContainer.Add(new DrawableRadioButton(button)); } } }