diff --git a/assets/images/ui/button.png b/assets/images/ui/button.png index 0712ec25e8..3a39af5069 100644 Binary files a/assets/images/ui/button.png and b/assets/images/ui/button.png differ diff --git a/flixel/ui/FlxButton.hx b/flixel/ui/FlxButton.hx index 64311f3dd4..dd2bdc1f63 100644 --- a/flixel/ui/FlxButton.hx +++ b/flixel/ui/FlxButton.hx @@ -18,6 +18,21 @@ import flixel.util.FlxDestroyUtil; import flixel.input.touch.FlxTouch; #end +enum abstract FlxButtonState(Int) to Int +{ + /** The button is not highlighted or pressed */ + var NORMAL = 0; + + /** The button is selected, usually meaning the mouse is hovering over it */ + var HIGHLIGHT = 1; + + /** The button is being pressed usually by a mouse */ + var PRESSED = 2; + + /** The button is not interactible */ + var DISABLED = 3; +} + /** * A simple button class that calls a function when clicked by the mouse. */ @@ -26,17 +41,30 @@ class FlxButton extends FlxTypedButton /** * Used with public variable status, means not highlighted or pressed. */ - public static inline var NORMAL:Int = 0; + @:dox(hide) @:noCompletion + @:deprecated("FlxButton.NORMAL is deprecated, use FlxButtonState.NORMAL") + public static inline var NORMAL = FlxButtonState.NORMAL; /** * Used with public variable status, means highlighted (usually from mouse over). */ - public static inline var HIGHLIGHT:Int = 1; + @:dox(hide) @:noCompletion + @:deprecated("FlxButton.HIGHLIGHT is deprecated, use FlxButtonState.HIGHLIGHT") + public static inline var HIGHLIGHT = FlxButtonState.HIGHLIGHT; /** * Used with public variable status, means pressed (usually from mouse click). */ - public static inline var PRESSED:Int = 2; + @:dox(hide) @:noCompletion + @:deprecated("FlxButton.PRESSED is deprecated, use FlxButtonState.PRESSED") + public static inline var PRESSED = FlxButtonState.PRESSED; + + /** + * Used with public variable status, means non interactible. + */ + @:dox(hide) @:noCompletion + @:deprecated("FlxButton.DISABLED is deprecated, use FlxButtonState.DISABLED") + public static inline var DISABLED = FlxButtonState.DISABLED; /** * Shortcut to setting label.text @@ -80,7 +108,7 @@ class FlxButton extends FlxTypedButton { if (Text != null) { - label = new FlxText(x + labelOffsets[NORMAL].x, y + labelOffsets[NORMAL].y, 80, Text); + label = new FlxText(x + labelOffsets[FlxButtonState.NORMAL].x, y + labelOffsets[FlxButtonState.NORMAL].y, 80, Text); label.setFormat(null, 8, 0x333333, "center"); label.alpha = labelAlphas[status]; label.drawFrame(true); @@ -122,19 +150,19 @@ class FlxTypedButton extends FlxSprite implements IFlxInput /** * What offsets the `label` should have for each status. */ - public var labelOffsets:Array = [FlxPoint.get(), FlxPoint.get(), FlxPoint.get(0, 1)]; + public var labelOffsets:Array = [FlxPoint.get(), FlxPoint.get(), FlxPoint.get(0, 1), FlxPoint.get()]; /** * What alpha value the label should have for each status. Default is `[0.8, 1.0, 0.5]`. * Multiplied with the button's `alpha`. */ - public var labelAlphas:Array = [0.8, 1.0, 0.5]; + public var labelAlphas:Array = [0.8, 1.0, 0.5, 0.3]; /** * What animation should be played for each status. * Default is ["normal", "highlight", "pressed"]. */ - public var statusAnimations:Array = ["normal", "highlight", "pressed"]; + public var statusAnimations:Array = ["normal", "highlight", "pressed", "disabled"]; /** * Whether you can press the button simply by releasing the touch / mouse button over it (default). @@ -157,10 +185,10 @@ class FlxTypedButton extends FlxSprite implements IFlxInput public var maxInputMovement:Float = Math.POSITIVE_INFINITY; /** - * Shows the current state of the button, either `FlxButton.NORMAL`, - * `FlxButton.HIGHLIGHT` or `FlxButton.PRESSED`. + * Shows the current state of the button, either `NORMAL`, + * `HIGHLIGHT` or `PRESSED`. */ - public var status(default, set):Int; + public var status(default, set):FlxButtonState; /** * The properties of this button's `onUp` event (callback function, sound). @@ -222,7 +250,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput onOver = new FlxButtonEvent(); onOut = new FlxButtonEvent(); - status = FlxButton.NORMAL; + status = NORMAL; // Since this is a UI element, the default scrollFactor is (0, 0) scrollFactor.set(); @@ -232,8 +260,8 @@ class FlxTypedButton extends FlxSprite implements IFlxInput #end #if FLX_NO_MOUSE // no need for highlight frame without mouse input - statusAnimations[FlxButton.HIGHLIGHT] = "normal"; - labelAlphas[FlxButton.HIGHLIGHT] = 1; + statusAnimations[HIGHLIGHT] = "normal"; + labelAlphas[HIGHLIGHT] = 1; #end input = new FlxInput(0); @@ -243,9 +271,10 @@ class FlxTypedButton extends FlxSprite implements IFlxInput { super.graphicLoaded(); - setupAnimation("normal", FlxButton.NORMAL); - setupAnimation("highlight", FlxButton.HIGHLIGHT); - setupAnimation("pressed", FlxButton.PRESSED); + setupAnimation("normal", NORMAL); + setupAnimation("highlight", HIGHLIGHT); + setupAnimation("pressed", PRESSED); + setupAnimation("disabled", DISABLED); } function loadDefaultGraphic():Void @@ -384,6 +413,9 @@ class FlxTypedButton extends FlxSprite implements IFlxInput */ function updateButton():Void { + // Prevent interactions with this input if it's currently disabled + if (status == DISABLED) + return; // We're looking for any touch / mouse overlaps with this button var overlapFound = checkMouseOverlap(); if (!overlapFound) @@ -394,7 +426,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput onUpHandler(); } - if (status != FlxButton.NORMAL && (!overlapFound || (currentInput != null && currentInput.justReleased))) + if (status != NORMAL && (!overlapFound || (currentInput != null && currentInput.justReleased))) { onOutHandler(); } @@ -464,7 +496,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput currentInput = input; onDownHandler(); } - else if (status == FlxButton.NORMAL) + else if (status == NORMAL) { // Allow "swiping" to press a button (dragging it over the button while pressed) if (allowSwiping && input.pressed) @@ -489,7 +521,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput function updateLabelAlpha() { - if (_spriteLabel != null && labelAlphas.length > status) + if (_spriteLabel != null && labelAlphas.length > (status : Int)) { _spriteLabel.alpha = alpha * labelAlphas[status]; } @@ -502,7 +534,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput #if FLX_MOUSE function onUpEventListener(_):Void { - if (visible && exists && active && status == FlxButton.PRESSED) + if (visible && exists && active && status == PRESSED) { onUpHandler(); } @@ -514,7 +546,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput */ function onUpHandler():Void { - status = FlxButton.HIGHLIGHT; + status = HIGHLIGHT; input.release(); currentInput = null; // Order matters here, because onUp.fire() could cause a state change and destroy this object. @@ -526,7 +558,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput */ function onDownHandler():Void { - status = FlxButton.PRESSED; + status = PRESSED; input.press(); // Order matters here, because onDown.fire() could cause a state change and destroy this object. onDown.fire(); @@ -542,11 +574,11 @@ class FlxTypedButton extends FlxSprite implements IFlxInput // by remaining in the normal state (until mouse input is re-enabled). if (!FlxG.mouse.enabled) { - status = FlxButton.NORMAL; + status = NORMAL; return; } #end - status = FlxButton.HIGHLIGHT; + status = HIGHLIGHT; // Order matters here, because onOver.fire() could cause a state change and destroy this object. onOver.fire(); } @@ -556,7 +588,7 @@ class FlxTypedButton extends FlxSprite implements IFlxInput */ function onOutHandler():Void { - status = FlxButton.NORMAL; + status = NORMAL; input.release(); // Order matters here, because onOut.fire() could cause a state change and destroy this object. onOut.fire(); @@ -579,9 +611,9 @@ class FlxTypedButton extends FlxSprite implements IFlxInput return Value; } - function set_status(Value:Int):Int + function set_status(value:FlxButtonState):FlxButtonState { - status = Value; + status = value; updateLabelAlpha(); return status; } diff --git a/tests/unit/src/flixel/ui/FlxButtonTest.hx b/tests/unit/src/flixel/ui/FlxButtonTest.hx index b00eb88b30..943c7c261e 100644 --- a/tests/unit/src/flixel/ui/FlxButtonTest.hx +++ b/tests/unit/src/flixel/ui/FlxButtonTest.hx @@ -1,7 +1,8 @@ package flixel.ui; -import openfl.display.BitmapData; import flixel.FlxSprite; +import flixel.ui.FlxButton; +import openfl.display.BitmapData; import massive.munit.Assert; class FlxButtonTest extends FlxTest @@ -45,9 +46,9 @@ class FlxButtonTest extends FlxTest function assertStatusAnimationsExist() { - var normalName:String = button.statusAnimations[FlxButton.NORMAL]; - var highlightName:String = button.statusAnimations[FlxButton.HIGHLIGHT]; - var pressedName:String = button.statusAnimations[FlxButton.PRESSED]; + var normalName:String = button.statusAnimations[NORMAL]; + var highlightName:String = button.statusAnimations[HIGHLIGHT]; + var pressedName:String = button.statusAnimations[PRESSED]; Assert.isNotNull(button.animation.getByName(normalName)); Assert.isNotNull(button.animation.getByName(highlightName)); @@ -74,7 +75,7 @@ class FlxButtonTest extends FlxTest button.setPosition(); step(1); - Assert.areEqual(FlxButton.HIGHLIGHT, button.status); + Assert.areEqual(HIGHLIGHT, button.status); FlxG.state.remove(button); } @@ -87,7 +88,7 @@ class FlxButtonTest extends FlxTest FlxG.state.add(button); step(2); - Assert.areEqual(FlxButton.NORMAL, button.status); + Assert.areEqual(NORMAL, button.status); Assert.areEqual("normal", button.animation.curAnim.name); Assert.areEqual(false, button.animation.finished); step(10);