diff --git a/assets b/assets index 4246be3aa..b282f3431 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4246be3aa353e43772760d02ae9ff262718dee06 +Subproject commit b282f3431c15b719222196813da98ab70839d3e5 diff --git a/source/Main.hx b/source/Main.hx index 5fbb6747b..86e520e69 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -112,5 +112,6 @@ class Main extends Sprite Toolkit.theme = 'dark'; // don't be cringe Toolkit.autoScale = false; funkin.input.Cursor.registerHaxeUICursors(); + haxe.ui.tooltips.ToolTipManager.defaultDelay = 200; } } diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 661902468..1773a84fe 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -15,6 +15,7 @@ import flixel.group.FlxSpriteGroup; import flixel.input.keyboard.FlxKey; import flixel.math.FlxMath; import flixel.math.FlxPoint; +import flixel.graphics.FlxGraphic; import flixel.math.FlxRect; import flixel.sound.FlxSound; import flixel.system.FlxAssets.FlxSoundAsset; @@ -81,6 +82,7 @@ import funkin.ui.debug.charting.components.ChartEditorEventSprite; import funkin.ui.debug.charting.components.ChartEditorHoldNoteSprite; import funkin.ui.debug.charting.components.ChartEditorNotePreview; import funkin.ui.debug.charting.components.ChartEditorNoteSprite; +import funkin.ui.debug.charting.components.ChartEditorMeasureTicks; import funkin.ui.debug.charting.components.ChartEditorPlaybarHead; import funkin.ui.debug.charting.components.ChartEditorSelectionSquareSprite; import funkin.ui.debug.charting.handlers.ChartEditorShortcutHandler; @@ -169,7 +171,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState /** * The width of the scroll area. */ - public static final PLAYHEAD_SCROLL_AREA_WIDTH:Int = 12; + public static final PLAYHEAD_SCROLL_AREA_WIDTH:Int = Std.int(GRID_SIZE); /** * The height of the playhead, in pixels. @@ -335,17 +337,17 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState this.scrollPositionInPixels = value; // Move the grid sprite to the correct position. - if (gridTiledSprite != null && gridPlayheadScrollArea != null) + if (gridTiledSprite != null && measureTicks != null) { if (isViewDownscroll) { gridTiledSprite.y = -scrollPositionInPixels + (MENU_BAR_HEIGHT + GRID_TOP_PAD); - gridPlayheadScrollArea.y = gridTiledSprite.y; + measureTicks.y = gridTiledSprite.y; } else { gridTiledSprite.y = -scrollPositionInPixels + (MENU_BAR_HEIGHT + GRID_TOP_PAD); - gridPlayheadScrollArea.y = gridTiledSprite.y; + measureTicks.y = gridTiledSprite.y; if (audioVisGroup != null && audioVisGroup.playerVis != null) { @@ -367,6 +369,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (selectionBoxStartPos != null) selectionBoxStartPos.y -= diff; // Update the note preview viewport box. setNotePreviewViewportBounds(calculateNotePreviewViewportBounds()); + // Update the measure tick display. + if (measureTicks != null) measureTicks.y = gridTiledSprite?.y ?? 0.0; return this.scrollPositionInPixels; } @@ -1701,23 +1705,28 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState */ var notePreviewViewportBitmap:Null = null; + /**r + * The IMAGE used for the measure ticks. Updated by ChartEditorThemeHandler. + */ + var measureTickBitmap:Null = null; + /** * The tiled sprite used to display the grid. * The height is the length of the song, and scrolling is done by simply the sprite. */ var gridTiledSprite:Null = null; + /** + * The measure ticks area. Includes the numbers and the background sprite. + */ + var measureTicks:Null = null; + /** * The playhead representing the current position in the song. * Can move around on the grid independently of the view. */ var gridPlayhead:FlxSpriteGroup = new FlxSpriteGroup(); - /** - * The sprite for the scroll area under - */ - var gridPlayheadScrollArea:Null = null; - /** * A sprite used to indicate the note that will be placed on click. */ @@ -1875,6 +1884,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState this.updateTheme(); buildGrid(); + buildMeasureTicks(); buildNotePreview(); buildSelectionBox(); @@ -2130,20 +2140,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState buildNoteGroup(); - gridPlayheadScrollArea = new FlxSprite(0, 0); - gridPlayheadScrollArea.makeGraphic(10, 10, PLAYHEAD_SCROLL_AREA_COLOR); // Make it 10x10px and then scale it as needed. - add(gridPlayheadScrollArea); - gridPlayheadScrollArea.setGraphicSize(PLAYHEAD_SCROLL_AREA_WIDTH, 3000); - gridPlayheadScrollArea.updateHitbox(); - gridPlayheadScrollArea.x = gridTiledSprite.x - PLAYHEAD_SCROLL_AREA_WIDTH; - gridPlayheadScrollArea.y = MENU_BAR_HEIGHT + GRID_TOP_PAD; - gridPlayheadScrollArea.zIndex = 25; - // The playhead that show the current position in the song. add(gridPlayhead); gridPlayhead.zIndex = 30; - var playheadWidth:Int = GRID_SIZE * (STRUMLINE_SIZE * 2 + 1) + (PLAYHEAD_SCROLL_AREA_WIDTH * 2); + var playheadWidth:Int = GRID_SIZE * (STRUMLINE_SIZE * 2 + 1) + (PLAYHEAD_SCROLL_AREA_WIDTH); var playheadBaseYPos:Float = MENU_BAR_HEIGHT + GRID_TOP_PAD; gridPlayhead.setPosition(gridTiledSprite.x, playheadBaseYPos); var playheadSprite:FlxSprite = new FlxSprite().makeGraphic(playheadWidth, PLAYHEAD_HEIGHT, PLAYHEAD_COLOR); @@ -2174,11 +2175,22 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState add(audioVisGroup); } + function buildMeasureTicks():Void + { + measureTicks = new ChartEditorMeasureTicks(this); + var measureTicksWidth = (GRID_SIZE); + measureTicks.x = gridTiledSprite.x - measureTicksWidth; + measureTicks.y = MENU_BAR_HEIGHT + GRID_TOP_PAD; + measureTicks.zIndex = 20; + + add(measureTicks); + } + function buildNotePreview():Void { var height:Int = FlxG.height - MENU_BAR_HEIGHT - GRID_TOP_PAD - PLAYBAR_HEIGHT - GRID_TOP_PAD - GRID_TOP_PAD; notePreview = new ChartEditorNotePreview(height); - notePreview.x = 350; + notePreview.x = 320; notePreview.y = MENU_BAR_HEIGHT + GRID_TOP_PAD; add(notePreview); @@ -2258,6 +2270,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState bounds.height = MIN_HEIGHT; } + trace('Note preview viewport bounds: ' + bounds.toString()); + return bounds; } @@ -2868,7 +2882,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (metronomeVolume > 0.0 && this.subState == null && (audioInstTrack != null && audioInstTrack.isPlaying)) { - playMetronomeTick(Conductor.instance.currentBeat % 4 == 0); + playMetronomeTick(Conductor.instance.currentBeat % Conductor.instance.beatsPerMeasure == 0); } // Show the mouse cursor. @@ -3581,7 +3595,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { scrollAnchorScreenPos = null; } - else if (gridPlayheadScrollArea != null && FlxG.mouse.overlaps(gridPlayheadScrollArea) && !isCursorOverHaxeUI) + else if (measureTicks != null && FlxG.mouse.overlaps(measureTicks) && !isCursorOverHaxeUI) { gridPlayheadScrollAreaPressed = true; } @@ -4298,7 +4312,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { targetCursorMode = Pointer; } - else if (gridPlayheadScrollArea != null && FlxG.mouse.overlaps(gridPlayheadScrollArea)) + else if (measureTicks != null && FlxG.mouse.overlaps(measureTicks)) { targetCursorMode = Pointer; } @@ -4592,7 +4606,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Visibly center the Dad health icon. if (healthIconDad != null) { - healthIconDad.x = (gridTiledSprite == null) ? (0) : (gridTiledSprite.x - 45 - (healthIconDad.width / 2)); + healthIconDad.x = (gridTiledSprite == null) ? (0) : (gridTiledSprite.x - 75 - (healthIconDad.width / 2)); healthIconDad.y = (gridTiledSprite == null) ? (0) : (MENU_BAR_HEIGHT + GRID_TOP_PAD + 30 - (healthIconDad.height / 2)); } } @@ -5078,11 +5092,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function onSongLengthChanged():Void { - if (gridTiledSprite != null) gridTiledSprite.height = songLengthInPixels; - if (gridPlayheadScrollArea != null) + if (gridTiledSprite != null) { - gridPlayheadScrollArea.setGraphicSize(Std.int(gridPlayheadScrollArea.width), songLengthInPixels); - gridPlayheadScrollArea.updateHitbox(); + gridTiledSprite.height = songLengthInPixels; + } + if (measureTicks != null) + { + measureTicks.setHeight(songLengthInPixels); } // Remove any notes past the end of the song. @@ -5190,6 +5206,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState selectedDifficulty = prevDifficulty; Conductor.instance.mapTimeChanges(this.currentSongMetadata.timeChanges); + updateTimeSignature(); refreshDifficultyTreeSelection(); this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT); @@ -5343,6 +5360,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (audioVocalTrackGroup != null) audioVocalTrackGroup.volume = vocalTargetVolume; } + function updateTimeSignature():Void + { + // Redo the grid bitmap to be 4/4. + this.updateTheme(); + gridTiledSprite.loadGraphic(gridBitmap); + measureTicks.reloadTickBitmap(); + } + /** * HAXEUI FUNCTIONS */ @@ -5455,6 +5480,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (notePreviewViewportBoundsDirty) { setNotePreviewViewportBounds(calculateNotePreviewViewportBounds()); + notePreviewViewportBoundsDirty = false; } } diff --git a/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx b/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx new file mode 100644 index 000000000..1a76d1e22 --- /dev/null +++ b/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx @@ -0,0 +1,71 @@ +package funkin.ui.debug.charting.components; + +import flixel.FlxSprite; +import flixel.addons.display.FlxTiledSprite; +import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +import flixel.text.FlxText; +import flixel.util.FlxColor; + +@:access(funkin.ui.debug.charting.ChartEditorState) +class ChartEditorMeasureTicks extends FlxTypedSpriteGroup +{ + var chartEditorState:ChartEditorState; + + var tickTiledSprite:FlxTiledSprite; + var measureNumber:FlxText; + + override function set_y(value:Float):Float + { + var result = super.set_y(value); + + updateMeasureNumber(); + + return result; + } + + public function new(chartEditorState:ChartEditorState) + { + super(); + + this.chartEditorState = chartEditorState; + + tickTiledSprite = new FlxTiledSprite(chartEditorState.measureTickBitmap, chartEditorState.measureTickBitmap.width, 1000, false, true); + add(tickTiledSprite); + + measureNumber = new FlxText(0, 0, ChartEditorState.GRID_SIZE, "1"); + measureNumber.setFormat(Paths.font('vcr.ttf'), 20, FlxColor.WHITE); + measureNumber.borderStyle = FlxTextBorderStyle.OUTLINE; + measureNumber.borderColor = FlxColor.BLACK; + add(measureNumber); + } + + public function reloadTickBitmap():Void + { + tickTiledSprite.loadGraphic(chartEditorState.measureTickBitmap); + } + + /** + * At time of writing, we only have to manipulate one measure number because we can only see one measure at a time. + */ + function updateMeasureNumber() + { + if (measureNumber == null) return; + + var viewTopPosition = 0 - this.y; + var viewHeight = FlxG.height - ChartEditorState.MENU_BAR_HEIGHT - ChartEditorState.PLAYBAR_HEIGHT; + var viewBottomPosition = viewTopPosition + viewHeight; + + var measureNumberInViewport = Math.floor(viewTopPosition / ChartEditorState.GRID_SIZE / Conductor.instance.stepsPerMeasure) + 1; + var measureNumberPosition = measureNumberInViewport * ChartEditorState.GRID_SIZE * Conductor.instance.stepsPerMeasure; + + measureNumber.text = '${measureNumberInViewport + 1}'; + measureNumber.y = measureNumberPosition + this.y; + + // trace(measureNumber.text + ' at ' + measureNumber.y); + } + + public function setHeight(songLengthInPixels:Float):Void + { + tickTiledSprite.height = songLengthInPixels; + } +} diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx index 2ef3fd683..4df53663c 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx @@ -194,7 +194,7 @@ class ChartEditorAudioHandler case DAD: state.audioVocalTrackGroup.addOpponentVoice(vocalTrack); state.audioVisGroup.addOpponentVis(vocalTrack); - state.audioVisGroup.opponentVis.x = 435; + state.audioVisGroup.opponentVis.x = 405; state.audioVisGroup.opponentVis.realtimeVisLenght = Conductor.instance.getStepTimeInMs(16) * 0.00195; state.audioVisGroup.opponentVis.daHeight = (ChartEditorState.GRID_SIZE) * 16; diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx index 1d53dfebd..1e1a02974 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx @@ -686,6 +686,7 @@ class ChartEditorDialogHandler Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata. Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges); + state.updateTimeSignature(); state.selectedVariation = Constants.DEFAULT_VARIATION; state.selectedDifficulty = state.availableDifficulties[0]; diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx index a38916c3b..9c86269e8 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx @@ -118,6 +118,7 @@ class ChartEditorImportExportHandler Conductor.instance.forceBPM(null); // Disable the forced BPM. Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata. Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges); + state.updateTimeSignature(); state.notePreviewDirty = true; state.notePreviewViewportBoundsDirty = true; diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx index 1625c53bc..d3aef4bfd 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx @@ -81,6 +81,7 @@ class ChartEditorThemeHandler { updateBackground(state); updateGridBitmap(state); + updateMeasureTicks(state); updateSelectionSquare(state); updateNotePreview(state); } @@ -207,9 +208,6 @@ class ChartEditorThemeHandler } } - // Divider at top - state.gridBitmap.fillRect(new Rectangle(0, 0, state.gridBitmap.width, GRID_MEASURE_DIVIDER_WIDTH / 2), gridMeasureDividerColor); - // Draw vertical dividers between the strumlines. var gridStrumlineDividerColor:FlxColor = switch (state.currentTheme) @@ -233,6 +231,61 @@ class ChartEditorThemeHandler // Else, gridTiledSprite will be built later. } + static function updateMeasureTicks(state:ChartEditorState):Void + { + var measureTickWidth:Int = 6; + var beatTickWidth:Int = 4; + var stepTickWidth:Int = 2; + + // Draw the measure ticks. + var ticksWidth:Int = Std.int(ChartEditorState.GRID_SIZE); // 1 grid squares wide. + var ticksHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.instance.stepsPerMeasure); // 1 measure tall. + state.measureTickBitmap = new BitmapData(ticksWidth, ticksHeight, true); + state.measureTickBitmap.fillRect(new Rectangle(0, 0, ticksWidth, ticksHeight), GRID_BEAT_DIVIDER_COLOR_DARK); + + // Draw the measure ticks. + state.measureTickBitmap.fillRect(new Rectangle(0, 0, state.measureTickBitmap.width, measureTickWidth / 2), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + var bottomTickY:Float = state.measureTickBitmap.height - (measureTickWidth / 2); + state.measureTickBitmap.fillRect(new Rectangle(0, bottomTickY, state.measureTickBitmap.width, measureTickWidth / 2), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + + // Draw the beat ticks. + var beatTick2Y:Float = state.measureTickBitmap.height * 1 / Conductor.instance.beatsPerMeasure - (beatTickWidth / 2); + var beatTick3Y:Float = state.measureTickBitmap.height * 2 / Conductor.instance.beatsPerMeasure - (beatTickWidth / 2); + var beatTick4Y:Float = state.measureTickBitmap.height * 3 / Conductor.instance.beatsPerMeasure - (beatTickWidth / 2); + var beatTickLength:Float = state.measureTickBitmap.width * 2 / 3; + state.measureTickBitmap.fillRect(new Rectangle(0, beatTick2Y, beatTickLength, beatTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, beatTick3Y, beatTickLength, beatTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, beatTick4Y, beatTickLength, beatTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + + // Draw the step ticks. + // TODO: Make this a loop or something. + var stepTick2Y:Float = state.measureTickBitmap.height * 1 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick3Y:Float = state.measureTickBitmap.height * 2 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick4Y:Float = state.measureTickBitmap.height * 3 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick6Y:Float = state.measureTickBitmap.height * 5 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick7Y:Float = state.measureTickBitmap.height * 6 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick8Y:Float = state.measureTickBitmap.height * 7 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick10Y:Float = state.measureTickBitmap.height * 9 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick11Y:Float = state.measureTickBitmap.height * 10 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick12Y:Float = state.measureTickBitmap.height * 11 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick14Y:Float = state.measureTickBitmap.height * 13 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick15Y:Float = state.measureTickBitmap.height * 14 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTick16Y:Float = state.measureTickBitmap.height * 15 / Conductor.instance.stepsPerMeasure - (stepTickWidth / 2); + var stepTickLength:Float = state.measureTickBitmap.width * 1 / 3; + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick2Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick3Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick4Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick6Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick7Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick8Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick10Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick11Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick12Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick14Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick15Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + state.measureTickBitmap.fillRect(new Rectangle(0, stepTick16Y, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT); + } + static function updateSelectionSquare(state:ChartEditorState):Void { var selectionSquareBorderColor:FlxColor = switch (state.currentTheme) @@ -289,14 +342,21 @@ class ChartEditorThemeHandler ChartEditorState.GRID_SIZE - (SELECTION_SQUARE_BORDER_WIDTH * 2), ChartEditorState.GRID_SIZE - (SELECTION_SQUARE_BORDER_WIDTH * 2)), viewportFillColor); - state.notePreviewViewport = new FlxSliceSprite(state.notePreviewViewportBitmap, - new FlxRect(SELECTION_SQUARE_BORDER_WIDTH - + 1, SELECTION_SQUARE_BORDER_WIDTH - + 1, ChartEditorState.GRID_SIZE - - (2 * SELECTION_SQUARE_BORDER_WIDTH + 2), - ChartEditorState.GRID_SIZE - - (2 * SELECTION_SQUARE_BORDER_WIDTH + 2)), - 32, 32); + if (state.notePreviewViewport != null) + { + state.notePreviewViewport.loadGraphic(state.notePreviewViewportBitmap); + } + else + { + state.notePreviewViewport = new FlxSliceSprite(state.notePreviewViewportBitmap, + new FlxRect(SELECTION_SQUARE_BORDER_WIDTH + + 1, SELECTION_SQUARE_BORDER_WIDTH + + 1, + ChartEditorState.GRID_SIZE + - (2 * SELECTION_SQUARE_BORDER_WIDTH + 2), ChartEditorState.GRID_SIZE + - (2 * SELECTION_SQUARE_BORDER_WIDTH + 2)), + 32, 32); + } } public static function buildPlayheadBlock():FlxSprite diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx index 764f516f7..98aa02151 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx @@ -116,6 +116,26 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox } }; + inputTimeSignature.onChange = function(event:UIEvent) { + var timeSignatureStr:String = event.data.text; + var timeSignature = timeSignatureStr.split('/'); + if (timeSignature.length != 2) return; + + var timeSignatureNum:Int = Std.parseInt(timeSignature[0]); + var timeSignatureDen:Int = Std.parseInt(timeSignature[1]); + + var previousTimeSignatureNum:Int = chartEditorState.currentSongMetadata.timeChanges[0].timeSignatureNum; + var previousTimeSignatureDen:Int = chartEditorState.currentSongMetadata.timeChanges[0].timeSignatureDen; + if (timeSignatureNum == previousTimeSignatureNum && timeSignatureDen == previousTimeSignatureDen) return; + + chartEditorState.currentSongMetadata.timeChanges[0].timeSignatureNum = timeSignatureNum; + chartEditorState.currentSongMetadata.timeChanges[0].timeSignatureDen = timeSignatureDen; + + trace('Time signature changed to ${timeSignatureNum}/${timeSignatureDen}'); + + chartEditorState.updateTimeSignature(); + }; + inputOffsetInst.onChange = function(event:UIEvent) { if (event.value == null) return; @@ -174,6 +194,10 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox frameVariation.text = 'Variation: ${chartEditorState.selectedVariation.toTitleCase()}'; frameDifficulty.text = 'Difficulty: ${chartEditorState.selectedDifficulty.toTitleCase()}'; + var currentTimeSignature = '${chartEditorState.currentSongMetadata.timeChanges[0].timeSignatureNum}/${chartEditorState.currentSongMetadata.timeChanges[0].timeSignatureDen}'; + trace('Setting time signature to ${currentTimeSignature}'); + inputTimeSignature.value = {id: currentTimeSignature, text: currentTimeSignature}; + var stageId:String = chartEditorState.currentSongMetadata.playData.stage; var stageData:Null = StageDataParser.parseStageData(stageId); if (inputStage != null)