mirror of
https://github.com/ppy/osu.git
synced 2025-03-11 06:37:19 +08:00
Merge pull request #31806 from bdach/bookmark-follow-ups
Improve bookmark controls
This commit is contained in:
commit
dd53ae0e02
148
osu.Game/Screens/Edit/BookmarkController.cs
Normal file
148
osu.Game/Screens/Edit/BookmarkController.cs
Normal file
@ -0,0 +1,148 @@
|
||||
// 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 System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.Edit.Components.Menus;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
public partial class BookmarkController : Component, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
public EditorMenuItem Menu { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
private EditorClock clock { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private EditorBeatmap editorBeatmap { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private IDialogOverlay? dialogOverlay { get; set; }
|
||||
|
||||
private readonly BindableList<int> bookmarks = new BindableList<int>();
|
||||
|
||||
private readonly EditorMenuItem removeBookmarkMenuItem;
|
||||
private readonly EditorMenuItem seekToPreviousBookmarkMenuItem;
|
||||
private readonly EditorMenuItem seekToNextBookmarkMenuItem;
|
||||
private readonly EditorMenuItem resetBookmarkMenuItem;
|
||||
|
||||
public BookmarkController()
|
||||
{
|
||||
Menu = new EditorMenuItem(EditorStrings.Bookmarks)
|
||||
{
|
||||
Items = new MenuItem[]
|
||||
{
|
||||
new EditorMenuItem(EditorStrings.AddBookmark, MenuItemType.Standard, addBookmarkAtCurrentTime)
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorAddBookmark),
|
||||
},
|
||||
removeBookmarkMenuItem = new EditorMenuItem(EditorStrings.RemoveClosestBookmark, MenuItemType.Destructive, removeClosestBookmark)
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorRemoveClosestBookmark)
|
||||
},
|
||||
seekToPreviousBookmarkMenuItem = new EditorMenuItem(EditorStrings.SeekToPreviousBookmark, MenuItemType.Standard, () => seekBookmark(-1))
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorSeekToPreviousBookmark)
|
||||
},
|
||||
seekToNextBookmarkMenuItem = new EditorMenuItem(EditorStrings.SeekToNextBookmark, MenuItemType.Standard, () => seekBookmark(1))
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorSeekToNextBookmark)
|
||||
},
|
||||
resetBookmarkMenuItem = new EditorMenuItem(EditorStrings.ResetBookmarks, MenuItemType.Destructive, () => dialogOverlay?.Push(new BookmarkResetDialog(editorBeatmap)))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
bookmarks.BindTo(editorBeatmap.Bookmarks);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
bool hasAnyBookmark = bookmarks.Count > 0;
|
||||
bool hasBookmarkCloseEnoughForDeletion = bookmarks.Any(b => Math.Abs(b - clock.CurrentTimeAccurate) < 2000);
|
||||
|
||||
removeBookmarkMenuItem.Action.Disabled = !hasBookmarkCloseEnoughForDeletion;
|
||||
seekToPreviousBookmarkMenuItem.Action.Disabled = !hasAnyBookmark;
|
||||
seekToNextBookmarkMenuItem.Action.Disabled = !hasAnyBookmark;
|
||||
resetBookmarkMenuItem.Action.Disabled = !hasAnyBookmark;
|
||||
}
|
||||
|
||||
private void addBookmarkAtCurrentTime()
|
||||
{
|
||||
int bookmark = (int)clock.CurrentTimeAccurate;
|
||||
int idx = bookmarks.BinarySearch(bookmark);
|
||||
if (idx < 0)
|
||||
bookmarks.Insert(~idx, bookmark);
|
||||
}
|
||||
|
||||
private void removeClosestBookmark()
|
||||
{
|
||||
if (removeBookmarkMenuItem.Action.Disabled)
|
||||
return;
|
||||
|
||||
int closestBookmark = bookmarks.MinBy(b => Math.Abs(b - clock.CurrentTimeAccurate));
|
||||
bookmarks.Remove(closestBookmark);
|
||||
}
|
||||
|
||||
private void seekBookmark(int direction)
|
||||
{
|
||||
int? targetBookmark = direction < 1
|
||||
? bookmarks.Cast<int?>().LastOrDefault(b => b < clock.CurrentTimeAccurate)
|
||||
: bookmarks.Cast<int?>().FirstOrDefault(b => b > clock.CurrentTimeAccurate);
|
||||
|
||||
if (targetBookmark != null)
|
||||
clock.SeekSmoothlyTo(targetBookmark.Value);
|
||||
}
|
||||
|
||||
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case GlobalAction.EditorSeekToPreviousBookmark:
|
||||
seekBookmark(-1);
|
||||
return true;
|
||||
|
||||
case GlobalAction.EditorSeekToNextBookmark:
|
||||
seekBookmark(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e.Repeat)
|
||||
return false;
|
||||
|
||||
switch (e.Action)
|
||||
{
|
||||
case GlobalAction.EditorAddBookmark:
|
||||
addBookmarkAtCurrentTime();
|
||||
return true;
|
||||
|
||||
case GlobalAction.EditorRemoveClosestBookmark:
|
||||
removeClosestBookmark();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -317,6 +317,9 @@ namespace osu.Game.Screens.Edit
|
||||
workingBeatmapUpdated = true;
|
||||
});
|
||||
|
||||
var bookmarkController = new BookmarkController();
|
||||
AddInternal(bookmarkController);
|
||||
|
||||
OsuMenuItem undoMenuItem;
|
||||
OsuMenuItem redoMenuItem;
|
||||
|
||||
@ -442,29 +445,7 @@ namespace osu.Game.Screens.Edit
|
||||
Items = new MenuItem[]
|
||||
{
|
||||
new EditorMenuItem(EditorStrings.SetPreviewPointToCurrent, MenuItemType.Standard, SetPreviewPointToCurrentTime),
|
||||
new EditorMenuItem(EditorStrings.Bookmarks)
|
||||
{
|
||||
Items = new MenuItem[]
|
||||
{
|
||||
new EditorMenuItem(EditorStrings.AddBookmark, MenuItemType.Standard, addBookmarkAtCurrentTime)
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorAddBookmark),
|
||||
},
|
||||
new EditorMenuItem(EditorStrings.RemoveClosestBookmark, MenuItemType.Destructive, removeBookmarksInProximityToCurrentTime)
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorRemoveClosestBookmark)
|
||||
},
|
||||
new EditorMenuItem(EditorStrings.SeekToPreviousBookmark, MenuItemType.Standard, () => seekBookmark(-1))
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorSeekToPreviousBookmark)
|
||||
},
|
||||
new EditorMenuItem(EditorStrings.SeekToNextBookmark, MenuItemType.Standard, () => seekBookmark(1))
|
||||
{
|
||||
Hotkey = new Hotkey(GlobalAction.EditorSeekToNextBookmark)
|
||||
},
|
||||
new EditorMenuItem(EditorStrings.ResetBookmarks, MenuItemType.Destructive, () => dialogOverlay?.Push(new BookmarkResetDialog(editorBeatmap)))
|
||||
}
|
||||
}
|
||||
bookmarkController.Menu,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -800,14 +781,6 @@ namespace osu.Game.Screens.Edit
|
||||
case GlobalAction.EditorSeekToNextSamplePoint:
|
||||
seekSamplePoint(1);
|
||||
return true;
|
||||
|
||||
case GlobalAction.EditorSeekToPreviousBookmark:
|
||||
seekBookmark(-1);
|
||||
return true;
|
||||
|
||||
case GlobalAction.EditorSeekToNextBookmark:
|
||||
seekBookmark(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e.Repeat)
|
||||
@ -815,14 +788,6 @@ namespace osu.Game.Screens.Edit
|
||||
|
||||
switch (e.Action)
|
||||
{
|
||||
case GlobalAction.EditorAddBookmark:
|
||||
addBookmarkAtCurrentTime();
|
||||
return true;
|
||||
|
||||
case GlobalAction.EditorRemoveClosestBookmark:
|
||||
removeBookmarksInProximityToCurrentTime();
|
||||
return true;
|
||||
|
||||
case GlobalAction.EditorCloneSelection:
|
||||
Clone();
|
||||
return true;
|
||||
@ -855,19 +820,6 @@ namespace osu.Game.Screens.Edit
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addBookmarkAtCurrentTime()
|
||||
{
|
||||
int bookmark = (int)clock.CurrentTimeAccurate;
|
||||
int idx = editorBeatmap.Bookmarks.BinarySearch(bookmark);
|
||||
if (idx < 0)
|
||||
editorBeatmap.Bookmarks.Insert(~idx, bookmark);
|
||||
}
|
||||
|
||||
private void removeBookmarksInProximityToCurrentTime()
|
||||
{
|
||||
editorBeatmap.Bookmarks.RemoveAll(b => Math.Abs(b - clock.CurrentTimeAccurate) < 2000);
|
||||
}
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
|
||||
{
|
||||
}
|
||||
@ -1202,16 +1154,6 @@ namespace osu.Game.Screens.Edit
|
||||
clock.SeekSmoothlyTo(found.StartTime);
|
||||
}
|
||||
|
||||
private void seekBookmark(int direction)
|
||||
{
|
||||
int? targetBookmark = direction < 1
|
||||
? editorBeatmap.Bookmarks.Cast<int?>().LastOrDefault(b => b < clock.CurrentTimeAccurate)
|
||||
: editorBeatmap.Bookmarks.Cast<int?>().FirstOrDefault(b => b > clock.CurrentTimeAccurate);
|
||||
|
||||
if (targetBookmark != null)
|
||||
clock.SeekSmoothlyTo(targetBookmark.Value);
|
||||
}
|
||||
|
||||
private void seekSamplePoint(int direction)
|
||||
{
|
||||
double currentTime = clock.CurrentTimeAccurate;
|
||||
|
@ -115,7 +115,9 @@ namespace osu.Game.Screens.Edit
|
||||
if (editorBeatmap.Bookmarks.Contains(newBookmark))
|
||||
continue;
|
||||
|
||||
editorBeatmap.Bookmarks.Add(newBookmark);
|
||||
int idx = editorBeatmap.Bookmarks.BinarySearch(newBookmark);
|
||||
if (idx < 0)
|
||||
editorBeatmap.Bookmarks.Insert(~idx, newBookmark);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user