I’ve been working away on AScalpel for a while now, polishing it and adding some new features to it. It’s settled enough now that I can sit down and write a real step-by-step guide to using it.

There is also a sample application included with the AScalpel library which is already integrated. Compile com.andrewtraviss.ascalpel.sample::BouncingBallSample.as as an application to view it.

Setup

Downloads

  1. Latest AScalpel build from GitHub
  2. Latest Minimal Components from GitHub

Project Setup

Start by creating a new Actionscript 3.0 project and copying the AScalpel and Minimal Component source files into the source directory. Once that’s done, you need to do two things to get AScalpel up and running. By default, AScalpel isn’t configured to handle most situations. The AScalpel package includes a helper class to configure it for common cases. Once you call StandardBit101Components.install, the system is ready to handle basic data types using the Minimal Components.

In order to actually see the editors you need to add AScalpel to the display list. AScalpel is a singleton, so you’ll need to access its display through AScalpel.instance.display. Be sure to keep this object on top of your game.

Your Main constructor should look something like this now.

[SWF(width="600", height="450")]
public class Main extends Sprite
{
	public function Main()
	{
		StandardBit101Editors.install();
		addChild(AScalpel.instance.display);
	}
}

Simple Integration

Opening the Object Editor

Before we get started, we’ll need an object to play with. For the sake of example, I’m going to use a simple bouncing ball demo. Here is our BouncingBall class without any metadata.

package com.andrewtraviss.ascalpel.sample
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.utils.getQualifiedClassName;

	public class BouncingBall
	{
		public function BouncingBall()
		{
			_sprite = new Sprite();
			redraw();
		}

		public function redraw():void
		{
			_sprite.graphics.clear();
			_sprite.graphics.beginFill(_color);
			_sprite.graphics.drawCircle(x,y,_radius);
			_sprite.graphics.endFill();
		}

		public function get radius():Number
		{
			return _radius;
		}
		public function set radius(in_value:Number):void
		{
			_radius = in_value;
			redraw();
		}

		public function get color():uint
		{
			return _color;
		}
		public function set color(in_value:uint):void
		{
			_color = in_value;
			redraw();
		}

		public function get sprite():DisplayObject
		{
			return _sprite;
		}

		public var x:Number = 0;
		public var y:Number = 0;
		public var xVelocity:Number = 0;
		public var yVelocity:Number = 0;
		public var name:String;

		private var _radius:Number = 1;
		private var _color:uint = 0x000000;
		private var _sprite:Sprite;
	}
}

Once we have our object class, all we need to do is create an instance of it, and use AScalpel to open it. Our updated constructor looks like this.

[SWF(width="600", height="450")]
public class Main extends Sprite
{
	public function Main()
	{
		StandardBit101Editors.install();
		var ball:BouncingBall = new BouncingBall();
		addChild(ball.sprite);
		addChild(AScalpel.instance.display);
		AScalpel.instance.open(ball);
	}
}

If you run this simple example, you should see a tiny editor window with nothing in it.

There’s nothing in it because we haven’t  told AScalpel anything about the BouncingBall class yet.

A Little Bit About Metadata

If you haven’t worked with metadata before, it’s fairly simple. All metadata is enclosed in square brackets, as in [Editable]. If there are parameters being passed with metadata, they are placed in parentheses inside the square brackets. For example, [Editable(explicitCommit=”true”)]. Metadata is available at runtime through the describeType method. This spits out an XML that contains every detail about the object you apply it to. AScalpel uses this XML to create its editor windows.

Adding Basic AScalpel Metadata

The easiest way to integrate with AScalpel is to simply slap the [Editable] tag on the line above each property you want to edit. For example:

[Editable]
public var x:Number = 0;

In our example, I chose to make all of the public variables and getter/setters editable except for the name property. If you do that and run the example again, you’ll see something that looks much more useful than the last time.

You can now edit all of these properties. There’s a problem, though. As you type numbers into the fields, the object reacts to the changes instantly. This is probably not what you want in all cases. When you type in 400 for x, the object shouldn’t move to 4, then 40, then 400. AScalpel has a solution for this problem. For the position and velocity properties, we’ll use the explicitCommit option.

[Editable(explicitCommit="true")]
public var x:Number = 0;

And now that section of the editor looks like this. When a property is marked for explicit commit, the editor creates a button for that property which applies the current value when you click on it.

Advanced Integration

Specifying Editors

Continuing our above example, there are a few things that could be improved. The colour field accepts a uint value instead of a proper colour hex value, which is cumbersome to work with. To solve this problem, we can tell AScalpel to use a different control to edit the colour field. By using editorClass we can use any custom class as an editor. In this case, the Minimal Components Color Chooser control is enough, and is part of the standard installation. So we can just change the Editable tag for the color property like so.

[Editable(editorClass="com.bit101.components.ColorChooser")]
public function get color():uint
{
	return _color;
}
public function set color(in_value:uint):void
{
	_color = in_value;
	redraw();
}

Which gives us this.

Editor Properties

Perhaps we want to limit the radius of the ball within a particular range. The NumericStepper component supports minimum and maximum, so we will use that. We can set the minimum and maximum, and the step size on the NumericStepper just by adding those properties into the Editable tag. If AScalpel doesn’t recognize a metadata property, it will check for that property on the editor class and try to apply the value to it.

[Editable(editorClass="com.bit101.components.NumericStepper", minimum="1", maximum="30", step="0.1")]
public function get radius():Number
{
	return _radius;
}
public function set radius(in_value:Number):void
{
	_radius = in_value;
	redraw();
}


I will post an Advanced User Guide later on to describe how to create custom editors and change the default behaviour of AScalpel.