diff --git a/source/Main.hx b/source/Main.hx index 86e520e69..a7482c8d6 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -111,6 +111,8 @@ class Main extends Sprite Toolkit.init(); Toolkit.theme = 'dark'; // don't be cringe Toolkit.autoScale = false; + // Don't focus on UI elements when they first appear. + haxe.ui.focus.FocusManager.instance.autoFocus = 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 f3236578a..1b9176174 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -366,8 +366,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState } } - updatePlayheadGhostHoldNotes(); - // Move the rendered notes to the correct position. renderedNotes.setPosition(gridTiledSprite?.x ?? 0.0, gridTiledSprite?.y ?? 0.0); renderedHoldNotes.setPosition(gridTiledSprite?.x ?? 0.0, gridTiledSprite?.y ?? 0.0); @@ -375,8 +373,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState renderedSelectionSquares.setPosition(gridTiledSprite?.x ?? 0.0, gridTiledSprite?.y ?? 0.0); // Offset the selection box start position, if we are dragging. if (selectionBoxStartPos != null) selectionBoxStartPos.y -= diff; - // Update the note preview viewport box. + + // Update the note preview. setNotePreviewViewportBounds(calculateNotePreviewViewportBounds()); + refreshNotePreviewPlayheadPosition(); + // Update the measure tick display. if (measureTicks != null) measureTicks.y = gridTiledSprite?.y ?? 0.0; return this.scrollPositionInPixels; @@ -438,6 +439,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState gridPlayhead.y = this.playheadPositionInPixels + (MENU_BAR_HEIGHT + GRID_TOP_PAD); updatePlayheadGhostHoldNotes(); + refreshNotePreviewPlayheadPosition(); return this.playheadPositionInPixels; } @@ -1842,6 +1844,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState */ var notePreviewViewport:Null = null; + /** + * The thin sprite used for representing the playhead on the note preview. + * We move this up and down to represent the current position. + */ + var notePreviewPlayhead:Null = null; + /** * The rectangular sprite used for rendering the selection box. * Uses a 9-slice to stretch the selection box to the correct size without warping. @@ -2219,18 +2227,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState add(gridGhostHoldNote); gridGhostHoldNote.zIndex = 11; - while (gridPlayheadGhostHoldNotes.length < (STRUMLINE_SIZE * 2)) - { - var ghost = new ChartEditorHoldNoteSprite(this); - ghost.alpha = 0.6; - ghost.noteData = null; - ghost.visible = false; - add(ghost); - ghost.zIndex = 11; - - gridPlayheadGhostHoldNotes.push(ghost); - } - gridGhostEvent = new ChartEditorEventSprite(this); gridGhostEvent.alpha = 0.6; gridGhostEvent.eventData = new SongEventData(-1, '', {}); @@ -2300,6 +2296,15 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState add(notePreviewViewport); notePreviewViewport.zIndex = 30; + notePreviewPlayhead = new FlxSprite().makeGraphic(2, 2, 0xFFFF0000); + notePreviewPlayhead.scrollFactor.set(0, 0); + notePreviewPlayhead.scale.set(notePreview.width / 2, 0.5); // Setting width does nothing. + notePreviewPlayhead.updateHitbox(); + notePreviewPlayhead.x = notePreview.x; + notePreviewPlayhead.y = notePreview.y; + add(notePreviewPlayhead); + notePreviewPlayhead.zIndex = 31; + setNotePreviewViewportBounds(calculateNotePreviewViewportBounds()); } @@ -2399,6 +2404,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState } } + function refreshNotePreviewPlayheadPosition():Void + { + if (notePreviewPlayhead == null) return; + + notePreviewPlayhead.y = notePreview.y + (notePreview.height * ((scrollPositionInPixels + playheadPositionInPixels) / songLengthInPixels)); + } + /** * Builds the group that will hold all the notes. */ @@ -4194,7 +4206,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState gridGhostHoldNote.visible = true; gridGhostHoldNote.noteData = gridGhostNote.noteData; gridGhostHoldNote.noteDirection = gridGhostNote.noteData.getDirection(); - gridGhostHoldNote.setHeightDirectly(dragLengthPixels, true); gridGhostHoldNote.updateHoldNotePosition(renderedHoldNotes); @@ -4741,27 +4752,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Do nothing. } - // Place notes at the playhead with the gamepad. - if (FlxG.gamepads.firstActive != null) - { - if (FlxG.gamepads.firstActive.justPressed.DPAD_LEFT) placeNoteAtPlayhead(4); - if (FlxG.gamepads.firstActive.justReleased.DPAD_LEFT) finishPlaceNoteAtPlayhead(4); - if (FlxG.gamepads.firstActive.justPressed.DPAD_DOWN) placeNoteAtPlayhead(5); - if (FlxG.gamepads.firstActive.justReleased.DPAD_DOWN) finishPlaceNoteAtPlayhead(5); - if (FlxG.gamepads.firstActive.justPressed.DPAD_UP) placeNoteAtPlayhead(6); - if (FlxG.gamepads.firstActive.justReleased.DPAD_UP) finishPlaceNoteAtPlayhead(6); - if (FlxG.gamepads.firstActive.justPressed.DPAD_RIGHT) placeNoteAtPlayhead(7); - if (FlxG.gamepads.firstActive.justReleased.DPAD_RIGHT) finishPlaceNoteAtPlayhead(7); - - if (FlxG.gamepads.firstActive.justPressed.X) placeNoteAtPlayhead(0); - if (FlxG.gamepads.firstActive.justReleased.X) finishPlaceNoteAtPlayhead(0); - if (FlxG.gamepads.firstActive.justPressed.A) placeNoteAtPlayhead(1); - if (FlxG.gamepads.firstActive.justReleased.A) finishPlaceNoteAtPlayhead(1); - if (FlxG.gamepads.firstActive.justPressed.Y) placeNoteAtPlayhead(2); - if (FlxG.gamepads.firstActive.justReleased.Y) finishPlaceNoteAtPlayhead(2); - if (FlxG.gamepads.firstActive.justPressed.B) placeNoteAtPlayhead(3); - if (FlxG.gamepads.firstActive.justReleased.B) finishPlaceNoteAtPlayhead(3); - } + updatePlayheadGhostHoldNotes(); } function placeNoteAtPlayhead(column:Int):Void @@ -4781,38 +4772,68 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (notesAtPos.length == 0 && !removeNoteInstead) { + trace('Placing note. ${column}'); var newNoteData:SongNoteData = new SongNoteData(playheadPosSnappedMs, column, 0, noteKindToPlace); performCommand(new AddNotesCommand([newNoteData], FlxG.keys.pressed.CONTROL)); currentLiveInputPlaceNoteData[column] = newNoteData; - gridPlayheadGhostHoldNotes[column].noteData = newNoteData.clone(); - gridPlayheadGhostHoldNotes[column].noteDirection = newNoteData.getDirection(); } else if (removeNoteInstead) { - trace('Removing existing note at position.'); + trace('Removing existing note at position. ${column}'); performCommand(new RemoveNotesCommand(notesAtPos)); } else { - trace('Already a note there.'); + trace('Already a note there. ${column}'); } } function updatePlayheadGhostHoldNotes():Void { - // Update playhead ghost hold notes. - for (index in 0...gridPlayheadGhostHoldNotes.length) + // Ensure all the ghost hold notes exist. + while (gridPlayheadGhostHoldNotes.length < (STRUMLINE_SIZE * 2)) { - var ghostHold = gridPlayheadGhostHoldNotes[index]; - if (ghostHold == null) continue; + var ghost = new ChartEditorHoldNoteSprite(this); + ghost.alpha = 0.6; + ghost.noteData = null; + ghost.visible = false; + ghost.zIndex = 11; + add(ghost); // Don't add to `renderedHoldNotes` because then it will get killed every frame. + + gridPlayheadGhostHoldNotes.push(ghost); + refresh(); + } + + // Update playhead ghost hold notes. + for (column in 0...gridPlayheadGhostHoldNotes.length) + { + var targetNoteData = currentLiveInputPlaceNoteData[column]; + var ghostHold = gridPlayheadGhostHoldNotes[column]; + + if (targetNoteData == null && ghostHold.noteData != null) + { + // Remove the ghost hold note. + ghostHold.noteData = null; + } + + if (targetNoteData != null && ghostHold.noteData == null) + { + // Readd the new ghost hold note. + ghostHold.noteData = targetNoteData.clone(); + ghostHold.noteDirection = ghostHold.noteData.getDirection(); + ghostHold.visible = true; + ghostHold.alpha = 0.6; + ghostHold.setHeightDirectly(0); + ghostHold.updateHoldNotePosition(renderedHoldNotes); + } if (ghostHold.noteData == null) { ghostHold.visible = false; ghostHold.setHeightDirectly(0); - playheadDragLengthCurrent[index] = 0; + playheadDragLengthCurrent[column] = 0; continue; - }; + } var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels; var playheadPosFractionalStep:Float = playheadPos / GRID_SIZE / noteSnapRatio; @@ -4829,22 +4850,25 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var targetNoteLengthStepsInt:Int = Std.int(Math.floor(targetNoteLengthSteps)); var targetNoteLengthPixels:Float = targetNoteLengthSteps * GRID_SIZE; - if (playheadDragLengthCurrent[index] != targetNoteLengthStepsInt) + if (playheadDragLengthCurrent[column] != targetNoteLengthStepsInt) { stretchySounds = !stretchySounds; this.playSound(Paths.sound('chartingSounds/stretch' + (stretchySounds ? '1' : '2') + '_UI')); - playheadDragLengthCurrent[index] = targetNoteLengthStepsInt; + playheadDragLengthCurrent[column] = targetNoteLengthStepsInt; } ghostHold.visible = true; - trace('newHeight: ${targetNoteLengthPixels}'); + ghostHold.alpha = 0.6; ghostHold.setHeightDirectly(targetNoteLengthPixels, true); ghostHold.updateHoldNotePosition(renderedHoldNotes); + trace('lerpLength: ${ghostHold.fullSustainLength}'); + trace('position: ${ghostHold.x}, ${ghostHold.y}'); } else { ghostHold.visible = false; ghostHold.setHeightDirectly(0); - playheadDragLengthCurrent[index] = 0; + playheadDragLengthCurrent[column] = 0; + continue; } } } @@ -4864,14 +4888,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (newNoteLength < Conductor.instance.stepLengthMs) { // Don't extend the note if it's too short. - trace('Not extending note.'); + trace('Not extending note. ${column}'); currentLiveInputPlaceNoteData[column] = null; gridPlayheadGhostHoldNotes[column].noteData = null; } else { // Extend the note to the playhead position. - trace('Extending note.'); + trace('Extending note. ${column}'); this.playSound(Paths.sound('chartingSounds/stretchSNAP_UI')); performCommand(new ExtendNoteLengthCommand(currentLiveInputPlaceNoteData[column], newNoteLength)); currentLiveInputPlaceNoteData[column] = null; diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorGamepadHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorGamepadHandler.hx index 896e2df68..70383d3fd 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorGamepadHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorGamepadHandler.hx @@ -1,133 +1,193 @@ package funkin.ui.debug.charting.handlers; +import haxe.ui.focus.FocusManager; +import flixel.input.gamepad.FlxGamepad; +import haxe.ui.actions.ActionManager; +import haxe.ui.actions.IActionInputSource; +import haxe.ui.actions.ActionType; + /** * Yes, we're that crazy. Gamepad support for the chart editor. */ -@:nullSafety +// @:nullSafety + @:access(funkin.ui.debug.charting.ChartEditorState) class ChartEditorGamepadHandler { public static function handleGamepadControls(chartEditorState:ChartEditorState) { - if (FlxG.gamepads.firstActive == null) return; + if (FlxG.gamepads.firstActive != null) handleGamepad(chartEditorState, FlxG.gamepads.firstActive); + } - if (FlxG.gamepads.firstActive.justPressed.A) + /** + * Handle context-generic binds for the gamepad. + * @param chartEditorState The chart editor state. + * @param gamepad The gamepad to handle. + */ + static function handleGamepad(chartEditorState:ChartEditorState, gamepad:FlxGamepad):Void + { + if (chartEditorState.isHaxeUIFocused) { - // trace('Gamepad: A pressed'); + ChartEditorGamepadActionInputSource.instance.handleGamepad(gamepad); } - if (FlxG.gamepads.firstActive.justPressed.B) + else { - // trace('Gamepad: B pressed'); - } - if (FlxG.gamepads.firstActive.justPressed.X) - { - // trace('Gamepad: X pressed'); - } - if (FlxG.gamepads.firstActive.justPressed.Y) - { - // trace('Gamepad: Y pressed'); + handleGamepadLiveInputs(chartEditorState, gamepad); + + if (gamepad.justPressed.RIGHT_SHOULDER) + { + trace('Gamepad: Right shoulder pressed, toggling audio playback.'); + chartEditorState.toggleAudioPlayback(); + } + + if (gamepad.justPressed.START) + { + var minimal = gamepad.pressed.LEFT_SHOULDER; + chartEditorState.hideAllToolboxes(); + trace('Gamepad: Start pressed, opening playtest (minimal: ${minimal})'); + chartEditorState.testSongInPlayState(minimal); + } + + if (gamepad.justPressed.BACK && !gamepad.pressed.LEFT_SHOULDER) + { + trace('Gamepad: Back pressed, focusing on HaxeUI menu.'); + // FocusManager.instance.focus = chartEditorState.menubarMenuFile; + } + else if (gamepad.justPressed.BACK && gamepad.pressed.LEFT_SHOULDER) + { + trace('Gamepad: Back pressed, unfocusing on HaxeUI menu.'); + FocusManager.instance.focus = null; + } } - if (FlxG.gamepads.firstActive.justPressed.LEFT_SHOULDER) + if (gamepad.justPressed.GUIDE) { - // trace('Gamepad: LEFT_SHOULDER pressed'); - } - if (FlxG.gamepads.firstActive.justPressed.RIGHT_SHOULDER) - { - // trace('Gamepad: RIGHT_SHOULDER pressed'); + trace('Gamepad: Guide pressed, quitting chart editor.'); + chartEditorState.quitChartEditor(); } + } - if (FlxG.gamepads.firstActive.justPressed.LEFT_STICK_CLICK) + static function handleGamepadLiveInputs(chartEditorState:ChartEditorState, gamepad:FlxGamepad):Void + { + // Place notes at the playhead with the gamepad. + // Disable when we are interacting with HaxeUI. + if (!(chartEditorState.isHaxeUIFocused || chartEditorState.isHaxeUIDialogOpen)) { - // trace('Gamepad: LEFT_STICK_CLICK pressed'); - } - if (FlxG.gamepads.firstActive.justPressed.RIGHT_STICK_CLICK) - { - // trace('Gamepad: RIGHT_STICK_CLICK pressed'); - } + if (gamepad.justPressed.DPAD_LEFT) chartEditorState.placeNoteAtPlayhead(4); + if (gamepad.justReleased.DPAD_LEFT) chartEditorState.finishPlaceNoteAtPlayhead(4); + if (gamepad.justPressed.DPAD_DOWN) chartEditorState.placeNoteAtPlayhead(5); + if (gamepad.justReleased.DPAD_DOWN) chartEditorState.finishPlaceNoteAtPlayhead(5); + if (gamepad.justPressed.DPAD_UP) chartEditorState.placeNoteAtPlayhead(6); + if (gamepad.justReleased.DPAD_UP) chartEditorState.finishPlaceNoteAtPlayhead(6); + if (gamepad.justPressed.DPAD_RIGHT) chartEditorState.placeNoteAtPlayhead(7); + if (gamepad.justReleased.DPAD_RIGHT) chartEditorState.finishPlaceNoteAtPlayhead(7); - if (FlxG.gamepads.firstActive.justPressed.LEFT_TRIGGER) - { - // trace('Gamepad: LEFT_TRIGGER pressed'); - } - if (FlxG.gamepads.firstActive.justPressed.RIGHT_TRIGGER) - { - // trace('Gamepad: RIGHT_TRIGGER pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.START) - { - // trace('Gamepad: START pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.BACK) - { - // trace('Gamepad: BACK pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.GUIDE) - { - // trace('Gamepad: GUIDE pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.DPAD_UP) - { - // trace('Gamepad: DPAD_UP pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.DPAD_DOWN) - { - // trace('Gamepad: DPAD_DOWN pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.DPAD_LEFT) - { - // trace('Gamepad: DPAD_LEFT pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.DPAD_RIGHT) - { - // trace('Gamepad: DPAD_RIGHT pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.LEFT_STICK_DIGITAL_UP) - { - // trace('Gamepad: LEFT_STICK_DIGITAL_UP pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.LEFT_STICK_DIGITAL_DOWN) - { - // trace('Gamepad: LEFT_STICK_DIGITAL_DOWN pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.LEFT_STICK_DIGITAL_LEFT) - { - // trace('Gamepad: LEFT_STICK_DIGITAL_LEFT pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.LEFT_STICK_DIGITAL_RIGHT) - { - // trace('Gamepad: LEFT_STICK_DIGITAL_RIGHT pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.RIGHT_STICK_DIGITAL_UP) - { - // trace('Gamepad: RIGHT_STICK_DIGITAL_UP pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.RIGHT_STICK_DIGITAL_DOWN) - { - // trace('Gamepad: RIGHT_STICK_DIGITAL_DOWN pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.RIGHT_STICK_DIGITAL_LEFT) - { - // trace('Gamepad: RIGHT_STICK_DIGITAL_LEFT pressed'); - } - - if (FlxG.gamepads.firstActive.justPressed.RIGHT_STICK_DIGITAL_RIGHT) - { - // trace('Gamepad: RIGHT_STICK_DIGITAL_RIGHT pressed'); + if (gamepad.justPressed.X) chartEditorState.placeNoteAtPlayhead(0); + if (gamepad.justReleased.X) chartEditorState.finishPlaceNoteAtPlayhead(0); + if (gamepad.justPressed.A) chartEditorState.placeNoteAtPlayhead(1); + if (gamepad.justReleased.A) chartEditorState.finishPlaceNoteAtPlayhead(1); + if (gamepad.justPressed.Y) chartEditorState.placeNoteAtPlayhead(2); + if (gamepad.justReleased.Y) chartEditorState.finishPlaceNoteAtPlayhead(2); + if (gamepad.justPressed.B) chartEditorState.placeNoteAtPlayhead(3); + if (gamepad.justReleased.B) chartEditorState.finishPlaceNoteAtPlayhead(3); + } + } +} + +class ChartEditorGamepadActionInputSource implements IActionInputSource +{ + public static var instance:ChartEditorGamepadActionInputSource = new ChartEditorGamepadActionInputSource(); + + public function new() {} + + public function start():Void {} + + /** + * Handle HaxeUI-specific binds for the gamepad. + * Only called when the HaxeUI menu is focused. + * @param chartEditorState The chart editor state. + * @param gamepad The gamepad to handle. + */ + public function handleGamepad(gamepad:FlxGamepad):Void + { + if (gamepad.justPressed.DPAD_LEFT) + { + trace('Gamepad: DPAD_LEFT pressed, moving left.'); + ActionManager.instance.actionStart(ActionType.LEFT, this); + } + else if (gamepad.justReleased.DPAD_LEFT) + { + ActionManager.instance.actionEnd(ActionType.LEFT, this); + } + + if (gamepad.justPressed.DPAD_RIGHT) + { + trace('Gamepad: DPAD_RIGHT pressed, moving right.'); + ActionManager.instance.actionStart(ActionType.RIGHT, this); + } + else if (gamepad.justReleased.DPAD_RIGHT) + { + ActionManager.instance.actionEnd(ActionType.RIGHT, this); + } + + if (gamepad.justPressed.DPAD_UP) + { + trace('Gamepad: DPAD_UP pressed, moving up.'); + ActionManager.instance.actionStart(ActionType.UP, this); + } + else if (gamepad.justReleased.DPAD_UP) + { + ActionManager.instance.actionEnd(ActionType.UP, this); + } + + if (gamepad.justPressed.DPAD_DOWN) + { + trace('Gamepad: DPAD_DOWN pressed, moving down.'); + ActionManager.instance.actionStart(ActionType.DOWN, this); + } + else if (gamepad.justReleased.DPAD_DOWN) + { + ActionManager.instance.actionEnd(ActionType.DOWN, this); + } + + if (gamepad.justPressed.A) + { + trace('Gamepad: A pressed, confirmingg.'); + ActionManager.instance.actionStart(ActionType.CONFIRM, this); + } + else if (gamepad.justReleased.A) + { + ActionManager.instance.actionEnd(ActionType.CONFIRM, this); + } + + if (gamepad.justPressed.B) + { + trace('Gamepad: B pressed, cancelling.'); + ActionManager.instance.actionStart(ActionType.CANCEL, this); + } + else if (gamepad.justReleased.B) + { + ActionManager.instance.actionEnd(ActionType.CANCEL, this); + } + + if (gamepad.justPressed.LEFT_TRIGGER) + { + trace('Gamepad: LEFT_TRIGGER pressed, moving to previous item.'); + ActionManager.instance.actionStart(ActionType.PREVIOUS, this); + } + else if (gamepad.justReleased.LEFT_TRIGGER) + { + ActionManager.instance.actionEnd(ActionType.PREVIOUS, this); + } + + if (gamepad.justPressed.RIGHT_TRIGGER) + { + trace('Gamepad: RIGHT_TRIGGER pressed, moving to next item.'); + ActionManager.instance.actionStart(ActionType.NEXT, this); + } + else if (gamepad.justReleased.RIGHT_TRIGGER) + { + ActionManager.instance.actionEnd(ActionType.NEXT, this); } } } diff --git a/source/funkin/ui/haxeui/FlxGamepadActionInputSource.hx b/source/funkin/ui/haxeui/FlxGamepadActionInputSource.hx new file mode 100644 index 000000000..9c2901d16 --- /dev/null +++ b/source/funkin/ui/haxeui/FlxGamepadActionInputSource.hx @@ -0,0 +1,53 @@ +package funkin.ui.haxeui; + +import flixel.FlxBasic; +import flixel.input.gamepad.FlxGamepad; +import haxe.ui.actions.IActionInputSource; + +/** + * Receives button presses from the Flixel gamepad and emits HaxeUI events. + */ +class FlxGamepadActionInputSource extends FlxBasic +{ + public static var instance(get, null):FlxGamepadActionInputSource; + + static function get_instance():FlxGamepadActionInputSource + { + if (instance == null) instance = new FlxGamepadActionInputSource(); + return instance; + } + + public function new() + { + super(); + } + + public function start():Void + { + FlxG.plugins.addPlugin(this); + } + + public override function update(elapsed:Float):Void + { + super.update(elapsed); + + if (FlxG.gamepads.firstActive != null) + { + updateGamepad(elapsed, FlxG.gamepads.firstActive); + } + } + + function updateGamepad(elapsed:Float, gamepad:FlxGamepad):Void + { + if (gamepad.justPressed.BACK) + { + // + } + } + + public override function destroy():Void + { + super.destroy(); + FlxG.plugins.remove(this); + } +}