mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 08:33:55 +09:00
Merge pull request #10243 from peppy/editor-ternary-buttons
Add ternary toggle buttons to editor toolbox selection
This commit is contained in:
@ -9,7 +9,9 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Caching;
|
using osu.Framework.Caching;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -17,6 +19,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Screens.Edit.Components.TernaryButtons;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -39,11 +42,11 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
new SpinnerCompositionTool()
|
new SpinnerCompositionTool()
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly BindableBool distanceSnapToggle = new BindableBool(true) { Description = "Distance Snap" };
|
private readonly Bindable<TernaryState> distanceSnapToggle = new Bindable<TernaryState>();
|
||||||
|
|
||||||
protected override IEnumerable<Bindable<bool>> Toggles => base.Toggles.Concat(new[]
|
protected override IEnumerable<TernaryButton> CreateTernaryButtons() => base.CreateTernaryButtons().Concat(new[]
|
||||||
{
|
{
|
||||||
distanceSnapToggle
|
new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler })
|
||||||
});
|
});
|
||||||
|
|
||||||
private BindableList<HitObject> selectedHitObjects;
|
private BindableList<HitObject> selectedHitObjects;
|
||||||
@ -156,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
distanceSnapGridCache.Invalidate();
|
distanceSnapGridCache.Invalidate();
|
||||||
distanceSnapGrid = null;
|
distanceSnapGrid = null;
|
||||||
|
|
||||||
if (!distanceSnapToggle.Value)
|
if (distanceSnapToggle.Value != TernaryState.True)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (BlueprintContainer.CurrentTool)
|
switch (BlueprintContainer.CurrentTool)
|
||||||
|
@ -17,6 +17,11 @@ namespace osu.Game.Audio
|
|||||||
public const string HIT_NORMAL = @"hitnormal";
|
public const string HIT_NORMAL = @"hitnormal";
|
||||||
public const string HIT_CLAP = @"hitclap";
|
public const string HIT_CLAP = @"hitclap";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All valid sample addition constants.
|
||||||
|
/// </summary>
|
||||||
|
public static IEnumerable<string> AllAdditions => new[] { HIT_WHISTLE, HIT_CLAP, HIT_FINISH };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The bank to load the sample from.
|
/// The bank to load the sample from.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
@ -14,7 +13,6 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Overlays.Settings;
|
|
||||||
using osu.Game.Rulesets.Configuration;
|
using osu.Game.Rulesets.Configuration;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -24,6 +22,7 @@ using osu.Game.Rulesets.UI;
|
|||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
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;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -63,7 +62,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
private RadioButtonCollection toolboxCollection;
|
private RadioButtonCollection toolboxCollection;
|
||||||
|
|
||||||
private ToolboxGroup togglesCollection;
|
private FillFlowContainer togglesCollection;
|
||||||
|
|
||||||
protected HitObjectComposer(Ruleset ruleset)
|
protected HitObjectComposer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
@ -121,14 +120,19 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
Spacing = new Vector2(10),
|
Spacing = new Vector2(10),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new ToolboxGroup("toolbox") { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } },
|
new ToolboxGroup("toolbox (1-9)")
|
||||||
togglesCollection = new ToolboxGroup("toggles")
|
|
||||||
{
|
{
|
||||||
ChildrenEnumerable = Toggles.Select(b => new SettingsCheckbox
|
Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X }
|
||||||
|
},
|
||||||
|
new ToolboxGroup("toggles (Q~P)")
|
||||||
|
{
|
||||||
|
Child = togglesCollection = new FillFlowContainer
|
||||||
{
|
{
|
||||||
Bindable = b,
|
RelativeSizeAxes = Axes.X,
|
||||||
LabelText = b?.Description ?? "unknown"
|
AutoSizeAxes = Axes.Y,
|
||||||
})
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 5),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -139,6 +143,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
.Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon))
|
.Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
TernaryStates = CreateTernaryButtons().ToArray();
|
||||||
|
togglesCollection.AddRange(TernaryStates.Select(b => new DrawableTernaryButton(b)));
|
||||||
|
|
||||||
setSelectTool();
|
setSelectTool();
|
||||||
|
|
||||||
EditorBeatmap.SelectedHitObjects.CollectionChanged += selectionChanged;
|
EditorBeatmap.SelectedHitObjects.CollectionChanged += selectionChanged;
|
||||||
@ -167,10 +174,14 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of toggles which will be displayed to the user.
|
/// A collection of states which will be displayed to the user in the toolbox.
|
||||||
/// The display name will be decided by <see cref="Bindable{T}.Description"/>.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual IEnumerable<Bindable<bool>> Toggles => BlueprintContainer.Toggles;
|
public TernaryButton[] TernaryStates { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create all ternary states required to be displayed to the user.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual IEnumerable<TernaryButton> CreateTernaryButtons() => BlueprintContainer.TernaryStates;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic.
|
/// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic.
|
||||||
@ -215,9 +226,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
var item = togglesCollection.ElementAtOrDefault(rightIndex);
|
var item = togglesCollection.ElementAtOrDefault(rightIndex);
|
||||||
|
|
||||||
if (item is SettingsCheckbox checkbox)
|
if (item is DrawableTernaryButton button)
|
||||||
{
|
{
|
||||||
checkbox.Bindable.Value = !checkbox.Bindable.Value;
|
button.Button.Toggle();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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<TernaryState> Bindable;
|
||||||
|
|
||||||
|
public readonly string Description;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A function which creates a drawable icon to represent this item. If null, a sane default should be used.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Func<Drawable> CreateIcon;
|
||||||
|
|
||||||
|
public TernaryButton(Bindable<TernaryState> bindable, string description, Func<Drawable> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,15 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Screens.Edit.Components.TernaryButtons;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Compose.Components
|
namespace osu.Game.Screens.Edit.Compose.Components
|
||||||
@ -48,6 +51,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
TernaryStates = CreateTernaryButtons().ToArray();
|
||||||
|
|
||||||
AddInternal(placementBlueprintContainer);
|
AddInternal(placementBlueprintContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,36 +62,34 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
inputManager = GetContainingInputManager();
|
inputManager = GetContainingInputManager();
|
||||||
|
|
||||||
Beatmap.SelectedHitObjects.CollectionChanged += (_, __) => updateTogglesFromSelection();
|
// updates to selected are handled for us by SelectionHandler.
|
||||||
|
NewCombo.BindTo(SelectionHandler.SelectionNewComboState);
|
||||||
// the updated object may be in the selection
|
|
||||||
Beatmap.HitObjectUpdated += _ => updateTogglesFromSelection();
|
|
||||||
|
|
||||||
|
// we are responsible for current placement blueprint updated based on state changes.
|
||||||
NewCombo.ValueChanged += combo =>
|
NewCombo.ValueChanged += combo =>
|
||||||
{
|
{
|
||||||
if (Beatmap.SelectedHitObjects.Count > 0)
|
if (currentPlacement == null) return;
|
||||||
{
|
|
||||||
SelectionHandler.SetNewCombo(combo.NewValue);
|
if (currentPlacement.HitObject is IHasComboInformation c)
|
||||||
}
|
c.NewCombo = combo.NewValue == TernaryState.True;
|
||||||
else if (currentPlacement != null)
|
|
||||||
{
|
|
||||||
// update placement object from toggle
|
|
||||||
if (currentPlacement.HitObject is IHasComboInformation c)
|
|
||||||
c.NewCombo = combo.NewValue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTogglesFromSelection() =>
|
public readonly Bindable<TernaryState> NewCombo = new Bindable<TernaryState> { Description = "New Combo" };
|
||||||
NewCombo.Value = Beatmap.SelectedHitObjects.OfType<IHasComboInformation>().All(c => c.NewCombo);
|
|
||||||
|
|
||||||
public readonly Bindable<bool> NewCombo = new Bindable<bool> { Description = "New Combo" };
|
/// <summary>
|
||||||
|
/// A collection of states which will be displayed to the user in the toolbox.
|
||||||
|
/// </summary>
|
||||||
|
public TernaryButton[] TernaryStates { get; private set; }
|
||||||
|
|
||||||
public virtual IEnumerable<Bindable<bool>> Toggles => new[]
|
/// <summary>
|
||||||
|
/// Create all ternary states required to be displayed to the user.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual IEnumerable<TernaryButton> CreateTernaryButtons()
|
||||||
{
|
{
|
||||||
//TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects.
|
//TODO: this should only be enabled (visible?) for rulesets that provide combo-supporting HitObjects.
|
||||||
NewCombo
|
yield return new TernaryButton(NewCombo, "New combo", () => new SpriteIcon { Icon = FontAwesome.Regular.DotCircle });
|
||||||
};
|
}
|
||||||
|
|
||||||
#region Placement
|
#region Placement
|
||||||
|
|
||||||
|
@ -316,19 +316,22 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
#region Selection State
|
#region Selection State
|
||||||
|
|
||||||
private readonly Bindable<TernaryState> selectionNewComboState = new Bindable<TernaryState>();
|
/// <summary>
|
||||||
|
/// The state of "new combo" for all selected hitobjects.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Bindable<TernaryState> SelectionNewComboState = new Bindable<TernaryState>();
|
||||||
|
|
||||||
private readonly Dictionary<string, Bindable<TernaryState>> selectionSampleStates = new Dictionary<string, Bindable<TernaryState>>();
|
/// <summary>
|
||||||
|
/// The state of each sample type for all selected hitobjects. Keys match with <see cref="HitSampleInfo"/> constant specifications.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Dictionary<string, Bindable<TernaryState>> SelectionSampleStates = new Dictionary<string, Bindable<TernaryState>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set up ternary state bindables and bind them to selection/hitobject changes (in both directions)
|
/// Set up ternary state bindables and bind them to selection/hitobject changes (in both directions)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void createStateBindables()
|
private void createStateBindables()
|
||||||
{
|
{
|
||||||
// hit samples
|
foreach (var sampleName in HitSampleInfo.AllAdditions)
|
||||||
var sampleTypes = new[] { HitSampleInfo.HIT_WHISTLE, HitSampleInfo.HIT_CLAP, HitSampleInfo.HIT_FINISH };
|
|
||||||
|
|
||||||
foreach (var sampleName in sampleTypes)
|
|
||||||
{
|
{
|
||||||
var bindable = new Bindable<TernaryState>
|
var bindable = new Bindable<TernaryState>
|
||||||
{
|
{
|
||||||
@ -349,11 +352,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
selectionSampleStates[sampleName] = bindable;
|
SelectionSampleStates[sampleName] = bindable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// new combo
|
// new combo
|
||||||
selectionNewComboState.ValueChanged += state =>
|
SelectionNewComboState.ValueChanged += state =>
|
||||||
{
|
{
|
||||||
switch (state.NewValue)
|
switch (state.NewValue)
|
||||||
{
|
{
|
||||||
@ -377,9 +380,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void UpdateTernaryStates()
|
protected virtual void UpdateTernaryStates()
|
||||||
{
|
{
|
||||||
selectionNewComboState.Value = GetStateFromSelection(SelectedHitObjects.OfType<IHasComboInformation>(), h => h.NewCombo);
|
SelectionNewComboState.Value = GetStateFromSelection(SelectedHitObjects.OfType<IHasComboInformation>(), 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));
|
bindable.Value = GetStateFromSelection(SelectedHitObjects, h => h.Samples.Any(s => s.Name == sampleName));
|
||||||
}
|
}
|
||||||
@ -413,7 +416,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
if (selectedBlueprints.All(b => b.HitObject is IHasComboInformation))
|
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)
|
if (selectedBlueprints.Count == 1)
|
||||||
@ -423,7 +426,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
{
|
{
|
||||||
new OsuMenuItem("Sound")
|
new OsuMenuItem("Sound")
|
||||||
{
|
{
|
||||||
Items = selectionSampleStates.Select(kvp =>
|
Items = SelectionSampleStates.Select(kvp =>
|
||||||
new TernaryStateMenuItem(kvp.Value.Description) { State = { BindTarget = kvp.Value } }).ToArray()
|
new TernaryStateMenuItem(kvp.Value.Description) { State = { BindTarget = kvp.Value } }).ToArray()
|
||||||
},
|
},
|
||||||
new OsuMenuItem("Delete", MenuItemType.Destructive, deleteSelected),
|
new OsuMenuItem("Delete", MenuItemType.Destructive, deleteSelected),
|
||||||
|
Reference in New Issue
Block a user