1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 14:03:21 +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()
{
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());
}
}
}
}

View File

@ -27,16 +27,34 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
/// <summary>
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
/// </summary>
public Action<DrawableRadioButton> Selected;
public Action<RadioButton> 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);
}

View File

@ -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
{
/// <summary>
/// Whether this <see cref="RadioButton"/> is selected.
/// </summary>
/// <returns></returns>
public readonly BindableBool Selected;
/// <summary>
/// The text that should be displayed in this button.
/// </summary>
@ -17,16 +24,28 @@ namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
/// </summary>
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;
}
/// <summary>
/// Selects this <see cref="RadioButton"/>.
/// </summary>
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
{
private IReadOnlyList<RadioButton> items;
public IReadOnlyList<RadioButton> 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));
}
}
}