mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 21:07:33 +08:00
Merge pull request #1636 from smoogipoo/editor-composer
Implement structure for Editor HitObject composition
This commit is contained in:
commit
58777a9674
13
osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs
Normal file
13
osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class OsuEditPlayfield : OsuPlayfield
|
||||
{
|
||||
protected override CursorContainer CreateCursor() => null;
|
||||
}
|
||||
}
|
19
osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
Normal file
19
osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class OsuEditRulesetContainer : OsuRulesetContainer
|
||||
{
|
||||
public OsuEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Playfield CreatePlayfield() => new OsuEditPlayfield();
|
||||
}
|
||||
}
|
29
osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
Normal file
29
osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class OsuHitObjectComposer : HitObjectComposer
|
||||
{
|
||||
public OsuHitObjectComposer(Ruleset ruleset)
|
||||
: base(ruleset)
|
||||
{
|
||||
}
|
||||
|
||||
protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new OsuEditRulesetContainer(ruleset, beatmap, true);
|
||||
|
||||
protected override IReadOnlyList<ICompositionTool> CompositionTools => new ICompositionTool[]
|
||||
{
|
||||
new HitObjectCompositionTool<HitCircle>(),
|
||||
new HitObjectCompositionTool<Slider>(),
|
||||
new HitObjectCompositionTool<Spinner>()
|
||||
};
|
||||
}
|
||||
}
|
@ -16,6 +16,8 @@ using osu.Game.Overlays.Settings;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Osu.Scoring;
|
||||
using osu.Game.Rulesets.Osu.Edit;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
@ -118,6 +120,8 @@ namespace osu.Game.Rulesets.Osu
|
||||
|
||||
public override PerformanceCalculator CreatePerformanceCalculator(Beatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score);
|
||||
|
||||
public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this);
|
||||
|
||||
public override string Description => "osu!";
|
||||
|
||||
public override SettingsSubsection CreateSettings() => new OsuSettings();
|
||||
|
@ -13,6 +13,7 @@ using System.Linq;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.UI.Cursor;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
@ -65,7 +66,10 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
AddInternal(new GameplayCursor());
|
||||
|
||||
var cursor = CreateCursor();
|
||||
if (cursor != null)
|
||||
AddInternal(cursor);
|
||||
}
|
||||
|
||||
public override void Add(DrawableHitObject h)
|
||||
@ -102,5 +106,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
|
||||
judgementLayer.Add(explosion);
|
||||
}
|
||||
|
||||
protected virtual CursorContainer CreateCursor() => new GameplayCursor();
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,9 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Beatmaps\OsuBeatmapConverter.cs" />
|
||||
<Compile Include="Beatmaps\OsuBeatmapProcessor.cs" />
|
||||
<Compile Include="Edit\OsuEditPlayfield.cs" />
|
||||
<Compile Include="Edit\OsuEditRulesetContainer.cs" />
|
||||
<Compile Include="Edit\OsuHitObjectComposer.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableOsuHitObject.cs" />
|
||||
<Compile Include="Objects\Drawables\Connections\ConnectionRenderer.cs" />
|
||||
<Compile Include="Objects\Drawables\Connections\FollowPointRenderer.cs" />
|
||||
|
46
osu.Game.Tests/Visual/TestCaseEditorCompose.cs
Normal file
46
osu.Game.Tests/Visual/TestCaseEditorCompose.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit.Screens.Compose;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseEditorCompose : OsuTestCase
|
||||
{
|
||||
private readonly Random random;
|
||||
private readonly Compose compose;
|
||||
|
||||
public TestCaseEditorCompose()
|
||||
{
|
||||
random = new Random(1337);
|
||||
|
||||
Add(compose = new Compose());
|
||||
AddStep("Next beatmap", nextBeatmap);
|
||||
}
|
||||
|
||||
private OsuGameBase osuGame;
|
||||
private BeatmapManager beatmaps;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osuGame, BeatmapManager beatmaps)
|
||||
{
|
||||
this.osuGame = osuGame;
|
||||
this.beatmaps = beatmaps;
|
||||
|
||||
compose.Beatmap.BindTo(osuGame.Beatmap);
|
||||
}
|
||||
|
||||
private void nextBeatmap()
|
||||
{
|
||||
var sets = beatmaps.GetAllUsableBeatmapSets();
|
||||
if (sets.Count == 0)
|
||||
return;
|
||||
|
||||
var b = sets[random.Next(0, sets.Count)].Beatmaps[0];
|
||||
osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(b);
|
||||
}
|
||||
}
|
||||
}
|
41
osu.Game.Tests/Visual/TestCaseEditorComposeRadioButtons.cs
Normal file
41
osu.Game.Tests/Visual/TestCaseEditorComposeRadioButtons.cs
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.RadioButtons;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseEditorComposeRadioButtons : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableRadioButton) };
|
||||
|
||||
public TestCaseEditorComposeRadioButtons()
|
||||
{
|
||||
RadioButtonCollection collection;
|
||||
Add(collection = new RadioButtonCollection
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Width = 150,
|
||||
Items = new[]
|
||||
{
|
||||
new RadioButton("Item 1", () => { }),
|
||||
new RadioButton("Item 2", () => { }),
|
||||
new RadioButton("Item 3", () => { }),
|
||||
new RadioButton("Item 4", () => { }),
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -102,6 +102,8 @@
|
||||
<Compile Include="Visual\TestCaseDrawableRoom.cs" />
|
||||
<Compile Include="Visual\TestCaseDrawings.cs" />
|
||||
<Compile Include="Visual\TestCaseEditor.cs" />
|
||||
<Compile Include="Visual\TestCaseEditorCompose.cs" />
|
||||
<Compile Include="Visual\TestCaseEditorComposeRadioButtons.cs" />
|
||||
<Compile Include="Visual\TestCaseEditorComposeTimeline.cs" />
|
||||
<Compile Include="Visual\TestCaseEditorMenuBar.cs" />
|
||||
<Compile Include="Visual\TestCaseEditorSummaryTimeline.cs" />
|
||||
|
109
osu.Game/Rulesets/Edit/HitObjectComposer.cs
Normal file
109
osu.Game/Rulesets/Edit/HitObjectComposer.cs
Normal file
@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.RadioButtons;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
public abstract class HitObjectComposer : CompositeDrawable
|
||||
{
|
||||
private readonly Ruleset ruleset;
|
||||
|
||||
protected ICompositionTool CurrentTool { get; private set; }
|
||||
|
||||
protected HitObjectComposer(Ruleset ruleset)
|
||||
{
|
||||
this.ruleset = ruleset;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osuGame)
|
||||
{
|
||||
RulesetContainer rulesetContainer;
|
||||
try
|
||||
{
|
||||
rulesetContainer = CreateRulesetContainer(ruleset, osuGame.Beatmap.Value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log($"Could not load this beatmap sucessfully ({e})!", LoggingTarget.Runtime, LogLevel.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
RadioButtonCollection toolboxCollection;
|
||||
InternalChild = new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Name = "Sidebar",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Right = 10 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ToolboxGroup { Child = toolboxCollection = new RadioButtonCollection { RelativeSizeAxes = Axes.X } }
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
BorderColour = Color4.White,
|
||||
BorderThickness = 2,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true,
|
||||
},
|
||||
rulesetContainer
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
ColumnDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.Absolute, 200),
|
||||
}
|
||||
};
|
||||
|
||||
rulesetContainer.Clock = new InterpolatingFramedClock((IAdjustableClock)osuGame.Beatmap.Value.Track ?? new StopwatchClock());
|
||||
|
||||
toolboxCollection.Items =
|
||||
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
|
||||
.Concat(
|
||||
CompositionTools.Select(t => new RadioButton(t.Name, () => setCompositionTool(t)))
|
||||
)
|
||||
.ToList();
|
||||
|
||||
toolboxCollection.Items[0].Select();
|
||||
}
|
||||
|
||||
private void setCompositionTool(ICompositionTool tool) => CurrentTool = tool;
|
||||
|
||||
protected virtual RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => ruleset.CreateRulesetContainerWith(beatmap, true);
|
||||
|
||||
protected abstract IReadOnlyList<ICompositionTool> CompositionTools { get; }
|
||||
}
|
||||
}
|
19
osu.Game/Rulesets/Edit/ToolboxGroup.cs
Normal file
19
osu.Game/Rulesets/Edit/ToolboxGroup.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Play.ReplaySettings;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
public class ToolboxGroup : ReplayGroup
|
||||
{
|
||||
protected override string Title => "toolbox";
|
||||
|
||||
public ToolboxGroup()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Width = 1;
|
||||
}
|
||||
}
|
||||
}
|
13
osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs
Normal file
13
osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Tools
|
||||
{
|
||||
public class HitObjectCompositionTool<T> : ICompositionTool
|
||||
where T : HitObject
|
||||
{
|
||||
public string Name => typeof(T).Name;
|
||||
}
|
||||
}
|
10
osu.Game/Rulesets/Edit/Tools/ICompositionTool.cs
Normal file
10
osu.Game/Rulesets/Edit/Tools/ICompositionTool.cs
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Tools
|
||||
{
|
||||
public interface ICompositionTool
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
@ -52,6 +53,8 @@ namespace osu.Game.Rulesets
|
||||
|
||||
public virtual PerformanceCalculator CreatePerformanceCalculator(Beatmap beatmap, Score score) => null;
|
||||
|
||||
public virtual HitObjectComposer CreateHitObjectComposer() => null;
|
||||
|
||||
public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_question_circle };
|
||||
|
||||
public abstract string Description { get; }
|
||||
|
@ -55,6 +55,11 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
public abstract IEnumerable<HitObject> Objects { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The playfield.
|
||||
/// </summary>
|
||||
public Playfield Playfield { get; protected set; }
|
||||
|
||||
protected readonly Ruleset Ruleset;
|
||||
|
||||
/// <summary>
|
||||
@ -135,11 +140,6 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor<TObject>(this);
|
||||
|
||||
/// <summary>
|
||||
/// The playfield.
|
||||
/// </summary>
|
||||
public Playfield Playfield { get; private set; }
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private Container content;
|
||||
|
||||
|
@ -6,22 +6,35 @@ using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit.Screens.Compose.Timeline;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
{
|
||||
public class Compose : EditorScreen
|
||||
{
|
||||
private const float vertical_margins = 10;
|
||||
private const float horizontal_margins = 20;
|
||||
|
||||
private readonly Container composerContainer;
|
||||
|
||||
public Compose()
|
||||
{
|
||||
ScrollableTimeline timeline;
|
||||
Children = new[]
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Name = "Timeline",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 110,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@ -31,9 +44,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Name = "Content",
|
||||
Name = "Timeline content",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = 17, Vertical = 10 },
|
||||
Padding = new MarginPadding { Horizontal = horizontal_margins, Vertical = vertical_margins },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
@ -46,9 +59,46 @@ namespace osu.Game.Screens.Edit.Screens.Compose
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new Drawable[]
|
||||
{
|
||||
composerContainer = new Container
|
||||
{
|
||||
Name = "Composer content",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = horizontal_margins, Vertical = vertical_margins },
|
||||
}
|
||||
}
|
||||
},
|
||||
RowDimensions = new[] { new Dimension(GridSizeMode.Absolute, 110) }
|
||||
},
|
||||
};
|
||||
|
||||
timeline.Beatmap.BindTo(Beatmap);
|
||||
Beatmap.ValueChanged += beatmapChanged;
|
||||
}
|
||||
|
||||
private void beatmapChanged(WorkingBeatmap newBeatmap)
|
||||
{
|
||||
composerContainer.Clear();
|
||||
|
||||
var ruleset = newBeatmap.BeatmapInfo.Ruleset?.CreateInstance();
|
||||
if (ruleset == null)
|
||||
{
|
||||
Logger.Log("Beatmap doesn't have a ruleset assigned.");
|
||||
// ExitRequested?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
var composer = ruleset.CreateHitObjectComposer();
|
||||
if (composer == null)
|
||||
{
|
||||
Logger.Log($"Ruleset {ruleset.Description} doesn't support hitobject composition.");
|
||||
// ExitRequested?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
composerContainer.Child = composer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,123 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Screens.Compose.RadioButtons
|
||||
{
|
||||
public class DrawableRadioButton : TriangleButton
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
|
||||
/// </summary>
|
||||
public Action<RadioButton> Selected;
|
||||
|
||||
private Color4 defaultBackgroundColour;
|
||||
private Color4 defaultBubbleColour;
|
||||
private Color4 selectedBackgroundColour;
|
||||
private Color4 selectedBubbleColour;
|
||||
|
||||
private readonly 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,
|
||||
Blending = BlendingMode.Additive,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both }
|
||||
};
|
||||
}
|
||||
|
||||
[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(bubble);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
button.Selected.ValueChanged += v =>
|
||||
{
|
||||
updateSelectionState();
|
||||
if (v)
|
||||
Selected?.Invoke(button);
|
||||
};
|
||||
|
||||
updateSelectionState();
|
||||
}
|
||||
|
||||
private void updateSelectionState()
|
||||
{
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
BackgroundColour = button.Selected ? selectedBackgroundColour : defaultBackgroundColour;
|
||||
bubble.Colour = button.Selected ? selectedBubbleColour : defaultBubbleColour;
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state)
|
||||
{
|
||||
if (button.Selected)
|
||||
return true;
|
||||
|
||||
if (!Enabled)
|
||||
return true;
|
||||
|
||||
button.Selected.Value = true;
|
||||
|
||||
return base.OnClick(state);
|
||||
}
|
||||
|
||||
protected override SpriteText CreateText() => new OsuSpriteText
|
||||
{
|
||||
Depth = -1,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
X = 40f
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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 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>
|
||||
public string Text;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Action"/> that should be invoked when this button is selected.
|
||||
/// </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;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenTK;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
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 (ReferenceEquals(items, value))
|
||||
return;
|
||||
items = value;
|
||||
|
||||
buttonContainer.Clear();
|
||||
items.ForEach(addButton);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly FlowContainer<DrawableRadioButton> buttonContainer;
|
||||
|
||||
public RadioButtonCollection()
|
||||
{
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChild = buttonContainer = new FillFlowContainer<DrawableRadioButton>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5)
|
||||
};
|
||||
}
|
||||
|
||||
private RadioButton currentlySelected;
|
||||
private void addButton(RadioButton button)
|
||||
{
|
||||
button.Selected.ValueChanged += v =>
|
||||
{
|
||||
if (v)
|
||||
{
|
||||
currentlySelected?.Deselect();
|
||||
currentlySelected = button;
|
||||
}
|
||||
else
|
||||
currentlySelected = null;
|
||||
};
|
||||
|
||||
buttonContainer.Add(new DrawableRadioButton(button));
|
||||
}
|
||||
}
|
||||
}
|
@ -303,7 +303,6 @@
|
||||
<Compile Include="Screens\Edit\Components\PlaybackControl.cs" />
|
||||
<Compile Include="Screens\Edit\Components\TimeInfoContainer.cs" />
|
||||
<Compile Include="Rulesets\Mods\IApplicableToScoreProcessor.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\BeatmapWaveformGraph.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\DifficultyColouredContainer.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\Panel.cs" />
|
||||
@ -313,6 +312,10 @@
|
||||
<Compile Include="Beatmaps\IO\ArchiveReader.cs" />
|
||||
<Compile Include="Beatmaps\IO\LegacyFilesystemReader.cs" />
|
||||
<Compile Include="Online\API\Requests\GetUserScoresRequest.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\RadioButtons\DrawableRadioButton.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\RadioButtons\RadioButton.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\RadioButtons\RadioButtonCollection.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\BeatmapWaveformGraph.cs" />
|
||||
<Compile Include="Screens\Edit\Screens\Compose\Timeline\TimelineButton.cs" />
|
||||
<Compile Include="Screens\Play\BreaksOverlay\ArrowsOverlay.cs" />
|
||||
<Compile Include="Screens\Play\BreaksOverlay\BlurredIcon.cs" />
|
||||
@ -556,6 +559,10 @@
|
||||
<Compile Include="Overlays\UserProfileOverlay.cs" />
|
||||
<Compile Include="Overlays\WaveOverlayContainer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Rulesets\Edit\Tools\HitObjectCompositionTool.cs" />
|
||||
<Compile Include="Rulesets\Edit\Tools\ICompositionTool.cs" />
|
||||
<Compile Include="Rulesets\Edit\HitObjectComposer.cs" />
|
||||
<Compile Include="Rulesets\Edit\ToolboxGroup.cs" />
|
||||
<Compile Include="Rulesets\Judgements\DrawableJudgement.cs" />
|
||||
<Compile Include="Rulesets\Judgements\Judgement.cs" />
|
||||
<Compile Include="Rulesets\Mods\IApplicableToClock.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user