1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 16:12:57 +08:00

Improve selection/deselection behaviour of RadioButtonCollections

This commit is contained in:
smoogipoo 2017-11-30 19:49:55 +09:00
parent 677f3653eb
commit e9cbef88f1
4 changed files with 93 additions and 46 deletions

View File

@ -14,7 +14,8 @@ namespace osu.Game.Tests.Visual
public TestCaseEditorComposeRadioButtons() public TestCaseEditorComposeRadioButtons()
{ {
Add(new RadioButtonCollection RadioButtonCollection collection;
Add(collection = new RadioButtonCollection
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -28,6 +29,13 @@ namespace osu.Game.Tests.Visual
new RadioButton("Item 5", () => { }) 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());
}
} }
} }
} }

View File

@ -27,16 +27,34 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
/// <summary> /// <summary>
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected. /// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
/// </summary> /// </summary>
public Action<DrawableRadioButton> Selected; public Action<RadioButton> Selected;
private Drawable bubble; private Drawable bubble;
private readonly RadioButton button;
public DrawableRadioButton(RadioButton button) public DrawableRadioButton(RadioButton button)
{ {
this.button = button;
Text = button.Text; Text = button.Text;
Action = button.Action; Action = button.Action;
RelativeSizeAxes = Axes.X; 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] [BackgroundDependencyLoader]
@ -53,53 +71,41 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
Colour = Color4.Black.Opacity(0.5f) Colour = Color4.Black.Opacity(0.5f)
}; };
Add(bubble = new CircularContainer Add(bubble);
{
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 }
});
} }
private bool isSelected; protected override void LoadComplete()
public void Deselect()
{ {
if (!isSelected) base.LoadComplete();
return;
isSelected = false;
BackgroundColour = default_background_colour; button.Selected.ValueChanged += v =>
bubble.Colour = default_bubble_colour; {
updateSelectionState();
if (v)
Selected?.Invoke(button);
};
updateSelectionState();
} }
public void Select() private void updateSelectionState()
{ {
if (isSelected) if (!IsLoaded)
return; return;
isSelected = true;
Selected?.Invoke(this);
BackgroundColour = selected_background_colour; BackgroundColour = button.Selected ? selected_background_colour : default_background_colour;
bubble.Colour = selected_bubble_colour; bubble.Colour = button.Selected ? selected_bubble_colour : default_bubble_colour;
} }
protected override bool OnClick(InputState state) protected override bool OnClick(InputState state)
{ {
if (isSelected) if (button.Selected)
return true; return true;
if (!Enabled) if (!Enabled)
return true; return true;
Select(); button.Selected.Value = true;
return base.OnClick(state); return base.OnClick(state);
} }

View File

@ -2,11 +2,18 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System; using System;
using osu.Framework.Configuration;
namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
{ {
public struct RadioButton public class RadioButton
{ {
/// <summary>
/// Whether this <see cref="RadioButton"/> is selected.
/// </summary>
/// <returns></returns>
public readonly BindableBool Selected;
/// <summary> /// <summary>
/// The text that should be displayed in this button. /// The text that should be displayed in this button.
/// </summary> /// </summary>
@ -17,16 +24,28 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
/// </summary> /// </summary>
public Action Action; public Action Action;
public RadioButton(string text, Action action)
{
Text = text;
Action = action;
Selected = new BindableBool();
}
public RadioButton(string text) public RadioButton(string text)
: this(text, null)
{ {
Text = text; Text = text;
Action = null; Action = null;
} }
public RadioButton(string text, Action action) /// <summary>
{ /// Selects this <see cref="RadioButton"/>.
Text = text; /// </summary>
Action = action; public void Select() => Selected.Value = true;
}
/// <summary>
/// Deselects this <see cref="RadioButton"/>.
/// </summary>
public void Deselect() => Selected.Value = false;
} }
} }

View File

@ -11,10 +11,16 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
{ {
public class RadioButtonCollection : CompositeDrawable public class RadioButtonCollection : CompositeDrawable
{ {
private IReadOnlyList<RadioButton> items;
public IReadOnlyList<RadioButton> Items public IReadOnlyList<RadioButton> Items
{ {
get { return items; }
set set
{ {
if (items == value)
return;
items = value;
buttonContainer.Clear(); buttonContainer.Clear();
value.ForEach(addButton); 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 RadioButton currentlySelected;
private void addButton(RadioButton button)
private DrawableRadioButton currentlySelected; {
private void buttonSelected(DrawableRadioButton drawableButton) button.Selected.ValueChanged += v =>
{
if (v)
{ {
currentlySelected?.Deselect(); currentlySelected?.Deselect();
currentlySelected = drawableButton; currentlySelected = button;
}
else
currentlySelected = null;
};
buttonContainer.Add(new DrawableRadioButton(button));
} }
} }
} }