mirror of
https://github.com/osukey/osukey.git
synced 2025-06-05 21:07:18 +09:00
Merge branch 'master' into ruleset-replayframes
This commit is contained in:
commit
c54c1699bf
@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.MathUtils
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class FastRandom
|
internal class FastRandom
|
||||||
{
|
{
|
||||||
private const double uint_to_real = 1.0 / (uint.MaxValue + 1.0);
|
private const double int_to_real = 1.0 / (int.MaxValue + 1.0);
|
||||||
private const uint int_mask = 0x7FFFFFFF;
|
private const uint int_mask = 0x7FFFFFFF;
|
||||||
private const uint y = 842502087;
|
private const uint y = 842502087;
|
||||||
private const uint z = 3579807591;
|
private const uint z = 3579807591;
|
||||||
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.MathUtils
|
|||||||
/// Generates a random double value within the range [0, 1).
|
/// Generates a random double value within the range [0, 1).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The random value.</returns>
|
/// <returns>The random value.</returns>
|
||||||
public double NextDouble() => uint_to_real * NextUInt();
|
public double NextDouble() => int_to_real * Next();
|
||||||
|
|
||||||
private uint bitBuffer;
|
private uint bitBuffer;
|
||||||
private int bitIndex = 32;
|
private int bitIndex = 32;
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Edit.Layers.Selection.Overlays;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Edit.Layers.Selection
|
||||||
|
{
|
||||||
|
public class OsuHitObjectOverlayLayer : HitObjectOverlayLayer
|
||||||
|
{
|
||||||
|
protected override HitObjectOverlay CreateOverlayFor(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableHitCircle circle:
|
||||||
|
return new HitCircleOverlay(circle);
|
||||||
|
case DrawableSlider slider:
|
||||||
|
return new SliderOverlay(slider);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateOverlayFor(hitObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Framework.Allocation;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Edit.Layers.Selection.Overlays
|
||||||
|
{
|
||||||
|
public class HitCircleOverlay : HitObjectOverlay
|
||||||
|
{
|
||||||
|
public HitCircleOverlay(DrawableHitCircle hitCircle)
|
||||||
|
: base(hitCircle)
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
Position = hitCircle.Position;
|
||||||
|
Size = hitCircle.Size;
|
||||||
|
Scale = hitCircle.Scale;
|
||||||
|
|
||||||
|
AddInternal(new RingPiece());
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Edit.Layers.Selection.Overlays
|
||||||
|
{
|
||||||
|
public class SliderCircleOverlay : HitObjectOverlay
|
||||||
|
{
|
||||||
|
public SliderCircleOverlay(DrawableHitCircle sliderHead, DrawableSlider slider)
|
||||||
|
: this(sliderHead, sliderHead.Position, slider)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SliderCircleOverlay(DrawableSliderTail sliderTail, DrawableSlider slider)
|
||||||
|
: this(sliderTail, sliderTail.Position, slider)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly DrawableOsuHitObject hitObject;
|
||||||
|
|
||||||
|
private SliderCircleOverlay(DrawableOsuHitObject hitObject, Vector2 position, DrawableSlider slider)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
this.hitObject = hitObject;
|
||||||
|
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
Position = position;
|
||||||
|
Size = slider.HeadCircle.Size;
|
||||||
|
Scale = slider.HeadCircle.Scale;
|
||||||
|
|
||||||
|
AddInternal(new RingPiece());
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
RelativeAnchorPosition = hitObject.RelativeAnchorPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Edit.Layers.Selection.Overlays
|
||||||
|
{
|
||||||
|
public class SliderOverlay : HitObjectOverlay
|
||||||
|
{
|
||||||
|
private readonly SliderBody body;
|
||||||
|
private readonly DrawableSlider slider;
|
||||||
|
|
||||||
|
public SliderOverlay(DrawableSlider slider)
|
||||||
|
: base(slider)
|
||||||
|
{
|
||||||
|
this.slider = slider;
|
||||||
|
|
||||||
|
var obj = (Slider)slider.HitObject;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
body = new SliderBody(obj)
|
||||||
|
{
|
||||||
|
AccentColour = Color4.Transparent,
|
||||||
|
PathWidth = obj.Scale * 64
|
||||||
|
},
|
||||||
|
new SliderCircleOverlay(slider.HeadCircle, slider),
|
||||||
|
new SliderCircleOverlay(slider.TailCircle, slider),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
body.BorderColour = colours.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
Position = slider.Position;
|
||||||
|
Size = slider.Size;
|
||||||
|
OriginPosition = slider.OriginPosition;
|
||||||
|
|
||||||
|
// Need to cause one update
|
||||||
|
body.UpdateProgress(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,9 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Osu.Edit.Layers.Selection;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
@ -29,5 +31,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected override ScalableContainer CreateLayerContainer() => new ScalableContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
|
protected override ScalableContainer CreateLayerContainer() => new ScalableContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
protected override HitObjectOverlayLayer CreateHitObjectOverlayLayer() => new OsuHitObjectOverlayLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private readonly List<Drawable> components = new List<Drawable>();
|
private readonly List<Drawable> components = new List<Drawable>();
|
||||||
|
|
||||||
public readonly DrawableHitCircle HeadCircle;
|
public readonly DrawableHitCircle HeadCircle;
|
||||||
|
public readonly DrawableSliderTail TailCircle;
|
||||||
|
|
||||||
public readonly SliderBody Body;
|
public readonly SliderBody Body;
|
||||||
public readonly SliderBall Ball;
|
public readonly SliderBall Ball;
|
||||||
|
|
||||||
@ -33,7 +35,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
Position = s.StackedPosition;
|
Position = s.StackedPosition;
|
||||||
|
|
||||||
DrawableSliderTail tail;
|
|
||||||
Container<DrawableSliderTick> ticks;
|
Container<DrawableSliderTick> ticks;
|
||||||
Container<DrawableRepeatPoint> repeatPoints;
|
Container<DrawableRepeatPoint> repeatPoints;
|
||||||
|
|
||||||
@ -54,8 +55,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
AlwaysPresent = true,
|
AlwaysPresent = true,
|
||||||
Alpha = 0
|
Alpha = 0
|
||||||
},
|
},
|
||||||
HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.HeadCircle.Position - s.Position },
|
HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.TailCircle.Position - s.Position },
|
||||||
tail = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position }
|
TailCircle = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position }
|
||||||
};
|
};
|
||||||
|
|
||||||
components.Add(Body);
|
components.Add(Body);
|
||||||
@ -63,8 +64,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
AddNested(HeadCircle);
|
AddNested(HeadCircle);
|
||||||
|
|
||||||
AddNested(tail);
|
AddNested(TailCircle);
|
||||||
components.Add(tail);
|
components.Add(TailCircle);
|
||||||
|
|
||||||
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
|
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
|
||||||
{
|
{
|
||||||
@ -170,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Body.ReceiveMouseInputAt(screenSpacePos);
|
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Body.ReceiveMouseInputAt(screenSpacePos);
|
||||||
|
|
||||||
public override Vector2 SelectionPoint => ToScreenSpace(Body.Position);
|
public override Vector2 SelectionPoint => ToScreenSpace(OriginPosition);
|
||||||
public override Quad SelectionQuad => Body.PathDrawQuad;
|
public override Quad SelectionQuad => Body.PathDrawQuad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,10 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Beatmaps\OsuBeatmapConverter.cs" />
|
<Compile Include="Beatmaps\OsuBeatmapConverter.cs" />
|
||||||
<Compile Include="Beatmaps\OsuBeatmapProcessor.cs" />
|
<Compile Include="Beatmaps\OsuBeatmapProcessor.cs" />
|
||||||
|
<Compile Include="Edit\Layers\Selection\OsuHitObjectOverlayLayer.cs" />
|
||||||
|
<Compile Include="Edit\Layers\Selection\Overlays\HitCircleOverlay.cs" />
|
||||||
|
<Compile Include="Edit\Layers\Selection\Overlays\SliderCircleOverlay.cs" />
|
||||||
|
<Compile Include="Edit\Layers\Selection\Overlays\SliderOverlay.cs" />
|
||||||
<Compile Include="Edit\OsuEditPlayfield.cs" />
|
<Compile Include="Edit\OsuEditPlayfield.cs" />
|
||||||
<Compile Include="Edit\OsuEditRulesetContainer.cs" />
|
<Compile Include="Edit\OsuEditRulesetContainer.cs" />
|
||||||
<Compile Include="Edit\OsuHitObjectComposer.cs" />
|
<Compile Include="Edit\OsuHitObjectComposer.cs" />
|
||||||
|
@ -6,10 +6,13 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Layers.Selection;
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Edit;
|
using osu.Game.Rulesets.Osu.Edit;
|
||||||
|
using osu.Game.Rulesets.Osu.Edit.Layers.Selection;
|
||||||
|
using osu.Game.Rulesets.Osu.Edit.Layers.Selection.Overlays;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
@ -21,7 +24,15 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
typeof(SelectionBox),
|
typeof(SelectionBox),
|
||||||
typeof(SelectionLayer),
|
typeof(SelectionLayer),
|
||||||
typeof(CaptureBox)
|
typeof(CaptureBox),
|
||||||
|
typeof(HitObjectComposer),
|
||||||
|
typeof(OsuHitObjectComposer),
|
||||||
|
typeof(HitObjectOverlayLayer),
|
||||||
|
typeof(OsuHitObjectOverlayLayer),
|
||||||
|
typeof(HitObjectOverlay),
|
||||||
|
typeof(HitCircleOverlay),
|
||||||
|
typeof(SliderOverlay),
|
||||||
|
typeof(SliderCircleOverlay)
|
||||||
};
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit.Layers;
|
||||||
using osu.Game.Rulesets.Edit.Layers.Selection;
|
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
@ -50,13 +49,25 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScalableContainer createLayerContainerWithContent(Drawable content)
|
HitObjectOverlayLayer hitObjectOverlayLayer = CreateHitObjectOverlayLayer();
|
||||||
|
SelectionLayer selectionLayer = new SelectionLayer(rulesetContainer.Playfield);
|
||||||
|
|
||||||
|
var layerBelowRuleset = new BorderLayer
|
||||||
{
|
{
|
||||||
var container = CreateLayerContainer();
|
RelativeSizeAxes = Axes.Both,
|
||||||
container.Child = content;
|
Child = CreateLayerContainer()
|
||||||
layerContainers.Add(container);
|
};
|
||||||
return container;
|
|
||||||
}
|
var layerAboveRuleset = CreateLayerContainer();
|
||||||
|
layerAboveRuleset.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
selectionLayer, // Below object overlays for input
|
||||||
|
hitObjectOverlayLayer,
|
||||||
|
selectionLayer.CreateProxy() // Proxy above object overlays for selections
|
||||||
|
};
|
||||||
|
|
||||||
|
layerContainers.Add(layerBelowRuleset);
|
||||||
|
layerContainers.Add(layerAboveRuleset);
|
||||||
|
|
||||||
RadioButtonCollection toolboxCollection;
|
RadioButtonCollection toolboxCollection;
|
||||||
InternalChild = new GridContainer
|
InternalChild = new GridContainer
|
||||||
@ -82,17 +93,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
createLayerContainerWithContent(new Container
|
layerBelowRuleset,
|
||||||
{
|
|
||||||
Name = "Border",
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Masking = true,
|
|
||||||
BorderColour = Color4.White,
|
|
||||||
BorderThickness = 2,
|
|
||||||
Child = new Box { RelativeSizeAxes = Axes.Both, Alpha = 0, AlwaysPresent = true }
|
|
||||||
}),
|
|
||||||
rulesetContainer,
|
rulesetContainer,
|
||||||
createLayerContainerWithContent(new SelectionLayer(rulesetContainer.Playfield))
|
layerAboveRuleset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -103,6 +106,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
selectionLayer.ObjectSelected += hitObjectOverlayLayer.AddOverlay;
|
||||||
|
selectionLayer.ObjectDeselected += hitObjectOverlayLayer.RemoveOverlay;
|
||||||
|
|
||||||
toolboxCollection.Items =
|
toolboxCollection.Items =
|
||||||
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
|
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
|
||||||
.Concat(
|
.Concat(
|
||||||
@ -136,5 +142,10 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// Creates a <see cref="ScalableContainer"/> which provides a layer above or below the <see cref="Playfield"/>.
|
/// Creates a <see cref="ScalableContainer"/> which provides a layer above or below the <see cref="Playfield"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual ScalableContainer CreateLayerContainer() => new ScalableContainer { RelativeSizeAxes = Axes.Both };
|
protected virtual ScalableContainer CreateLayerContainer() => new ScalableContainer { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the <see cref="HitObjectOverlayLayer"/> which overlays selected <see cref="DrawableHitObject"/>s.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual HitObjectOverlayLayer CreateHitObjectOverlayLayer() => new HitObjectOverlayLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
osu.Game/Rulesets/Edit/Layers/BorderLayer.cs
Normal file
38
osu.Game/Rulesets/Edit/Layers/BorderLayer.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Edit.Layers
|
||||||
|
{
|
||||||
|
public class BorderLayer : Container
|
||||||
|
{
|
||||||
|
protected override Container<Drawable> Content => content;
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
|
public BorderLayer()
|
||||||
|
{
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Name = "Border",
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
BorderColour = Color4.White,
|
||||||
|
BorderThickness = 2,
|
||||||
|
Child = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = new Container { RelativeSizeAxes = Axes.Both }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs
Normal file
25
osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||||
|
{
|
||||||
|
public class HitObjectOverlay : OverlayContainer
|
||||||
|
{
|
||||||
|
// ReSharper disable once NotAccessedField.Local
|
||||||
|
// This will be used later to handle drag movement, etc
|
||||||
|
private readonly DrawableHitObject hitObject;
|
||||||
|
|
||||||
|
public HitObjectOverlay(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
this.hitObject = hitObject;
|
||||||
|
|
||||||
|
State = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopIn() => Alpha = 1;
|
||||||
|
protected override void PopOut() => Alpha = 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||||
|
{
|
||||||
|
public class HitObjectOverlayLayer : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly Dictionary<DrawableHitObject, HitObjectOverlay> existingOverlays = new Dictionary<DrawableHitObject, HitObjectOverlay>();
|
||||||
|
|
||||||
|
public HitObjectOverlayLayer()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an overlay for a <see cref="DrawableHitObject"/> which adds movement support.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to create an overlay for.</param>
|
||||||
|
public void AddOverlay(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
var overlay = CreateOverlayFor(hitObject);
|
||||||
|
if (overlay == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
existingOverlays[hitObject] = overlay;
|
||||||
|
AddInternal(overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the overlay for a <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to remove the overlay for.</param>
|
||||||
|
public void RemoveOverlay(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
if (!existingOverlays.TryGetValue(hitObject, out var existing))
|
||||||
|
return;
|
||||||
|
|
||||||
|
existing.Hide();
|
||||||
|
existing.Expire();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="HitObjectOverlay"/> for a specific <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to create the overlay for.</param>
|
||||||
|
protected virtual HitObjectOverlay CreateOverlayFor(DrawableHitObject hitObject) => null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
@ -15,6 +17,16 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
{
|
{
|
||||||
public class SelectionLayer : CompositeDrawable
|
public class SelectionLayer : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a <see cref="DrawableHitObject"/> is selected.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<DrawableHitObject> ObjectSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a <see cref="DrawableHitObject"/> is deselected.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<DrawableHitObject> ObjectDeselected;
|
||||||
|
|
||||||
private readonly Playfield playfield;
|
private readonly Playfield playfield;
|
||||||
|
|
||||||
public SelectionLayer(Playfield playfield)
|
public SelectionLayer(Playfield playfield)
|
||||||
@ -27,11 +39,11 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
private SelectionBox selectionBox;
|
private SelectionBox selectionBox;
|
||||||
private CaptureBox captureBox;
|
private CaptureBox captureBox;
|
||||||
|
|
||||||
private readonly List<DrawableHitObject> selectedHitObjects = new List<DrawableHitObject>();
|
private readonly HashSet<DrawableHitObject> selectedHitObjects = new HashSet<DrawableHitObject>();
|
||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
{
|
{
|
||||||
clearSelection();
|
DeselectAll();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,24 +86,85 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects a <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to select.</param>
|
||||||
|
public void Select(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
if (!select(hitObject))
|
||||||
|
return;
|
||||||
|
|
||||||
|
clearCapture();
|
||||||
|
finishSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects a <see cref="DrawableHitObject"/> without performing capture updates.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to select.</param>
|
||||||
|
/// <returns>Whether <paramref name="hitObject"/> was selected.</returns>
|
||||||
|
private bool select(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
if (!selectedHitObjects.Add(hitObject))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ObjectSelected?.Invoke(hitObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deselects a <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to deselect.</param>
|
||||||
|
public void Deselect(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
if (!deselect(hitObject))
|
||||||
|
return;
|
||||||
|
|
||||||
|
clearCapture();
|
||||||
|
finishSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deselects a <see cref="DrawableHitObject"/> without performing capture updates.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to deselect.</param>
|
||||||
|
/// <returns>Whether the <see cref="DrawableHitObject"/> was deselected.</returns>
|
||||||
|
private bool deselect(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
if (!selectedHitObjects.Remove(hitObject))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ObjectDeselected?.Invoke(hitObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deselects all selected <see cref="DrawableHitObject"/>s.
|
/// Deselects all selected <see cref="DrawableHitObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void clearSelection()
|
public void DeselectAll()
|
||||||
{
|
{
|
||||||
|
selectedHitObjects.ForEach(h => ObjectDeselected?.Invoke(h));
|
||||||
selectedHitObjects.Clear();
|
selectedHitObjects.Clear();
|
||||||
captureBox?.Hide();
|
|
||||||
captureBox?.Expire();
|
clearCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects all hitobjects that are present within the area of a <see cref="Quad"/>.
|
/// Selects all hitobjects that are present within the area of a <see cref="Quad"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="screenSpaceQuad">The selection <see cref="Quad"/>.</param>
|
/// <param name="screenSpaceQuad">The selection <see cref="Quad"/>.</param>
|
||||||
|
// Todo: If needed we can severely reduce allocations in this method
|
||||||
private void selectQuad(Quad screenSpaceQuad)
|
private void selectQuad(Quad screenSpaceQuad)
|
||||||
{
|
{
|
||||||
foreach (var obj in playfield.HitObjects.Objects.Where(h => h.IsAlive && h.IsPresent && screenSpaceQuad.Contains(h.SelectionPoint)))
|
var expectedSelection = playfield.HitObjects.Objects.Where(h => h.IsAlive && h.IsPresent && screenSpaceQuad.Contains(h.SelectionPoint)).ToList();
|
||||||
selectedHitObjects.Add(obj);
|
|
||||||
|
var toRemove = selectedHitObjects.Except(expectedSelection).ToList();
|
||||||
|
foreach (var obj in toRemove)
|
||||||
|
deselect(obj);
|
||||||
|
|
||||||
|
expectedSelection.ForEach(h => select(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -100,11 +173,17 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
/// <param name="screenSpacePoint">The <see cref="Vector2"/> to select at.</param>
|
/// <param name="screenSpacePoint">The <see cref="Vector2"/> to select at.</param>
|
||||||
private void selectPoint(Vector2 screenSpacePoint)
|
private void selectPoint(Vector2 screenSpacePoint)
|
||||||
{
|
{
|
||||||
var selected = playfield.HitObjects.Objects.Reverse().Where(h => h.IsAlive && h.IsPresent).FirstOrDefault(h => h.ReceiveMouseInputAt(screenSpacePoint));
|
var target = playfield.HitObjects.Objects.Reverse().Where(h => h.IsAlive && h.IsPresent).FirstOrDefault(h => h.ReceiveMouseInputAt(screenSpacePoint));
|
||||||
if (selected == null)
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selectedHitObjects.Add(selected);
|
select(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearCapture()
|
||||||
|
{
|
||||||
|
captureBox?.Hide();
|
||||||
|
captureBox?.Expire();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishSelection()
|
private void finishSelection()
|
||||||
|
@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScaledContainer : Container
|
private class ScaledContainer : Container
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value to scale the width of the content to match.
|
/// The value to scale the width of the content to match.
|
||||||
|
@ -143,7 +143,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
Alpha = 0.5f,
|
Alpha = 0.5f,
|
||||||
Size = new Vector2(0.96f)
|
Size = new Vector2(0.96f)
|
||||||
},
|
},
|
||||||
new BufferedContainer
|
new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
|
@ -352,7 +352,10 @@
|
|||||||
<Compile Include="Overlays\Settings\Sections\Maintenance\DeleteAllBeatmapsDialog.cs" />
|
<Compile Include="Overlays\Settings\Sections\Maintenance\DeleteAllBeatmapsDialog.cs" />
|
||||||
<Compile Include="Rulesets\Configuration\IRulesetConfigManager.cs" />
|
<Compile Include="Rulesets\Configuration\IRulesetConfigManager.cs" />
|
||||||
<Compile Include="Rulesets\Configuration\RulesetConfigManager.cs" />
|
<Compile Include="Rulesets\Configuration\RulesetConfigManager.cs" />
|
||||||
|
<Compile Include="Rulesets\Edit\Layers\BorderLayer.cs" />
|
||||||
<Compile Include="Rulesets\Edit\Layers\Selection\CaptureBox.cs" />
|
<Compile Include="Rulesets\Edit\Layers\Selection\CaptureBox.cs" />
|
||||||
|
<Compile Include="Rulesets\Edit\Layers\Selection\HitObjectOverlay.cs" />
|
||||||
|
<Compile Include="Rulesets\Edit\Layers\Selection\HitObjectOverlayLayer.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableFailOverride.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableFailOverride.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableToBeatmapConverter.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableToBeatmapConverter.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user