From 8580cf164035c591488bce7f071159fa67db637f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 26 Sep 2023 20:36:41 -0400 Subject: [PATCH 1/3] Snapped/unsnapped pasting, plus fixes for selection box and event rendering. --- assets | 2 +- source/funkin/data/song/SongDataUtils.hx | 37 +++++++++++----- .../ui/debug/charting/ChartEditorCommand.hx | 28 ++++++++++++ .../ui/debug/charting/ChartEditorState.hx | 43 +++++++++++++++---- 4 files changed, 90 insertions(+), 20 deletions(-) diff --git a/assets b/assets index af2767368..49ca221a5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit af2767368a273eaaf8010ba0de79f4f1a7482e16 +Subproject commit 49ca221a5c99ce19c8731ab37de711903788124b diff --git a/source/funkin/data/song/SongDataUtils.hx b/source/funkin/data/song/SongDataUtils.hx index 4b9318df2..ee3dfe98c 100644 --- a/source/funkin/data/song/SongDataUtils.hx +++ b/source/funkin/data/song/SongDataUtils.hx @@ -21,11 +21,21 @@ class SongDataUtils * @param notes The notes to modify. * @param offset The time difference to apply in milliseconds. */ - public static function offsetSongNoteData(notes:Array, offset:Int):Array + public static function offsetSongNoteData(notes:Array, offset:Float):Array { - return notes.map(function(note:SongNoteData):SongNoteData { - return new SongNoteData(note.time + offset, note.data, note.length, note.kind); - }); + var offsetNote = function(note:SongNoteData):SongNoteData { + var time:Float = note.time + offset; + var data:Int = note.data; + var length:Float = note.length; + var kind:String = note.kind; + return new SongNoteData(time, data, length, kind); + }; + + trace(notes); + trace(notes[0]); + var result = [for (i in 0...notes.length) offsetNote(notes[i])]; + trace(result); + return result; } /** @@ -36,7 +46,7 @@ class SongDataUtils * @param events The events to modify. * @param offset The time difference to apply in milliseconds. */ - public static function offsetSongEventData(events:Array, offset:Int):Array + public static function offsetSongEventData(events:Array, offset:Float):Array { return events.map(function(event:SongEventData):SongEventData { return new SongEventData(event.time + offset, event.event, event.value); @@ -152,7 +162,8 @@ class SongDataUtils */ public static function writeItemsToClipboard(data:SongClipboardItems):Void { - var dataString = SerializerUtil.toJSON(data); + var writer = new json2object.JsonWriter(); + var dataString:String = writer.write(data, ' '); ClipboardUtil.setClipboard(dataString); @@ -170,19 +181,24 @@ class SongDataUtils trace('Read ${notesString.length} characters from clipboard.'); - var data:SongClipboardItems = notesString.parseJSON(); - - if (data == null) + var parser = new json2object.JsonParser(); + parser.fromJson(notesString, 'clipboard'); + if (parser.errors.length > 0) { - trace('Failed to parse notes from clipboard.'); + trace('[SongDataUtils] Error parsing note JSON data from clipboard.'); + for (error in parser.errors) + DataError.printError(error); return { + valid: false, notes: [], events: [] }; } else { + var data:SongClipboardItems = parser.value; trace('Parsed ' + data.notes.length + ' notes and ' + data.events.length + ' from clipboard.'); + data.valid = true; return data; } } @@ -230,6 +246,7 @@ class SongDataUtils typedef SongClipboardItems = { + ?valid:Bool, notes:Array, events:Array } diff --git a/source/funkin/ui/debug/charting/ChartEditorCommand.hx b/source/funkin/ui/debug/charting/ChartEditorCommand.hx index c358c1d3d..3328336e6 100644 --- a/source/funkin/ui/debug/charting/ChartEditorCommand.hx +++ b/source/funkin/ui/debug/charting/ChartEditorCommand.hx @@ -1,5 +1,7 @@ package funkin.ui.debug.charting; +import haxe.ui.notifications.NotificationType; +import haxe.ui.notifications.NotificationManager; import funkin.data.song.SongData.SongEventData; import funkin.data.song.SongData.SongNoteData; import funkin.data.song.SongDataUtils; @@ -760,6 +762,22 @@ class PasteItemsCommand implements ChartEditorCommand { var currentClipboard:SongClipboardItems = SongDataUtils.readItemsFromClipboard(); + if (currentClipboard.valid != true) + { + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Failed to Paste', + body: 'Could not parse clipboard contents.', + type: NotificationType.Error, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end + return; + } + + trace(currentClipboard.notes); + addedNotes = SongDataUtils.offsetSongNoteData(currentClipboard.notes, Std.int(targetTimestamp)); addedEvents = SongDataUtils.offsetSongEventData(currentClipboard.events, Std.int(targetTimestamp)); @@ -773,6 +791,16 @@ class PasteItemsCommand implements ChartEditorCommand state.notePreviewDirty = true; state.sortChartData(); + + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Paste Successful', + body: 'Successfully pasted clipboard contents.', + type: NotificationType.Success, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end } public function undo(state:ChartEditorState):Void diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 6bf95fcb3..1b982e830 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -1509,11 +1509,11 @@ class ChartEditorState extends HaxeUIState renderedEvents.setPosition(gridTiledSprite.x, gridTiledSprite.y); add(renderedEvents); - renderedNotes.zIndex = 25; + renderedEvents.zIndex = 25; renderedSelectionSquares.setPosition(gridTiledSprite.x, gridTiledSprite.y); add(renderedSelectionSquares); - renderedNotes.zIndex = 26; + renderedSelectionSquares.zIndex = 26; } function buildAdditionalUI():Void @@ -1623,7 +1623,18 @@ class ChartEditorState extends HaxeUIState addUIClickListener('menubarItemCut', _ -> performCommand(new CutItemsCommand(currentNoteSelection, currentEventSelection))); - addUIClickListener('menubarItemPaste', _ -> performCommand(new PasteItemsCommand(scrollPositionInMs + playheadPositionInMs))); + addUIClickListener('menubarItemPaste', _ -> { + var targetMs:Float = scrollPositionInMs + playheadPositionInMs; + var targetStep:Float = Conductor.getTimeInSteps(targetMs); + var targetSnappedStep:Float = Math.floor(targetStep / noteSnapRatio) * noteSnapRatio; + var targetSnappedMs:Float = Conductor.getStepTimeInMs(targetSnappedStep); + performCommand(new PasteItemsCommand(targetSnappedMs)); + }); + + addUIClickListener('menubarItemPasteUnsnapped', _ -> { + var targetMs:Float = scrollPositionInMs + playheadPositionInMs; + performCommand(new PasteItemsCommand(targetMs)); + }); addUIClickListener('menubarItemDelete', function(_) { if (currentNoteSelection.length > 0 && currentEventSelection.length > 0) @@ -2267,7 +2278,6 @@ class ChartEditorState extends HaxeUIState // Scroll up. var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.screenY; scrollPositionInPixels -= diff * 0.5; // Too fast! - trace('Scroll up: ' + diff); moveSongToScrollPosition(); } else if (FlxG.mouse.screenY > (playbarHeadLayout?.y ?? 0.0)) @@ -2275,7 +2285,6 @@ class ChartEditorState extends HaxeUIState // Scroll down. var diff:Float = FlxG.mouse.screenY - (playbarHeadLayout?.y ?? 0.0); scrollPositionInPixels += diff * 0.5; // Too fast! - trace('Scroll down: ' + diff); moveSongToScrollPosition(); } @@ -2900,8 +2909,8 @@ class ChartEditorState extends HaxeUIState // Set the position and size (because we might be recycling one with bad values). selectionSquare.x = noteSprite.x; selectionSquare.y = noteSprite.y; - selectionSquare.width = noteSprite.width; - selectionSquare.height = noteSprite.height; + selectionSquare.width = GRID_SIZE; + selectionSquare.height = GRID_SIZE; } } @@ -2932,6 +2941,8 @@ class ChartEditorState extends HaxeUIState FlxG.watch.addQuick("tapNotesRendered", renderedNotes.members.length); FlxG.watch.addQuick("holdNotesRendered", renderedHoldNotes.members.length); FlxG.watch.addQuick("eventsRendered", renderedEvents.members.length); + FlxG.watch.addQuick("notesSelected", currentNoteSelection.length); + FlxG.watch.addQuick("eventsSelected", currentEventSelection.length); } /** @@ -2961,6 +2972,8 @@ class ChartEditorState extends HaxeUIState if (selectionSquareBitmap == null) throw "ERROR: Tried to build selection square, but selectionSquareBitmap is null! Check ChartEditorThemeHandler.updateSelectionSquare()"; + FlxG.bitmapLog.add(selectionSquareBitmap, "selectionSquareBitmap"); + return new FlxSprite().loadGraphic(selectionSquareBitmap); } @@ -3074,8 +3087,20 @@ class ChartEditorState extends HaxeUIState // CTRL + V = Paste if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.V) { - // Paste notes from clipboard, at the playhead. - performCommand(new PasteItemsCommand(scrollPositionInMs + playheadPositionInMs)); + // CTRL + SHIFT + V = Paste Unsnapped. + var targetMs:Float = if (FlxG.keys.pressed.SHIFT) + { + scrollPositionInMs + playheadPositionInMs; + } + else + { + var targetMs:Float = scrollPositionInMs + playheadPositionInMs; + var targetStep:Float = Conductor.getTimeInSteps(targetMs); + var targetSnappedStep:Float = Math.floor(targetStep / noteSnapRatio) * noteSnapRatio; + var targetSnappedMs:Float = Conductor.getStepTimeInMs(targetSnappedStep); + targetSnappedMs; + } + performCommand(new PasteItemsCommand(targetMs)); } // DELETE = Delete From e2864777e3ab722b3c7ffd0a71b0651b685e09e4 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 15 Oct 2023 00:26:42 -0400 Subject: [PATCH 2/3] Fast forward assets/ --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 49ca221a5..2becb7e61 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 49ca221a5c99ce19c8731ab37de711903788124b +Subproject commit 2becb7e61458c1185bdf23abb87df505eec28676 From ccedd82210b0a0ead6acc913c1a0c04066921860 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 15 Oct 2023 00:34:37 -0400 Subject: [PATCH 3/3] Move FunkinDropdown to FunkinDropDown --- .../ui/haxeui/components/{FunkinDropdown.hx => FunkinDropDown.hx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/funkin/ui/haxeui/components/{FunkinDropdown.hx => FunkinDropDown.hx} (100%) diff --git a/source/funkin/ui/haxeui/components/FunkinDropdown.hx b/source/funkin/ui/haxeui/components/FunkinDropDown.hx similarity index 100% rename from source/funkin/ui/haxeui/components/FunkinDropdown.hx rename to source/funkin/ui/haxeui/components/FunkinDropDown.hx