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:
parent
677f3653eb
commit
e9cbef88f1
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user