mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 07:06:35 +09:00
Merge branch 'master' into add-editor-nudging-support
This commit is contained in:
@ -71,7 +71,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
// Put earlier blueprints towards the end of the list, so they handle input first
|
||||
int i = yObj.HitObject.StartTime.CompareTo(xObj.HitObject.StartTime);
|
||||
return i == 0 ? CompareReverseChildID(x, y) : i;
|
||||
|
||||
if (i != 0) return i;
|
||||
|
||||
// Fall back to end time if the start time is equal.
|
||||
i = yObj.HitObject.GetEndTime().CompareTo(xObj.HitObject.GetEndTime());
|
||||
|
||||
return i == 0 ? CompareReverseChildID(y, x) : i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -121,14 +123,55 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
}
|
||||
|
||||
base.Update();
|
||||
|
||||
updateStacking();
|
||||
}
|
||||
|
||||
private void updateStacking()
|
||||
{
|
||||
// because only blueprints of objects which are alive (via pooling) are displayed in the timeline, it's feasible to do this every-update.
|
||||
|
||||
const int stack_offset = 5;
|
||||
|
||||
// after the stack gets this tall, we can presume there is space underneath to draw subsequent blueprints.
|
||||
const int stack_reset_count = 3;
|
||||
|
||||
Stack<HitObject> currentConcurrentObjects = new Stack<HitObject>();
|
||||
|
||||
foreach (var b in SelectionBlueprints.Reverse())
|
||||
{
|
||||
// remove objects from the stack as long as their end time is in the past.
|
||||
while (currentConcurrentObjects.TryPeek(out HitObject hitObject))
|
||||
{
|
||||
if (Precision.AlmostBigger(hitObject.GetEndTime(), b.HitObject.StartTime, 1))
|
||||
break;
|
||||
|
||||
currentConcurrentObjects.Pop();
|
||||
}
|
||||
|
||||
// if the stack gets too high, we should have space below it to display the next batch of objects.
|
||||
// importantly, we only do this if time has incremented, else a stack of hitobjects all at the same time value would start to overlap themselves.
|
||||
if (currentConcurrentObjects.TryPeek(out HitObject h) && !Precision.AlmostEquals(h.StartTime, b.HitObject.StartTime, 1))
|
||||
{
|
||||
if (currentConcurrentObjects.Count >= stack_reset_count)
|
||||
currentConcurrentObjects.Clear();
|
||||
}
|
||||
|
||||
b.Y = -(stack_offset * currentConcurrentObjects.Count);
|
||||
|
||||
currentConcurrentObjects.Push(b.HitObject);
|
||||
}
|
||||
}
|
||||
|
||||
protected override SelectionHandler CreateSelectionHandler() => new TimelineSelectionHandler();
|
||||
|
||||
protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectBlueprint(hitObject)
|
||||
protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject)
|
||||
{
|
||||
OnDragHandled = handleScrollViaDrag
|
||||
};
|
||||
return new TimelineHitObjectBlueprint(hitObject)
|
||||
{
|
||||
OnDragHandled = handleScrollViaDrag
|
||||
};
|
||||
}
|
||||
|
||||
protected override DragBox CreateDragBox(Action<RectangleF> performSelect) => new TimelineDragBox(performSelect);
|
||||
|
||||
@ -203,7 +246,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
Box.X = Math.Min(rescaledStart, rescaledEnd);
|
||||
Box.Width = Math.Abs(rescaledStart - rescaledEnd);
|
||||
|
||||
PerformSelection?.Invoke(Box.ScreenSpaceDrawQuad.AABBFloat);
|
||||
var boxScreenRect = Box.ScreenSpaceDrawQuad.AABBFloat;
|
||||
|
||||
// we don't care about where the hitobjects are vertically. in cases like stacking display, they may be outside the box without this adjustment.
|
||||
boxScreenRect.Y -= boxScreenRect.Height;
|
||||
boxScreenRect.Height *= 2;
|
||||
|
||||
PerformSelection?.Invoke(boxScreenRect);
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
|
@ -2,11 +2,16 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
@ -14,11 +19,17 @@ using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Compose
|
||||
{
|
||||
public class ComposeScreen : EditorScreenWithTimeline
|
||||
public class ComposeScreen : EditorScreenWithTimeline, IKeyBindingHandler<PlatformAction>
|
||||
{
|
||||
[Resolved]
|
||||
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private GameHost host { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; }
|
||||
|
||||
private HitObjectComposer composer;
|
||||
|
||||
public ComposeScreen()
|
||||
@ -72,5 +83,34 @@ namespace osu.Game.Screens.Edit.Compose
|
||||
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
|
||||
return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(content));
|
||||
}
|
||||
|
||||
#region Input Handling
|
||||
|
||||
public bool OnPressed(PlatformAction action)
|
||||
{
|
||||
if (action.ActionType == PlatformActionType.Copy)
|
||||
host.GetClipboard().SetText(formatSelectionAsString());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(PlatformAction action)
|
||||
{
|
||||
}
|
||||
|
||||
private string formatSelectionAsString()
|
||||
{
|
||||
if (composer == null)
|
||||
return string.Empty;
|
||||
|
||||
double displayTime = EditorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime).FirstOrDefault()?.StartTime ?? clock.CurrentTime;
|
||||
string selectionAsString = composer.ConvertSelectionToString();
|
||||
|
||||
return !string.IsNullOrEmpty(selectionAsString)
|
||||
? $"{displayTime.ToEditorFormattedString()} ({selectionAsString}) - "
|
||||
: $"{displayTime.ToEditorFormattedString()} - ";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ using osu.Framework.Input;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -103,7 +102,7 @@ namespace osu.Game.Screens.Edit
|
||||
private MusicController music { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, GameHost host, OsuConfigManager config)
|
||||
private void load(OsuColour colours, OsuConfigManager config)
|
||||
{
|
||||
var loadableBeatmap = Beatmap.Value;
|
||||
|
||||
|
Reference in New Issue
Block a user