mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-11-25 00:06:40 +00:00
Merge pull request #129 from FunkinCrew/feature/chart-editor-note-graph
Chart Editor: Note Preview Graph
This commit is contained in:
commit
ab34bbdcee
|
@ -16,10 +16,10 @@ class ChartEditorNotePreview extends FlxSprite
|
|||
// Constants
|
||||
//
|
||||
static final NOTE_WIDTH:Int = 5;
|
||||
static final NOTE_HEIGHT:Int = 1;
|
||||
static final WIDTH:Int = NOTE_WIDTH * 9;
|
||||
static final NOTE_HEIGHT:Int = 1;
|
||||
|
||||
static final BG_COLOR:FlxColor = FlxColor.GRAY;
|
||||
static final BG_COLOR:FlxColor = 0xFF606060;
|
||||
static final LEFT_COLOR:FlxColor = 0xFFFF22AA;
|
||||
static final DOWN_COLOR:FlxColor = 0xFF00EEFF;
|
||||
static final UP_COLOR:FlxColor = 0xFF00CC00;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package funkin.ui.debug.charting;
|
||||
|
||||
import flixel.math.FlxMath;
|
||||
import haxe.ui.components.TextField;
|
||||
import haxe.ui.components.DropDown;
|
||||
import haxe.ui.components.NumberStepper;
|
||||
|
@ -416,6 +417,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// Make sure view is updated when we change view modes.
|
||||
noteDisplayDirty = true;
|
||||
notePreviewDirty = true;
|
||||
notePreviewViewportBoundsDirty = true;
|
||||
this.scrollPositionInPixels = this.scrollPositionInPixels;
|
||||
|
||||
return isViewDownscroll;
|
||||
|
@ -482,6 +484,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// Make sure view is updated when the variation changes.
|
||||
noteDisplayDirty = true;
|
||||
notePreviewDirty = true;
|
||||
notePreviewViewportBoundsDirty = true;
|
||||
|
||||
return selectedVariation;
|
||||
}
|
||||
|
@ -498,6 +501,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// Make sure view is updated when the difficulty changes.
|
||||
noteDisplayDirty = true;
|
||||
notePreviewDirty = true;
|
||||
notePreviewViewportBoundsDirty = true;
|
||||
|
||||
return selectedDifficulty;
|
||||
}
|
||||
|
@ -514,6 +518,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// Make sure view is updated when the character changes.
|
||||
noteDisplayDirty = true;
|
||||
notePreviewDirty = true;
|
||||
notePreviewViewportBoundsDirty = true;
|
||||
|
||||
return selectedCharacter;
|
||||
}
|
||||
|
@ -531,6 +536,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// Make sure view is updated when we change modes.
|
||||
noteDisplayDirty = true;
|
||||
notePreviewDirty = true;
|
||||
notePreviewViewportBoundsDirty = true;
|
||||
this.scrollPositionInPixels = 0;
|
||||
|
||||
return isInPatternMode;
|
||||
|
@ -550,6 +556,8 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
var notePreviewDirty:Bool = true;
|
||||
|
||||
var notePreviewViewportBoundsDirty:Bool = true;
|
||||
|
||||
/**
|
||||
* Whether the chart has been modified since it was last saved.
|
||||
* Used to determine whether to auto-save, etc.
|
||||
|
@ -673,6 +681,12 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
var gridPlayheadScrollAreaPressed:Bool = false;
|
||||
|
||||
/**
|
||||
* Where the user's last mouse click was on the note preview scroll area.
|
||||
* `null` if the user isn't clicking on the note preview.
|
||||
*/
|
||||
var notePreviewScrollAreaStartPos:FlxPoint = null;
|
||||
|
||||
/**
|
||||
* The SongNoteData which is currently being placed.
|
||||
* As the user drags, we will update this note's sustain length.
|
||||
|
@ -1030,6 +1044,12 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
var selectionSquareBitmap:BitmapData = null;
|
||||
|
||||
/**
|
||||
* The IMAGE used for the note preview bitmap. Updated by ChartEditorThemeHandler.
|
||||
* The image is split and used for a 9-slice sprite for the box over the note preview.
|
||||
*/
|
||||
var notePreviewViewportBitmap:BitmapData = 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.
|
||||
|
@ -1065,6 +1085,12 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
var notePreview:ChartEditorNotePreview;
|
||||
|
||||
/**
|
||||
* The rectangular sprite used for representing the current viewport on the note preview.
|
||||
* We move this up and down and resize it to represent the visible area.
|
||||
*/
|
||||
var notePreviewViewport:FlxSliceSprite;
|
||||
|
||||
/**
|
||||
* The rectangular sprite used for rendering the selection box.
|
||||
* Uses a 9-slice to stretch the selection box to the correct size without warping.
|
||||
|
@ -1280,10 +1306,70 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
function buildNotePreview():Void
|
||||
{
|
||||
var height:Int = FlxG.height - MENU_BAR_HEIGHT - GRID_TOP_PAD - 200;
|
||||
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.y = MENU_BAR_HEIGHT + GRID_TOP_PAD;
|
||||
// add(notePreview);
|
||||
add(notePreview);
|
||||
|
||||
notePreviewViewport.scrollFactor.set(0, 0);
|
||||
add(notePreviewViewport);
|
||||
notePreviewViewport.zIndex = 30;
|
||||
|
||||
setNotePreviewViewportBounds(calculateNotePreviewViewportBounds());
|
||||
}
|
||||
|
||||
function calculateNotePreviewViewportBounds():FlxRect
|
||||
{
|
||||
var bounds:FlxRect = new FlxRect();
|
||||
|
||||
// Horizontal position and width are constant.
|
||||
bounds.x = notePreview.x;
|
||||
bounds.width = notePreview.width;
|
||||
|
||||
// Vertical position depends on scroll position.
|
||||
bounds.y = notePreview.y + (notePreview.height * (scrollPositionInPixels / songLengthInPixels));
|
||||
|
||||
// Height depends on the viewport size.
|
||||
bounds.height = notePreview.height * (FlxG.height / songLengthInPixels);
|
||||
|
||||
// Make sure the viewport doesn't go off the top or bottom of the note preview.
|
||||
if (bounds.y < notePreview.y)
|
||||
{
|
||||
bounds.height -= notePreview.y - bounds.y;
|
||||
bounds.y = notePreview.y;
|
||||
}
|
||||
else if (bounds.y + bounds.height > notePreview.y + notePreview.height)
|
||||
{
|
||||
bounds.height -= (bounds.y + bounds.height) - (notePreview.y + notePreview.height);
|
||||
}
|
||||
|
||||
var MIN_HEIGHT:Int = 8;
|
||||
if (bounds.height < MIN_HEIGHT)
|
||||
{
|
||||
bounds.y -= MIN_HEIGHT - bounds.height;
|
||||
bounds.height = MIN_HEIGHT;
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
function setNotePreviewViewportBounds(bounds:FlxRect = null):Void
|
||||
{
|
||||
if (bounds == null)
|
||||
{
|
||||
notePreviewViewport.visible = false;
|
||||
notePreviewViewport.x = -9999;
|
||||
notePreviewViewport.y = -9999;
|
||||
}
|
||||
else
|
||||
{
|
||||
notePreviewViewport.visible = true;
|
||||
notePreviewViewport.x = bounds.x;
|
||||
notePreviewViewport.y = bounds.y;
|
||||
notePreviewViewport.width = bounds.width;
|
||||
notePreviewViewport.height = bounds.height;
|
||||
}
|
||||
}
|
||||
|
||||
function buildSpectrogram(target:FlxSound):Void
|
||||
|
@ -1622,7 +1708,7 @@ class ChartEditorState extends HaxeUIState
|
|||
handleToolboxes();
|
||||
handlePlaybar();
|
||||
handlePlayhead();
|
||||
// handleNotePreview();
|
||||
handleNotePreview();
|
||||
|
||||
handleFileKeybinds();
|
||||
handleEditKeybinds();
|
||||
|
@ -1907,6 +1993,11 @@ class ChartEditorState extends HaxeUIState
|
|||
{
|
||||
gridPlayheadScrollAreaPressed = true;
|
||||
}
|
||||
else if (FlxG.mouse.overlaps(notePreview))
|
||||
{
|
||||
// Clicked note preview
|
||||
notePreviewScrollAreaStartPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
||||
}
|
||||
else if (!overlapsGrid || overlapsSelectionBorder)
|
||||
{
|
||||
selectionBoxStartPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
||||
|
@ -1924,6 +2015,10 @@ class ChartEditorState extends HaxeUIState
|
|||
{
|
||||
Cursor.cursorMode = Grabbing;
|
||||
}
|
||||
else if (notePreviewScrollAreaStartPos != null)
|
||||
{
|
||||
Cursor.cursorMode = Pointer;
|
||||
}
|
||||
else if (FlxG.mouse.overlaps(gridPlayheadScrollArea))
|
||||
{
|
||||
Cursor.cursorMode = Pointer;
|
||||
|
@ -1938,6 +2033,11 @@ class ChartEditorState extends HaxeUIState
|
|||
gridPlayheadScrollAreaPressed = false;
|
||||
}
|
||||
|
||||
if (notePreviewScrollAreaStartPos != null && FlxG.mouse.released)
|
||||
{
|
||||
notePreviewScrollAreaStartPos = null;
|
||||
}
|
||||
|
||||
if (gridPlayheadScrollAreaPressed)
|
||||
{
|
||||
// Clicked on the playhead scroll area.
|
||||
|
@ -2185,6 +2285,14 @@ class ChartEditorState extends HaxeUIState
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (notePreviewScrollAreaStartPos != null)
|
||||
{
|
||||
trace('Updating current song time while clicking and holding...');
|
||||
var clickedPosInPixels:Float = FlxMath.remapToRange(FlxG.mouse.screenY, notePreview.y, notePreview.y + notePreview.height, 0, songLengthInPixels);
|
||||
|
||||
scrollPositionInPixels = clickedPosInPixels;
|
||||
moveSongToScrollPosition();
|
||||
}
|
||||
else if (currentPlaceNoteData != null)
|
||||
{
|
||||
// Handle extending the note as you drag.
|
||||
|
@ -3214,7 +3322,6 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
function handleNotePreview():Void
|
||||
{
|
||||
// TODO: Finish this.
|
||||
if (notePreviewDirty)
|
||||
{
|
||||
notePreviewDirty = false;
|
||||
|
@ -3224,13 +3331,12 @@ class ChartEditorState extends HaxeUIState
|
|||
notePreview.addNotes(currentSongChartNoteData, Std.int(songLengthInMs));
|
||||
notePreview.addEvents(currentSongChartEventData, Std.int(songLengthInMs));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a spot update on the note preview, by editing the note preview
|
||||
* only where necessary. More efficient than a full update.
|
||||
*/
|
||||
function updateNotePreview(note:SongNoteData, ?deleteNote:Bool = false):Void {}
|
||||
if (notePreviewViewportBoundsDirty)
|
||||
{
|
||||
setNotePreviewViewportBounds(calculateNotePreviewViewportBounds());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles passive behavior of the menu bar, such as updating labels or enabled/disabled status.
|
||||
|
@ -3336,6 +3442,9 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
// We need to update the note sprites.
|
||||
noteDisplayDirty = true;
|
||||
|
||||
// Update the note preview viewport box.
|
||||
setNotePreviewViewportBounds(calculateNotePreviewViewportBounds());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3500,6 +3609,8 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
// Offset the selection box start position, if we are dragging.
|
||||
if (selectionBoxStartPos != null) selectionBoxStartPos.y -= diff;
|
||||
// Update the note preview viewport box.
|
||||
setNotePreviewViewportBounds(calculateNotePreviewViewportBounds());
|
||||
|
||||
return this.scrollPositionInPixels;
|
||||
}
|
||||
|
@ -3759,6 +3870,9 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
loadSong(songMetadata, songChartData);
|
||||
|
||||
notePreviewDirty = true;
|
||||
notePreviewViewportBoundsDirty = true;
|
||||
|
||||
if (audioInstTrack != null)
|
||||
{
|
||||
audioInstTrack.stop();
|
||||
|
|
|
@ -64,6 +64,14 @@ class ChartEditorThemeHandler
|
|||
static final PLAYHEAD_BLOCK_BORDER_COLOR:FlxColor = 0xFF9D0011;
|
||||
static final PLAYHEAD_BLOCK_FILL_COLOR:FlxColor = 0xFFBD0231;
|
||||
|
||||
// Border on the square over the note preview.
|
||||
static final NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_LIGHT = 0xFFF8A657;
|
||||
static final NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_DARK = 0xFFF8A657;
|
||||
|
||||
// Fill on the square over the note preview.
|
||||
static final NOTE_PREVIEW_VIEWPORT_FILL_COLOR_LIGHT = 0x80F8A657;
|
||||
static final NOTE_PREVIEW_VIEWPORT_FILL_COLOR_DARK = 0x80F8A657;
|
||||
|
||||
static final TOTAL_COLUMN_COUNT:Int = ChartEditorState.STRUMLINE_SIZE * 2 + 1;
|
||||
|
||||
/**
|
||||
|
@ -75,6 +83,7 @@ class ChartEditorThemeHandler
|
|||
updateBackground(state);
|
||||
updateGridBitmap(state);
|
||||
updateSelectionSquare(state);
|
||||
updateNotePreview(state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +125,7 @@ class ChartEditorThemeHandler
|
|||
// 2 * (Strumline Size) + 1 grid squares wide, by (4 * quarter notes per measure) grid squares tall.
|
||||
// This gets reused to fill the screen.
|
||||
var gridWidth:Int = Std.int(ChartEditorState.GRID_SIZE * TOTAL_COLUMN_COUNT);
|
||||
var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.stepsPerMeasure);
|
||||
var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.stepsPerMeasure * state.currentZoomLevel);
|
||||
state.gridBitmap = FlxGridOverlay.createGrid(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, gridWidth, gridHeight, true, gridColor1, gridColor2);
|
||||
|
||||
// Selection borders
|
||||
|
@ -234,6 +243,39 @@ class ChartEditorThemeHandler
|
|||
32, 32);
|
||||
}
|
||||
|
||||
static function updateNotePreview(state:ChartEditorState):Void
|
||||
{
|
||||
var viewportBorderColor:FlxColor = switch (state.currentTheme)
|
||||
{
|
||||
case Light: NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_LIGHT;
|
||||
case Dark: NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_DARK;
|
||||
default: NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
var viewportFillColor:FlxColor = switch (state.currentTheme)
|
||||
{
|
||||
case Light: NOTE_PREVIEW_VIEWPORT_FILL_COLOR_LIGHT;
|
||||
case Dark: NOTE_PREVIEW_VIEWPORT_FILL_COLOR_DARK;
|
||||
default: NOTE_PREVIEW_VIEWPORT_FILL_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
state.notePreviewViewportBitmap = new BitmapData(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, true);
|
||||
|
||||
state.notePreviewViewportBitmap.fillRect(new Rectangle(0, 0, ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE), viewportBorderColor);
|
||||
state.notePreviewViewportBitmap.fillRect(new Rectangle(SELECTION_SQUARE_BORDER_WIDTH, SELECTION_SQUARE_BORDER_WIDTH,
|
||||
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);
|
||||
}
|
||||
|
||||
public static function buildPlayheadBlock():FlxSprite
|
||||
{
|
||||
var playheadBlock:FlxSprite = new FlxSprite();
|
||||
|
|
Loading…
Reference in a new issue