diff --git a/Features/FlxPieDial/Project.xml b/Features/FlxPieDial/Project.xml
index e8b13cc94..b2e6580a4 100644
--- a/Features/FlxPieDial/Project.xml
+++ b/Features/FlxPieDial/Project.xml
@@ -30,6 +30,7 @@
+
diff --git a/Features/FlxPieDial/assets/images/flixel.png b/Features/FlxPieDial/assets/images/flixel.png
new file mode 100644
index 000000000..cf9836128
Binary files /dev/null and b/Features/FlxPieDial/assets/images/flixel.png differ
diff --git a/Features/FlxPieDial/source/DemoState.hx b/Features/FlxPieDial/source/DemoState.hx
deleted file mode 100644
index 9e8e93701..000000000
--- a/Features/FlxPieDial/source/DemoState.hx
+++ /dev/null
@@ -1,98 +0,0 @@
-package;
-
-import flixel.addons.display.FlxPieDial;
-import flixel.addons.display.FlxPieDial.FlxPieDialShape;
-import flixel.tweens.FlxTween;
-import flixel.FlxState;
-import flixel.util.FlxColor;
-
-class DemoState extends FlxState
-{
- override public function create():Void
- {
- super.create();
-
- var i:Int = 0;
- var x:Float = 10;
- var y:Float = 10;
- var shape:FlxPieDialShape = CIRCLE;
- var clockwise:Bool = false;
- var innerRadius:Int = 0;
-
- var createDial = function()
- {
- var colors = [FlxColor.RED, FlxColor.BLUE, FlxColor.LIME, FlxColor.WHITE];
- var amounts = [0.25, 0.50, 0.75, 1.00];
-
- var dial = new FlxPieDial(x, y, 25, colors[i], 72, shape, clockwise, innerRadius);
- dial.amount = amounts[i];
- add(dial);
- x += 100;
-
- i++;
- if (i > 3)
- i = 0;
- return dial;
- }
-
- var createFour = function()
- {
- for (_ in 0...4)
- createDial();
- }
-
- var nextLine = function()
- {
- x = 10;
- y += 100;
- }
-
- // Circular pie dials
- shape = CIRCLE;
- clockwise = true;
- createFour();
-
- clockwise = false;
- createFour();
-
- nextLine();
-
- // Square-ular pie dials
- shape = SQUARE;
- clockwise = true;
- createFour();
-
- clockwise = false;
- createFour();
-
- nextLine();
-
- // Donut-ular pie dials
- shape = CIRCLE;
- clockwise = true;
- innerRadius = 12;
- createFour();
-
- clockwise = false;
- createFour();
-
- nextLine();
-
- // Square donut-ular pie dials
- shape = SQUARE;
- clockwise = true;
- createFour();
-
- clockwise = false;
- createFour();
-
- nextLine();
-
- // Tweened pie dial
- var pieDial = new FlxPieDial(25, y, 25, FlxColor.LIME, 36, FlxPieDialShape.SQUARE, false, 10);
- pieDial.amount = 0.0;
- add(pieDial);
-
- FlxTween.tween(pieDial, {amount: 1.0}, 2.0, {type: PINGPONG});
- }
-}
diff --git a/Features/FlxPieDial/source/GaugeEditorState.hx b/Features/FlxPieDial/source/GaugeEditorState.hx
new file mode 100644
index 000000000..9bcecb247
--- /dev/null
+++ b/Features/FlxPieDial/source/GaugeEditorState.hx
@@ -0,0 +1,285 @@
+package;
+
+import flixel.FlxG;
+import flixel.FlxSprite;
+import flixel.addons.display.FlxRadialGauge;
+import flixel.input.mouse.FlxMouseEvent;
+import flixel.math.FlxPoint;
+import flixel.tweens.FlxTween;
+import flixel.ui.FlxButton;
+import flixel.util.FlxColor;
+import flixel.util.FlxSignal;
+
+using flixel.addons.display.FlxPieDial.FlxPieDialUtils;
+/**
+ * Demo for the soon to be added feature, FlxRadialGauge. Will replace FlxPieDial and this demo
+ */
+class GaugeEditorState extends flixel.FlxState
+{
+ final circleGauge:ShapeGaugeEditor;
+ final squareGauge:DoubleGauge;
+ final imageGauge:DoubleGauge;
+
+ public function new ()
+ {
+ super();
+
+ circleGauge = new ShapeGaugeEditor(FlxG.width * 0.5, FlxG.height * 0.5, CIRCLE, 100, 75, -225, 45);
+ squareGauge = new DoubleGauge();
+ squareGauge.makeShapeGraphic(SQUARE, 100, 75);
+ squareGauge.color = FlxColor.LIME;
+ squareGauge.back.color = FlxColor.BLACK;
+ circleGauge.onRedraw.add(function ()
+ {
+ squareGauge.makeShapeGraphic(SQUARE, Math.round(circleGauge.radius), Math.round(circleGauge.innerRadius));
+ });
+
+ drawLogo();
+ imageGauge = new DoubleGauge(FlxG.width * 0.5, FlxG.height * 0.5, "logo-200x200");
+ imageGauge.x -= imageGauge.width;
+ imageGauge.y -= imageGauge.height * 0.5;
+ imageGauge.back.color = 0xFF909090;
+ }
+
+ function drawLogo()
+ {
+ final image = FlxG.bitmap.create(200, 200, 0x0, false, "logo-200x200");
+ final logo = new openfl.display.Shape();
+ flixel.system.FlxAssets.drawLogo(logo.graphics);
+ final mat = new flixel.math.FlxMatrix();
+ mat.scale(image.width / logo.width, image.height / logo.height);
+ image.bitmap.draw(logo, mat);
+ }
+
+ override function create()
+ {
+ super.create();
+ bgColor = FlxColor.GRAY;
+
+ add(circleGauge);
+ add(squareGauge);
+ add(imageGauge);
+ }
+
+ override function draw()
+ {
+ squareGauge.amount = imageGauge.amount = circleGauge.getAmount();
+ squareGauge.start = imageGauge.start = circleGauge.getStart();
+ squareGauge.end = imageGauge.end = circleGauge.getEnd();
+ final scale = 2 * circleGauge.radius / imageGauge.frameWidth;
+ imageGauge.scale.set(scale, scale);
+ imageGauge.updateHitbox();
+
+ squareGauge.x = circleGauge.x - circleGauge.radius * 3 - 10;
+ imageGauge.x = circleGauge.x + circleGauge.radius + 10;
+ imageGauge.y = squareGauge.y = circleGauge.y - circleGauge.radius;
+
+ super.draw();
+ }
+}
+
+class DoubleGauge extends FlxRadialGauge
+{
+ public final back:FlxRadialGauge;
+ public function new (x = 0.0, y = 0.0, ?graphic)
+ {
+ back = new FlxRadialGauge(x, y, graphic);
+
+ super(x, y, graphic);
+ }
+
+ override function draw()
+ {
+ back.x = x;
+ back.y = y;
+ back.frames = frames;
+ back.start = start;
+ back.end = end;
+ back.scale.copyFrom(scale);
+ back.updateHitbox();
+ back.draw();
+ super.draw();
+ }
+}
+
+
+/**
+ * A visual editor for a FlxRadialGauge, has draggable objects that determine the gauge's properties
+ */
+class ShapeGaugeEditor extends flixel.group.FlxSpriteGroup
+{
+ public var shape:FlxRadialGaugeShape;
+ public var radius = 0.0;
+ public var innerRadius = 0.0;
+ public var onRedraw = new FlxSignal();
+
+ final gauge:DoubleGauge;
+ final radiusHandle:DragHandle;
+ final innerRadiusHandle:DragHandle;
+
+ public function new (x = 0.0, y = 0.0, shape = CIRCLE, radius:Int, innerRadius:Int, start:Float, end:Float)
+ {
+ this.shape = shape;
+ this.radius = radius;
+ this.innerRadius = innerRadius;
+ super(0, 0);
+
+ add(gauge = new DoubleGauge(-radius, -radius));
+ gauge.back.color = FlxColor.BLACK;
+ gauge.color = FlxColor.LIME;
+
+ // Helper point
+ final pos = FlxPoint.get();
+ pos.setPolarDegrees(radius, start);
+ add(radiusHandle = new DragHandle(pos.x, pos.y, onRadiusChange));
+ pos.setPolarDegrees(innerRadius, end);
+ add(innerRadiusHandle = new DragHandle(pos.x, pos.y, onInnerRadiusChange));
+
+ redraw();
+ gauge.setOrientation(start, end);
+
+
+ FlxTween.num(-0.1, 1.1, 2.0, {type: PINGPONG}, function (n)
+ {
+ final n = Math.min(1.0, Math.max(0.0, n));
+ gauge.amount = n;
+ });
+
+ // Setting position after everything is added makes it easier to use relative positioning
+ this.x = x;
+ this.y = y;
+ pos.put();
+
+ #if debug
+ FlxG.watch.addFunction("radius", ()->radius);
+ FlxG.watch.addFunction("innerRadius", ()->innerRadius);
+ FlxG.watch.addFunction("start", ()->gauge.start);
+ FlxG.watch.addFunction("end", ()->gauge.end);
+ FlxG.watch.addFunction("amount", ()->gauge.amount);
+ #end
+ }
+
+ inline function redraw()
+ {
+ gauge.makeShapeGraphic(shape, Math.round(radius), Math.round(innerRadius));
+ onRedraw.dispatch();
+ }
+
+ function onRadiusChange()
+ {
+ final dis = FlxPoint.get(radiusHandle.x - x, radiusHandle.y - y);
+ radius = dis.length;
+ redraw();
+ gauge.x = x - radius;
+ gauge.y = y - radius;
+ gauge.start = validateAngle(dis.degrees);
+ dis.put();
+ }
+
+ function onInnerRadiusChange()
+ {
+ final dis = FlxPoint.get(innerRadiusHandle.x - x, innerRadiusHandle.y - y);
+ innerRadius = dis.length;
+ redraw();
+ gauge.end = validateAngle(dis.degrees);
+ dis.put();
+ }
+
+ /** Convert angles so that the wrap point is directly down */
+ inline function validateAngle(degrees:Float):Float
+ {
+ return ((degrees + 270) % 360) - 270;
+ }
+
+ inline public function getStart()
+ {
+ return gauge.start;
+ }
+
+ inline public function getEnd()
+ {
+ return gauge.end;
+ }
+
+ inline public function getAmount()
+ {
+ return gauge.amount;
+ }
+}
+
+class DragHandle extends FlxSprite
+{
+ static inline final RADIUS = 10;
+ static inline final OUTLINE = 2;
+ static inline final KEY = 'drag-handle-$RADIUS';
+ static inline final OVER_COLOR = FlxColor.WHITE;
+ static inline final OUT_COLOR = 0xFFeeeeee;
+
+ static function getGraphic()
+ {
+ // Use existing graphic, if it exists
+ final graphic = FlxG.bitmap.get(KEY);
+ if (graphic != null)
+ return graphic;
+
+ // Generate graphic
+ final graphic = FlxG.bitmap.create(RADIUS * 2, RADIUS * 2, 0x0, false, KEY);
+ graphic.bitmap.drawCircle(RADIUS, FlxColor.BLACK);
+ graphic.bitmap.drawCircle(RADIUS - OUTLINE, FlxColor.WHITE);
+ return graphic;
+ }
+
+ /** Called whenever the handle moves */
+ public var onChange:()->Void;
+
+ /** Whether this is currently being dragged */
+ public var dragging(default, null):Bool = false;
+
+ public function new (x = 0.0, y = 0.0, onChange:()->Void)
+ {
+ this.onChange = onChange;
+ super(x, y, getGraphic());
+ offset.set(RADIUS, RADIUS);
+ color = OUT_COLOR;
+
+ /*
+ * Track mouse dragging via FlxMouseEvent, as it prevents the user from
+ * being able to select more than one, with a single click
+ */
+ FlxMouseEvent.add(this,
+ (_)->dragging = true, // onMouseDown
+ null, // onMouseUp: handled via update
+ (_)->color = OVER_COLOR, // onMouseOver
+ (_)->color = OUT_COLOR, // onMouseOver
+ false, // moueChildren: Whether other objects overlapped by this will still receive mouse events
+ true, // mouseEnabled: Whether this object will receive mouse events
+ true // pixelPerfect: Whether to ignore the graphic's alpha pixels
+ );
+
+ #if debug
+ ignoreDrawDebug = true;
+ #end
+ }
+
+ function moveToMouse()
+ {
+ x = FlxG.mouse.x;
+ y = FlxG.mouse.y;
+ onChange();
+ }
+
+ override function update(elapsed:Float)
+ {
+ super.update(elapsed);
+
+ if (dragging)
+ {
+ // Stop dragging
+ if (FlxG.mouse.justReleased)
+ dragging = false;
+
+ if (FlxG.mouse.justMoved)
+ moveToMouse();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Features/FlxPieDial/source/Main.hx b/Features/FlxPieDial/source/Main.hx
index ef266f628..d21ac99c2 100644
--- a/Features/FlxPieDial/source/Main.hx
+++ b/Features/FlxPieDial/source/Main.hx
@@ -8,6 +8,10 @@ class Main extends Sprite
public function new()
{
super();
- addChild(new FlxGame(800, 500, DemoState));
+ #if flash
+ addChild(new FlxGame(800, 500, PieDialState.new));
+ #else
+ addChild(new FlxGame(800, 500, GaugeEditorState.new));
+ #end
}
}
diff --git a/Features/FlxPieDial/source/PieDialState.hx b/Features/FlxPieDial/source/PieDialState.hx
new file mode 100644
index 000000000..00ae7060d
--- /dev/null
+++ b/Features/FlxPieDial/source/PieDialState.hx
@@ -0,0 +1,83 @@
+package;
+
+import flixel.FlxG;
+import flixel.FlxState;
+import flixel.addons.display.FlxPieDial;
+import flixel.group.FlxGroup;
+import flixel.tweens.FlxTween;
+import flixel.util.FlxColor;
+
+class PieDialState extends FlxState
+{
+ override public function create():Void
+ {
+ super.create();
+ FlxG.cameras.bgColor = FlxColor.GRAY;
+
+ final colors = [FlxColor.RED, FlxColor.BLUE, FlxColor.LIME, FlxColor.WHITE];
+ final spacingX = 100;
+ final spacingY = 100;
+
+ inline function createDial(x, y, color, shape = CIRCLE, clockwise = true, innerRadius = 0, quarters:Int)
+ {
+ final dial = new FlxPieDial(x, y, 25, color, 4, shape, clockwise, innerRadius);
+ dial.amount = quarters * .25;
+ add(dial);
+ return dial;
+ }
+
+ inline function createFour(x:Float, y, shape = CIRCLE, clockwise = true, innerRadius = 0)
+ {
+ for (i in 0...4)
+ createDial(x + i * spacingX, y, colors[i], shape, clockwise, innerRadius, i+1);
+ }
+
+ var y = 10;
+
+ inline function createEight(shape = CIRCLE, innerRadius = 0)
+ {
+ createFour(10, y, shape, true, innerRadius);
+ createFour(spacingX * 4 + 10, y, shape, false, innerRadius);
+ y += spacingY;
+ }
+
+ createEight(CIRCLE);
+ createEight(SQUARE);
+ createEight(CIRCLE, 12);
+ createEight(SQUARE, 12);
+
+ var x = 10;
+ final tweened = new FlxTypedGroup();
+ inline function createTweened(color, shape, innerRadius = 0, clockwise = true)
+ {
+ final dial = new FlxPieDial(x, y, 25, color, 36, shape, clockwise, innerRadius);
+ tweened.add(dial);
+ x += spacingX;
+
+ return dial;
+ }
+ add(tweened);
+
+ // clockwise
+ createTweened(colors[0], CIRCLE, 0 , true);
+ createTweened(colors[1], CIRCLE, 10, true);
+ createTweened(colors[2], SQUARE, 0 , true);
+ createTweened(colors[3], SQUARE, 10, true);
+ // counter-clockwise
+ createTweened(colors[0], CIRCLE, 0 , false);
+ createTweened(colors[1], CIRCLE, 10, false);
+ createTweened(colors[2], SQUARE, 0 , false);
+ createTweened(colors[3], SQUARE, 10, false);
+
+ FlxTween.num(-0.1, 1.1, 2.0, {type: PINGPONG}, function (n)
+ {
+ final n = Math.min(1.0, Math.max(0.0, n));
+ for (dial in tweened)
+ dial.amount = n;
+
+ #if debug
+ FlxG.watch.addQuick("amount", n);
+ #end
+ });
+ }
+}