package funkin.mobile.ui.mainmenu; import flixel.FlxG; import flixel.tweens.FlxTween; import flixel.util.FlxSignal; import flixel.util.FlxTimer; import funkin.audio.FunkinSound; import funkin.util.HapticUtil; class FunkinOptionsButton extends FunkinButton { public var onConfirmStart(default, null):FlxSignal = new FlxSignal(); public var onConfirmEnd(default, null):FlxSignal = new FlxSignal(); public var enabled:Bool = true; public var confirming(get, never):Bool; function get_confirming():Bool { return _confirming; } var _confirming:Bool = false; var instant:Bool = false; var held:Bool = false; /** * Creates a new FunkinOptionsButton instance. * * @param x The x position of the object. * @param y The y position of the object. * @param confirmCallback An optional callback function that will be triggered when the object is clicked. * @param instant An optional flag that makes the button not play the full animation before calling the callback. */ public function new(?x:Float = 0, ?y:Float = 0, ?confirmCallback:Void->Void, instant:Bool = false):Void { super(x, y); frames = Paths.getSparrowAtlas("mainmenu/optionsButton"); animation.addByIndices('idle', 'options', [0], "", 24, false); animation.addByIndices('hold', 'options', [3], "", 24, false); animation.addByIndices('confirm', 'options', [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], "", 24, false); animation.play("idle"); scale.set(0.7, 0.7); updateHitbox(); this.instant = instant; this.ignoreDownHandler = true; onUp.add(playConfirmAnim); onDown.add(playHoldAnim); onOut.add(playOutAnim); onConfirmEnd.add(confirmCallback); } function playHoldAnim():Void { if (confirming || held || !enabled) return; held = true; FlxTween.cancelTweensOf(this); HapticUtil.vibrate(0, 0.01, 0.2); animation.play('hold'); } function playConfirmAnim():Void { if (instant) { onConfirmEnd.dispatch(); return; } else if (confirming) { return; } _confirming = true; FlxTween.cancelTweensOf(this); HapticUtil.vibrate(0, 0.05, 0.5); animation.play('confirm'); FunkinSound.playOnce(Paths.sound('confirmMenu')); new FlxTimer().start(0.05, function(_) { HapticUtil.vibrate(0, 0.01, 0.2); }, 4); onConfirmStart.dispatch(); animation.onFinish.addOnce(function(name:String) { if (name != 'confirm') return; _confirming = false; held = false; onConfirmEnd.dispatch(); }); } function playOutAnim():Void { if (confirming || !enabled) return; FlxTween.cancelTweensOf(this); HapticUtil.vibrate(0, 0.01, 0.2); animation.play('idle'); held = false; } public function resetCallbacks():Void { onUp.removeAll(); onDown.removeAll(); onOut.removeAll(); _confirming = false; held = false; onUp.add(playConfirmAnim); onDown.add(playHoldAnim); onOut.add(playOutAnim); } override function destroy():Void { super.destroy(); onConfirmStart.removeAll(); onConfirmEnd.removeAll(); if (animation != null && animation.onFinish != null) animation.onFinish.removeAll(); } }