mirror of
https://github.com/ppy/osu.git
synced 2025-02-15 09:33:02 +08:00
Merge pull request #15545 from bdach/editor-clipboard-refactor
Move clipboard operation implementations to individual editor subscreens
This commit is contained in:
commit
61225092bf
@ -22,6 +22,9 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
||||
[Resolved]
|
||||
private SkinManager skins { get; set; }
|
||||
|
||||
[Cached]
|
||||
private EditorClipboard clipboard = new EditorClipboard();
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
|
@ -26,6 +26,9 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
}
|
||||
});
|
||||
|
||||
[Cached]
|
||||
private EditorClipboard clipboard = new EditorClipboard();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
|
@ -7,29 +7,26 @@ 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.Input.Events;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO.Serialization;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Compose
|
||||
{
|
||||
public class ComposeScreen : EditorScreenWithTimeline, IKeyBindingHandler<PlatformAction>
|
||||
public class ComposeScreen : EditorScreenWithTimeline
|
||||
{
|
||||
[Resolved]
|
||||
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private GameHost host { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; }
|
||||
|
||||
private Bindable<string> clipboard { get; set; }
|
||||
|
||||
private HitObjectComposer composer;
|
||||
|
||||
public ComposeScreen()
|
||||
@ -76,18 +73,65 @@ namespace osu.Game.Screens.Edit.Compose
|
||||
return new EditorSkinProvidingContainer(EditorBeatmap).WithChild(content);
|
||||
}
|
||||
|
||||
#region Input Handling
|
||||
|
||||
public bool OnPressed(KeyBindingPressEvent<PlatformAction> e)
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(EditorClipboard clipboard)
|
||||
{
|
||||
if (e.Action == PlatformAction.Copy)
|
||||
host.GetClipboard()?.SetText(formatSelectionAsString());
|
||||
|
||||
return false;
|
||||
this.clipboard = clipboard.Content.GetBoundCopy();
|
||||
}
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<PlatformAction> e)
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
EditorBeatmap.SelectedHitObjects.BindCollectionChanged((_, __) => updateClipboardActionAvailability());
|
||||
clipboard.BindValueChanged(_ => updateClipboardActionAvailability(), true);
|
||||
}
|
||||
|
||||
#region Clipboard operations
|
||||
|
||||
protected override void PerformCut()
|
||||
{
|
||||
base.PerformCut();
|
||||
|
||||
Copy();
|
||||
EditorBeatmap.RemoveRange(EditorBeatmap.SelectedHitObjects.ToArray());
|
||||
}
|
||||
|
||||
protected override void PerformCopy()
|
||||
{
|
||||
base.PerformCopy();
|
||||
|
||||
clipboard.Value = new ClipboardContent(EditorBeatmap).Serialize();
|
||||
|
||||
host.GetClipboard()?.SetText(formatSelectionAsString());
|
||||
}
|
||||
|
||||
protected override void PerformPaste()
|
||||
{
|
||||
base.PerformPaste();
|
||||
|
||||
var objects = clipboard.Value.Deserialize<ClipboardContent>().HitObjects;
|
||||
|
||||
Debug.Assert(objects.Any());
|
||||
|
||||
double timeOffset = clock.CurrentTime - objects.Min(o => o.StartTime);
|
||||
|
||||
foreach (var h in objects)
|
||||
h.StartTime += timeOffset;
|
||||
|
||||
EditorBeatmap.BeginChange();
|
||||
|
||||
EditorBeatmap.SelectedHitObjects.Clear();
|
||||
|
||||
EditorBeatmap.AddRange(objects);
|
||||
EditorBeatmap.SelectedHitObjects.AddRange(objects);
|
||||
|
||||
EditorBeatmap.EndChange();
|
||||
}
|
||||
|
||||
private void updateClipboardActionAvailability()
|
||||
{
|
||||
CanCut.Value = CanCopy.Value = EditorBeatmap.SelectedHitObjects.Any();
|
||||
CanPaste.Value = !string.IsNullOrEmpty(clipboard.Value);
|
||||
}
|
||||
|
||||
private string formatSelectionAsString()
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework;
|
||||
@ -24,7 +23,6 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.IO.Serialization;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
@ -105,6 +103,9 @@ namespace osu.Game.Screens.Edit
|
||||
[Resolved]
|
||||
private MusicController music { get; set; }
|
||||
|
||||
[Cached]
|
||||
public readonly EditorClipboard Clipboard = new EditorClipboard();
|
||||
|
||||
public Editor(EditorLoader loader = null)
|
||||
{
|
||||
this.loader = loader;
|
||||
@ -180,10 +181,6 @@ namespace osu.Game.Screens.Edit
|
||||
OsuMenuItem undoMenuItem;
|
||||
OsuMenuItem redoMenuItem;
|
||||
|
||||
EditorMenuItem cutMenuItem;
|
||||
EditorMenuItem copyMenuItem;
|
||||
EditorMenuItem pasteMenuItem;
|
||||
|
||||
AddInternal(new OsuContextMenuContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -299,19 +296,15 @@ namespace osu.Game.Screens.Edit
|
||||
changeHandler.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true);
|
||||
changeHandler.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true);
|
||||
|
||||
editorBeatmap.SelectedHitObjects.BindCollectionChanged((_, __) =>
|
||||
{
|
||||
bool hasObjects = editorBeatmap.SelectedHitObjects.Count > 0;
|
||||
|
||||
cutMenuItem.Action.Disabled = !hasObjects;
|
||||
copyMenuItem.Action.Disabled = !hasObjects;
|
||||
}, true);
|
||||
|
||||
clipboard.BindValueChanged(content => pasteMenuItem.Action.Disabled = string.IsNullOrEmpty(content.NewValue));
|
||||
|
||||
menuBar.Mode.ValueChanged += onModeChanged;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
setUpClipboardActionAvailability();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the beatmap's track has changed, this method must be called to keep the editor in a valid state.
|
||||
/// </summary>
|
||||
@ -324,7 +317,7 @@ namespace osu.Game.Screens.Edit
|
||||
public void RestoreState([NotNull] EditorState state) => Schedule(() =>
|
||||
{
|
||||
clock.Seek(state.Time);
|
||||
clipboard.Value = state.ClipboardContent;
|
||||
Clipboard.Content.Value = state.ClipboardContent;
|
||||
});
|
||||
|
||||
protected void Save()
|
||||
@ -561,45 +554,37 @@ namespace osu.Game.Screens.Edit
|
||||
this.Exit();
|
||||
}
|
||||
|
||||
private readonly Bindable<string> clipboard = new Bindable<string>();
|
||||
#region Clipboard support
|
||||
|
||||
protected void Cut()
|
||||
private EditorMenuItem cutMenuItem;
|
||||
private EditorMenuItem copyMenuItem;
|
||||
private EditorMenuItem pasteMenuItem;
|
||||
|
||||
private readonly BindableWithCurrent<bool> canCut = new BindableWithCurrent<bool>();
|
||||
private readonly BindableWithCurrent<bool> canCopy = new BindableWithCurrent<bool>();
|
||||
private readonly BindableWithCurrent<bool> canPaste = new BindableWithCurrent<bool>();
|
||||
|
||||
private void setUpClipboardActionAvailability()
|
||||
{
|
||||
Copy();
|
||||
editorBeatmap.RemoveRange(editorBeatmap.SelectedHitObjects.ToArray());
|
||||
canCut.Current.BindValueChanged(cut => cutMenuItem.Action.Disabled = !cut.NewValue, true);
|
||||
canCopy.Current.BindValueChanged(copy => copyMenuItem.Action.Disabled = !copy.NewValue, true);
|
||||
canPaste.Current.BindValueChanged(paste => pasteMenuItem.Action.Disabled = !paste.NewValue, true);
|
||||
}
|
||||
|
||||
protected void Copy()
|
||||
private void rebindClipboardBindables()
|
||||
{
|
||||
if (editorBeatmap.SelectedHitObjects.Count == 0)
|
||||
return;
|
||||
|
||||
clipboard.Value = new ClipboardContent(editorBeatmap).Serialize();
|
||||
canCut.Current = currentScreen.CanCut;
|
||||
canCopy.Current = currentScreen.CanCopy;
|
||||
canPaste.Current = currentScreen.CanPaste;
|
||||
}
|
||||
|
||||
protected void Paste()
|
||||
{
|
||||
if (string.IsNullOrEmpty(clipboard.Value))
|
||||
return;
|
||||
protected void Cut() => currentScreen?.Cut();
|
||||
|
||||
var objects = clipboard.Value.Deserialize<ClipboardContent>().HitObjects;
|
||||
protected void Copy() => currentScreen?.Copy();
|
||||
|
||||
Debug.Assert(objects.Any());
|
||||
protected void Paste() => currentScreen?.Paste();
|
||||
|
||||
double timeOffset = clock.CurrentTime - objects.Min(o => o.StartTime);
|
||||
|
||||
foreach (var h in objects)
|
||||
h.StartTime += timeOffset;
|
||||
|
||||
editorBeatmap.BeginChange();
|
||||
|
||||
editorBeatmap.SelectedHitObjects.Clear();
|
||||
|
||||
editorBeatmap.AddRange(objects);
|
||||
editorBeatmap.SelectedHitObjects.AddRange(objects);
|
||||
|
||||
editorBeatmap.EndChange();
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected void Undo() => changeHandler.RestoreState(-1);
|
||||
|
||||
@ -677,6 +662,7 @@ namespace osu.Game.Screens.Edit
|
||||
finally
|
||||
{
|
||||
updateSampleDisabledState();
|
||||
rebindClipboardBindables();
|
||||
}
|
||||
}
|
||||
|
||||
@ -757,7 +743,7 @@ namespace osu.Game.Screens.Edit
|
||||
protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleDifficultySwitch(nextBeatmap, new EditorState
|
||||
{
|
||||
Time = clock.CurrentTimeAccurate,
|
||||
ClipboardContent = editorBeatmap.BeatmapInfo.RulesetID == nextBeatmap.RulesetID ? clipboard.Value : string.Empty
|
||||
ClipboardContent = editorBeatmap.BeatmapInfo.RulesetID == nextBeatmap.RulesetID ? Clipboard.Content.Value : string.Empty
|
||||
});
|
||||
|
||||
private void cancelExit()
|
||||
|
15
osu.Game/Screens/Edit/EditorClipboard.cs
Normal file
15
osu.Game/Screens/Edit/EditorClipboard.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// 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.Bindables;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps the contents of the editor clipboard.
|
||||
/// </summary>
|
||||
public class EditorClipboard
|
||||
{
|
||||
public Bindable<string> Content { get; } = new Bindable<string>();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
@ -49,5 +50,54 @@ namespace osu.Game.Screens.Edit
|
||||
this.ScaleTo(0.98f, 200, Easing.OutQuint)
|
||||
.FadeOut(200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
#region Clipboard operations
|
||||
|
||||
public BindableBool CanCut { get; } = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// Performs a "cut to clipboard" operation appropriate for the given screen.
|
||||
/// </summary>
|
||||
protected virtual void PerformCut()
|
||||
{
|
||||
}
|
||||
|
||||
public void Cut()
|
||||
{
|
||||
if (CanCut.Value)
|
||||
PerformCut();
|
||||
}
|
||||
|
||||
public BindableBool CanCopy { get; } = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// Performs a "copy to clipboard" operation appropriate for the given screen.
|
||||
/// </summary>
|
||||
protected virtual void PerformCopy()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Copy()
|
||||
{
|
||||
if (CanCopy.Value)
|
||||
PerformCopy();
|
||||
}
|
||||
|
||||
public BindableBool CanPaste { get; } = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// Performs a "paste from clipboard" operation appropriate for the given screen.
|
||||
/// </summary>
|
||||
protected virtual void PerformPaste()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Paste()
|
||||
{
|
||||
if (CanPaste.Value)
|
||||
PerformPaste();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user