diff --git a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
index e14473c478..c8277af415 100644
--- a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
+++ b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
@@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.MathUtils
///
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 y = 842502087;
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).
///
/// The random value.
- public double NextDouble() => uint_to_real * NextUInt();
+ public double NextDouble() => int_to_real * Next();
private uint bitBuffer;
private int bitIndex = 32;
diff --git a/osu.Game.Rulesets.Osu/Edit/Layers/Selection/OsuHitObjectOverlayLayer.cs b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/OsuHitObjectOverlayLayer.cs
new file mode 100644
index 0000000000..e0d1b34ca5
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/OsuHitObjectOverlayLayer.cs
@@ -0,0 +1,26 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/HitCircleOverlay.cs b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/HitCircleOverlay.cs
new file mode 100644
index 0000000000..4e64783840
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/HitCircleOverlay.cs
@@ -0,0 +1,33 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/SliderCircleOverlay.cs b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/SliderCircleOverlay.cs
new file mode 100644
index 0000000000..3c7f8a067b
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/SliderCircleOverlay.cs
@@ -0,0 +1,55 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/SliderOverlay.cs b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/SliderOverlay.cs
new file mode 100644
index 0000000000..a035a683e9
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Edit/Layers/Selection/Overlays/SliderOverlay.cs
@@ -0,0 +1,57 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
index ae19706da3..70d49a6b4f 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
@@ -5,7 +5,9 @@ using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
+using osu.Game.Rulesets.Edit.Layers.Selection;
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.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 HitObjectOverlayLayer CreateHitObjectOverlayLayer() => new OsuHitObjectOverlayLayer();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index ede84e7737..f715ed075c 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -23,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private readonly List components = new List();
public readonly DrawableHitCircle HeadCircle;
+ public readonly DrawableSliderTail TailCircle;
+
public readonly SliderBody Body;
public readonly SliderBall Ball;
@@ -33,7 +35,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Position = s.StackedPosition;
- DrawableSliderTail tail;
Container ticks;
Container repeatPoints;
@@ -54,8 +55,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AlwaysPresent = true,
Alpha = 0
},
- HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.HeadCircle.Position - s.Position },
- tail = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position }
+ HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.TailCircle.Position - s.Position },
+ TailCircle = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position }
};
components.Add(Body);
@@ -63,8 +64,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AddNested(HeadCircle);
- AddNested(tail);
- components.Add(tail);
+ AddNested(TailCircle);
+ components.Add(TailCircle);
foreach (var tick in s.NestedHitObjects.OfType())
{
@@ -170,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
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;
}
}
diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
index a42dbeeb10..261c0be5eb 100644
--- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
+++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
@@ -64,6 +64,10 @@
+
+
+
+
diff --git a/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs b/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs
index 60ddff64ba..4926faa78c 100644
--- a/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs
+++ b/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs
@@ -6,10 +6,13 @@ using System.Collections.Generic;
using osu.Framework.Allocation;
using OpenTK;
using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Layers.Selection;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu;
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.Tests.Beatmaps;
@@ -21,7 +24,15 @@ namespace osu.Game.Tests.Visual
{
typeof(SelectionBox),
typeof(SelectionLayer),
- typeof(CaptureBox)
+ typeof(CaptureBox),
+ typeof(HitObjectComposer),
+ typeof(OsuHitObjectComposer),
+ typeof(HitObjectOverlayLayer),
+ typeof(OsuHitObjectOverlayLayer),
+ typeof(HitObjectOverlay),
+ typeof(HitCircleOverlay),
+ typeof(SliderOverlay),
+ typeof(SliderCircleOverlay)
};
[BackgroundDependencyLoader]
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index 1246127257..e6a51cc39b 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -4,14 +4,13 @@
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.Layers;
using osu.Game.Rulesets.Edit.Layers.Selection;
using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.UI;
@@ -50,13 +49,25 @@ namespace osu.Game.Rulesets.Edit
return;
}
- ScalableContainer createLayerContainerWithContent(Drawable content)
+ HitObjectOverlayLayer hitObjectOverlayLayer = CreateHitObjectOverlayLayer();
+ SelectionLayer selectionLayer = new SelectionLayer(rulesetContainer.Playfield);
+
+ var layerBelowRuleset = new BorderLayer
{
- var container = CreateLayerContainer();
- container.Child = content;
- layerContainers.Add(container);
- return container;
- }
+ RelativeSizeAxes = Axes.Both,
+ Child = CreateLayerContainer()
+ };
+
+ 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;
InternalChild = new GridContainer
@@ -82,17 +93,9 @@ namespace osu.Game.Rulesets.Edit
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- createLayerContainerWithContent(new Container
- {
- Name = "Border",
- RelativeSizeAxes = Axes.Both,
- Masking = true,
- BorderColour = Color4.White,
- BorderThickness = 2,
- Child = new Box { RelativeSizeAxes = Axes.Both, Alpha = 0, AlwaysPresent = true }
- }),
+ layerBelowRuleset,
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 =
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
.Concat(
@@ -136,5 +142,10 @@ namespace osu.Game.Rulesets.Edit
/// Creates a which provides a layer above or below the .
///
protected virtual ScalableContainer CreateLayerContainer() => new ScalableContainer { RelativeSizeAxes = Axes.Both };
+
+ ///
+ /// Creates the which overlays selected s.
+ ///
+ protected virtual HitObjectOverlayLayer CreateHitObjectOverlayLayer() => new HitObjectOverlayLayer();
}
}
diff --git a/osu.Game/Rulesets/Edit/Layers/BorderLayer.cs b/osu.Game/Rulesets/Edit/Layers/BorderLayer.cs
new file mode 100644
index 0000000000..54c30b8d89
--- /dev/null
+++ b/osu.Game/Rulesets/Edit/Layers/BorderLayer.cs
@@ -0,0 +1,38 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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 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 }
+ };
+ }
+ }
+}
diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs
new file mode 100644
index 0000000000..543dd2cc54
--- /dev/null
+++ b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs
@@ -0,0 +1,25 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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;
+ }
+}
diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs
new file mode 100644
index 0000000000..0b6e63d1fe
--- /dev/null
+++ b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs
@@ -0,0 +1,53 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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 existingOverlays = new Dictionary();
+
+ public HitObjectOverlayLayer()
+ {
+ RelativeSizeAxes = Axes.Both;
+ }
+
+ ///
+ /// Adds an overlay for a which adds movement support.
+ ///
+ /// The to create an overlay for.
+ public void AddOverlay(DrawableHitObject hitObject)
+ {
+ var overlay = CreateOverlayFor(hitObject);
+ if (overlay == null)
+ return;
+
+ existingOverlays[hitObject] = overlay;
+ AddInternal(overlay);
+ }
+
+ ///
+ /// Removes the overlay for a .
+ ///
+ /// The to remove the overlay for.
+ public void RemoveOverlay(DrawableHitObject hitObject)
+ {
+ if (!existingOverlays.TryGetValue(hitObject, out var existing))
+ return;
+
+ existing.Hide();
+ existing.Expire();
+ }
+
+ ///
+ /// Creates a for a specific .
+ ///
+ /// The to create the overlay for.
+ protected virtual HitObjectOverlay CreateOverlayFor(DrawableHitObject hitObject) => null;
+ }
+}
diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs b/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs
index bda613f617..3895d34d7f 100644
--- a/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs
+++ b/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs
@@ -1,8 +1,10 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using System;
using System.Collections.Generic;
using System.Linq;
+using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
@@ -15,6 +17,16 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
{
public class SelectionLayer : CompositeDrawable
{
+ ///
+ /// Invoked when a is selected.
+ ///
+ public event Action ObjectSelected;
+
+ ///
+ /// Invoked when a is deselected.
+ ///
+ public event Action ObjectDeselected;
+
private readonly Playfield playfield;
public SelectionLayer(Playfield playfield)
@@ -27,11 +39,11 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
private SelectionBox selectionBox;
private CaptureBox captureBox;
- private readonly List selectedHitObjects = new List();
+ private readonly HashSet selectedHitObjects = new HashSet();
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
- clearSelection();
+ DeselectAll();
return true;
}
@@ -74,24 +86,85 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
return true;
}
+ ///
+ /// Selects a .
+ ///
+ /// The to select.
+ public void Select(DrawableHitObject hitObject)
+ {
+ if (!select(hitObject))
+ return;
+
+ clearCapture();
+ finishSelection();
+ }
+
+ ///
+ /// Selects a without performing capture updates.
+ ///
+ /// The to select.
+ /// Whether was selected.
+ private bool select(DrawableHitObject hitObject)
+ {
+ if (!selectedHitObjects.Add(hitObject))
+ return false;
+
+ ObjectSelected?.Invoke(hitObject);
+ return true;
+ }
+
+ ///
+ /// Deselects a .
+ ///
+ /// The to deselect.
+ public void Deselect(DrawableHitObject hitObject)
+ {
+ if (!deselect(hitObject))
+ return;
+
+ clearCapture();
+ finishSelection();
+ }
+
+ ///
+ /// Deselects a without performing capture updates.
+ ///
+ /// The to deselect.
+ /// Whether the was deselected.
+ private bool deselect(DrawableHitObject hitObject)
+ {
+ if (!selectedHitObjects.Remove(hitObject))
+ return false;
+
+ ObjectDeselected?.Invoke(hitObject);
+ return true;
+ }
+
///
/// Deselects all selected s.
///
- private void clearSelection()
+ public void DeselectAll()
{
+ selectedHitObjects.ForEach(h => ObjectDeselected?.Invoke(h));
selectedHitObjects.Clear();
- captureBox?.Hide();
- captureBox?.Expire();
+
+ clearCapture();
}
///
/// Selects all hitobjects that are present within the area of a .
///
/// The selection .
+ // Todo: If needed we can severely reduce allocations in this method
private void selectQuad(Quad screenSpaceQuad)
{
- foreach (var obj in playfield.HitObjects.Objects.Where(h => h.IsAlive && h.IsPresent && screenSpaceQuad.Contains(h.SelectionPoint)))
- selectedHitObjects.Add(obj);
+ var expectedSelection = playfield.HitObjects.Objects.Where(h => h.IsAlive && h.IsPresent && screenSpaceQuad.Contains(h.SelectionPoint)).ToList();
+
+ var toRemove = selectedHitObjects.Except(expectedSelection).ToList();
+ foreach (var obj in toRemove)
+ deselect(obj);
+
+ expectedSelection.ForEach(h => select(h));
}
///
@@ -100,11 +173,17 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
/// The to select at.
private void selectPoint(Vector2 screenSpacePoint)
{
- var selected = playfield.HitObjects.Objects.Reverse().Where(h => h.IsAlive && h.IsPresent).FirstOrDefault(h => h.ReceiveMouseInputAt(screenSpacePoint));
- if (selected == null)
+ var target = playfield.HitObjects.Objects.Reverse().Where(h => h.IsAlive && h.IsPresent).FirstOrDefault(h => h.ReceiveMouseInputAt(screenSpacePoint));
+ if (target == null)
return;
- selectedHitObjects.Add(selected);
+ select(target);
+ }
+
+ private void clearCapture()
+ {
+ captureBox?.Hide();
+ captureBox?.Expire();
}
private void finishSelection()
diff --git a/osu.Game/Rulesets/UI/ScalableContainer.cs b/osu.Game/Rulesets/UI/ScalableContainer.cs
index 43ed770f77..9762828e7d 100644
--- a/osu.Game/Rulesets/UI/ScalableContainer.cs
+++ b/osu.Game/Rulesets/UI/ScalableContainer.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.UI
});
}
- public class ScaledContainer : Container
+ private class ScaledContainer : Container
{
///
/// The value to scale the width of the content to match.
diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs
index b91ff0d74b..3fcb885655 100644
--- a/osu.Game/Screens/Menu/OsuLogo.cs
+++ b/osu.Game/Screens/Menu/OsuLogo.cs
@@ -143,7 +143,7 @@ namespace osu.Game.Screens.Menu
Alpha = 0.5f,
Size = new Vector2(0.96f)
},
- new BufferedContainer
+ new Container
{
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 6d3746e30a..ee45bee80e 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -352,7 +352,10 @@
+
+
+