Requirements

Prerequisite knowledge

Familiarity with ActionScript programming using the Flex SDK or Flash Builder.

User level

Advanced

Additional required other products

  • Photoshop Touch SDK (Download)
  • as3corelib (Download)
  • as3crypto (Download)
  • StructuredLogTestingSDK (for logging) (Download)
  • Optional: An Android (or iOS) device for on-device testing

Adobe has recently created the Photoshop Touch SDK, which allows virtually any device to connect to and control Photoshop using any Internet or WiFi connection. For the first time, you can interface with Photoshop directly (see Figure 1), and use this to create mobile, desktop, or web applications that are tailored to the needs of creative professionals or casual-creative users.

Adobe nav for the  iPad

I wrote this tutorial to familiarize you with the Photoshop Touch SDK, and show you how to create a mobile application that communicates with Photoshop. I'll be using APIs in the Photoshop Touch SDK that I wrote with the help of my colleague, Renaun Erickson. This SWC library, called the Photoshop Touch SDK for AS3, allows you to write very simple ActionScript 3 code in any Flash, AIR, or Flex application, and saves you from doing tedious socket-level work.

As you'll discover, these AS3 APIs are flexible and easy to use, and will allow you to leverage the portability of Flash, versatility of Flex, and power of ActionScript 3 to help you realize your vision for designing creative apps.

In this tutorial you'll learn the APIs by completing a series of common tasks. I will step you through: connecting to Photoshop; choosing the currently selected tool; monitoring for color changes; and changing the brush size.

By the end of this article you'll be able to:

  • Create a project using the Photoshop Touch SDK
  • Use the Photoshop Touch SDK in a Flex mobile application
  • Select Photoshop tools from your app
  • Monitor color changes in Photoshop, and display the color in your Flex mobile application
  • Send custom messages to Photoshop

Before continuing, however, you need to set up your build environment: Be sure you have Flash Builder 4.5 or 4.0 installed (or set up command line tools), make sure you have the Flex 4.5 SDK, and download the PhotoshopTouchSDK.

Setup: Create your project

Before you can start coding, you need to create a project and link to the correct libraries.

Step 1: Create a new Project in Flash Builder

The first step is to create a new Flex Mobile Project. Although you're using Flex, the Flash runtime runs on a variety of platforms and devices, so you could just as easily create an AS3 or AIR project. For this article, though, you'll create a mobile application using Flex.

  1. Open Flash Builder and choose File > New > Flex Mobile Project.
  2. Enter a project name and choose a location. Click next.
  3. Make sure Google Android is your target platform, and select "View-Based application."
  4. Name your initial view LoginView. It's here that you'll write code to handle the connection to Photoshop.
  5. Click finish to complete the new Flex mobile project.

Step 2: Link to the Photoshop Touch SDK library

The Photoshop Touch SDK includes a file called PhotoshopTouchSDK.swc. This is a pre-compiled library that you can integrate into any Flash or Flex application; it provides APIs to connect to and control Photoshop. This part of the library is open source, and you are free to modify and learn from the code (in accordance with the accompanying EULA or license agreement).

  1. Locate the PhotoshopTouchSDK.swc file in the extracted files.

Note: After downloading and extracting the Photoshop Touch SDK from the Adobe site, you can find the PhotoshopTouchSDK.swc file in the following relative location: <some directory>\samples\air\photoshoptouchsdk\bin\PhotoshopTouchSDK.swc.

  1. Copy PhotoshopTouchSDK.swc and paste it in the libs folder inside your project directory. You can do this from within Flash Builder or by using Explorer/Finder/bash/etc.

Step 3: Link to the other required libraries

The file \samples\air\photoshoptouchsdk\README.txt indicates the complete list of libraries that are necessary to use the APIs. At the time of writing, there are three additional libraries you have to download and include:

Take these three SWC files and drop them into the "libs" directory in your project, as you did with the PhotoshopTouchSDK SWC.

Note: Extract the as3corelib ZIP file and open the lib folder to get the as3corelib.swc file.

All the required libraries in your libs folder.

You're now ready to add code to your project. The next steps will walk you through authenticating with Photoshop, initializing encryption, and handling communication errors.

Connecting to Photoshop

The PhotoshopTouchSDK includes a class called PhotoshopConnection, which provides functions and dispatches events for managing the connection state with Photoshop. You'll need to call functions such as connect(), initEncryption(), and (to save time for future connections) initEncryptionFromKey(). You'll need to listen for PhotoshopEvents such as PhotoshopEvent.CONNECTED, ENCRYPTION_SUCCESS, and ERROR.

Connecting to Photoshop using this class is a three-step process, barring any communication or password problems:

  1. Create a new PhotoshopConnection and listen for events.
  2. Call connect() on your instance of the PhotoshopConnection.
  3. After a successful connection, initialize encryption using either initEncryption() or (if you've saved the user's key with getKey()), initEncryptionFromKey().

After these steps have been completed, you may send and receive data with Photoshop. As you code these features into the mobile application, you'll create data structures that will allow you to easily add functionality later in this tutorial.

Step 1: Create a singleton Model, to establish a MVC design

Your application needs to create a PhotoshopConnection, but you want to store it in a location where it can be conveniently accessed by various parts of your UI (the View in the Model-View-Controller design pattern). Thus, you'll create a Model in which to store object references, constants, and variables.

  1. Right-click your project in Flash Builder, and choose New ActionScript Class.
  2. Enter the string model as the package.
  3. Name the class Model.
  4. Click Finish.

You now need to add a static variable to this class, a function called getInstance() which returns that variable and, finally, a Bindable, public variable that will store your PhotoshopConnection. Enter the following code inside of the public class Model { ... }:

private static var _inst:Model; [Bindable] public var photoshopConn:PhotoshopConnection; public function Model() { } public static function getInstance():Model { if ( !_inst ) { _inst = new Model(); } return _inst; }

You can now reference the variable photoshopConn from either AS3 or Flex code, simply by calling Model.getInstance() and referencing photoshopConn:

Model.getInstance().photoshopConn.

Step 2: Instantiate the PhotoshopConnection and listen for events

You'll instantiate the PhotoshopConnection the first time the user attempts to connect, but it would be a good idea to create initialization code in your own applications, to handle things like reading the hostname and password from disk, managing the user's key and preferences, and so on.

Open your views/LoginView.mxml file. You'll allow the user to connect to Photoshop using a Spark Button, and they'll have to enter the hostname and password using s:TextInput components. Type the following into the DisplayList on your LoginView class:

<fx:Script> <![CDATA[ protected function loginButton_clickHandler(event:MouseEvent):void { // TODO Auto-generated method stub } ]]> </fx:Script> <s:VGroup width="100%" height="100%"> <s:Label text="Hostname"/> <s:TextInput id="hostname" text="192.168.1.10"/> <s:Label text="Password"/> <s:TextInput id="password" displayAsPassword="true" text="photoshop"/> <s:Button id="loginButton" label="Login" click="loginButton_clickHandler(event)"/> </s:VGroup>

You've created two TextInput components and a Button, as well as an fx:Script tag that will contain some click-handler logic. When this button is pressed, you want to create a new PhotoshopConnection, and listen for events. Thus, type the following, so that your fx:Script tag looks like this:

<fx:Script> <![CDATA[ import com.adobe.photoshop.connection.PhotoshopConnection; import model.Model; protected function loginButton_clickHandler(event:MouseEvent):void { if ( !Model.getInstance().photoshopConn ) { createNewConnection(); } } private function createNewConnection():void { var m:Model = Model.getInstance(); m.photoshopConn = new PhotoshopConnection(); } ]]> </fx:Script>

You've created a function called createNewConnection(), which is called if the photoshopConn variable is null. You now have to attach event listeners to this new PhotoshopConnection. Add the following to the bottom of your createNewConnection function:

m.photoshopConn.addEventListener(PhotoshopEvent.CONNECTED,onConnected); m.photoshopConn.addEventListener(PhotoshopEvent.ENCRYPTION_SUCCESS,onEncrypted); m.photoshopConn.addEventListener(PhotoshopEvent.ERROR,onError);

Of course, you now have to create the functions onConnected, onEncrypted, and onError, in which you'll put the application logic for handling these eventualities.

private function onConnected(pe:PhotoshopEvent):void { trace("Connected established."); } private function onEncrypted(pe:PhotoshopEvent):void { trace("Encryption was successful"); } private function onError(pe:PhotoshopEvent):void { trace("There was an error while connecting!"); }

With these functions created, you're ready to try and connect to Photoshop. It's always a good idea to remove event listeners when you're not using them, however, so create a function called cleanUp(), and remove each of those three event listeners from the photoshopConn instance. You'll call this function once you're ready to switch Views in the application (after successfully encrypting the connection).

Step 3: Call connect()

As you'll see, connecting to Photoshop is very simple. In your click handler function for the Login button, add the following code to the bottom of the function:

Model.getInstance().photoshopConn.connect(this.hostname.text);

As the asdocs for the connect() function note:

Opens a Photoshop data connection to Photoshop. You may call this function before you call initEncryption(), but you will have to initialize the encryption before you can successfully communicate with Photoshop.

Parameters

serverName:String - IP address or resolvable hostname of the server

serverPort:int (default = 49494) - Port to connect to. Default is 49494

After this function has been called, the API will attempt to connect. It will dispatch the necessary events during this process.

Step 4: Initialize encryption, and move on to the next View.

As the docs indicate, a successful connection will cause PhotoshopConnection to dispatch a PhotoshopEvent.CONNECTED event. Since you're listening for this event, your function onConnected will be called. It's here that you'll make the call to initialize encryption. Thus, make your onConnected() function look like the following:

private function onConnected(pe:PhotoshopEvent):void { trace("Connected established. Encrypting connection. This will take a few seconds..."); Model.getInstance().photoshopConn.initEncryption(this.password.text); }

If this is successful, your code will enter the onEncrypted() event handler. At that point, you're ready to send data to and from Photoshop. To prepare for this step:

  1. Right-click your project and select New MXML Component.
  2. Put it in the package "views," and name it HomeView.
  3. Click Finish.

Now, you just have to push a HomeView onto the ViewNavigator:

private function onEncrypted(pe:PhotoshopEvent):void { trace("Encryption was successful. Cleaning up event listeners."); this.cleanUp(); trace("Proceeding to the 'Home' View."); this.navigator.pushView(HomeView); }

You've also cleaned up the event listeners, which you should do wherever possible, to prevent memory leaks. You should now test your project. In the next section, I'll show you how to send some simple commands to Photoshop.

If you need help with the previous steps, you may find it useful to view the sample project as it exists at this point in the tutorial. Download the sample code and open the project in the code_step1 folder (or import the FXP to Flash Builder 4.5).

Sending commands to Photoshop

At this point in your application, you've used the Photoshop Touch SDK to establish an encrypted connection to Photoshop. You're ready to send and receive data. With a single function call, you can push raw bytes to Photoshop—and you could create your own datagram format that encapsulates these bytes. The Photoshop Touch SDK includes ActionScript APIs to do this for you, however, and provides functions which minimize the amount of low-level code you have to write.

The first of these classes is the MessageDispatcher. As the asdocs state:

The MessageDispatcher is an abstraction layer on top of the PhotoshopConnection, which makes it easy to send properly formatted messages to Photoshop. You can either call some of the helper functions that will create and dispatch the messages for you (createNewDocument, requestThumbnail, etc.), or create your own IMessage and call sendMessage().

Since you're just beginning, you will indeed use the simplest of these method calls. You'll create an s:Button in your HomeView that tells Photoshop to create a new document. Photoshop will respond with an id referencing the document.

Step 1: Create a MessageDispatcher instance

Before you can use the MessageDispatcher, you have to create a new instance of it, and give it a reference to our existing PhotoshopConnection (this allows the MessageDispatcher to use the connection that you initialized in the previous section). You'll store this instance in the Model, just like you do with the photoshopConn variable. Thus, in your Model.mxml file, add the following:

[Bindable] public var messageDisp:MessageDispatcher;

The Bindable property allows you to use this variable in Flex or attach your own ChangeWatchers, should the need arise.

You now have to instantiate this variable. Open your HomeView class and generate an event handler for the initialize event. Type the following:

protected function view1_initializeHandler(event:FlexEvent):void { var m:Model = Model.getInstance(); if ( !m.messageDisp ) { m.messageDisp = new MessageDispatcher(m.photoshopConn); } }

As you can see, this code will only create a MessageDispatcher should it not already exist, and it'll pass a reference to the existing PhotoshopConnection. You'll want to handle initialization logic like this in a dedicated initialization controller, should you be creating a more robust application. You're now ready to use this object.

Step 2: Listen for Photoshop's response(s)

You could send the command at this point, but, should an error occur, your application would never hear about it. Thus, it's necessary to attach some event listeners to the PhotoshopConnection. Three events are particularly useful for handling message-related communication:

  • ErrorEvent: Dispatched when there's been an error in either data transfer, encryption, or connection management.
  • ErrorMessageReceivedEvent: Dispatched when an error message is received from Photoshop.
  • MessageReceivedEvent: Dispatched when a message is received from Photoshop.

There are number of other useful events, such as MessageSentEvent, ProgressEvent, and ImageReceivedEvent, but you won't be using them for this example.

Inside of your HomeView initialization handler, add the following, to attach event listeners to the PhotoshopConnection:

m.photoshopConn.addEventListener(PhotoshopEvent.ERROR,onError); m.photoshopConn.addEventListener(PhotoshopMessageEvent.MESSAGE_RECEIVED,onMessage); m.photoshopConn.addEventListener(PhotoshopMessageEvent.ERROR_MESSAGE_RECEIVED,onErrorMessage);

Of course, you now have to create three functions: onError, onMessage, and onErrorMessage:

private function onError(pe:PhotoshopEvent):void { trace("Error while sending a message!"); } private function onMessage(pme:PhotoshopMessageEvent):void { trace("We received a message from Photoshop"); } private function onErrorMessage(pme:PhotoshopMessageEvent):void { trace("We received an error message from Photoshop"); }

As before, it's a good idea to clean up event listeners that you no longer need. So create a cleanUp() function that calls removeEventListener for those three events.

Step 3: Send a message to Photoshop

You're finally ready to make Photoshop do something! We'll ask it to do something simple: create a new document. If this is successful, Photoshop will send a message in response that contains the id of the created document.

First, use MXML to create a Spark Button inside of the DisplayList:

<s:Button id="createNewDocument" label="Create a New Document" click="createNewDocument_clickHandler(event)"/>

Inside of the click handler for this Button, you'll tell the MessageDispatcher to dispatch a Message to Photoshop.

Model.getInstance().messageDisp.createNewDocument();

Pay particular attention to the default parameters in that function call. According to the ASDocs:

Dispatches a message instructing Photoshop to create a new document with the specified parameters.

Parameters

transactionID:int (default = -1) - You can override the default value if you wish to send the message with a custom transactionID. If you leave it as -1, the message dispatcher will keep track of transactionIDs for you. It's recommended that you don't mix these two systems, as it might lead to conflicts and unpredictable behavior. width:int (default = 640) - The width of the document to create, in pixels height:int (default = 480) - The height of the document to create, in pixels ppi:int (default = 72) - The density of the document to create, in pixels per inch

Since you're creating a relatively simply application, you don't need the added flexibility that comes with managing your own transaction IDs. You've also accepted the default values for the width, height, and PPI of the document that's to be created.

You should run your application. Once you press the button, you should see the appropriate trace statements, and Photoshop will create the document. In my case, Photoshop responded with a TextMessage. By inspecting the pme.message.message field, I was able to see that Photoshop responded with "[Document Untitled-1]"—the ID of the document.

To finish this step, you should add an event listener for the "removing" event to the View; inside of the handler, call this.cleanUp() to remove the event listeners that you no longer need.

As with the previous task, you may find it helpful to view the sample project as it exists at this point in the tutorial. Download the sample code and open the project in the code_step2 folder (or import the FXP to Flash Builder 4.5).

Managing subscriptions

At this point you should be quite adept at sending and receiving prepackaged messages to and from Photoshop; indeed, these skills will allow you to create an application not unlike Adobe's own Nav iOS app, which gives you a customizable toolbox for quickly changing the currently selected tool. You can continue on from this point, however, by managing and listening for subscriptions. Subscriptions are an abstraction layer provided by the Photoshop Touch SDK ActionScript 3 API, which allows your application to be informed about things like color changes, view changes, preference changes, or tool changes. All of these changes are initialized by the Photoshop user, and your application merely waits for their occurrence.

For example, from the ASDocs:

BACKGROUND_COLOR_CHANGED_EVENT:String ... The background color was changed in Photoshop DOCUMENT_CHANGED_EVENT:String ... A document was changed in Photoshop FOREGROUND_COLOR_CHANGED_EVENT:String ... The foreground color was changed in Photoshop TOOL_CHANGED_EVENT:String ... The user changed the currently selected tool in Photoshop

In this section you're going to subscribe for foreground color changes and display the color that Photoshop sends you.

Step 1: Create a SubscriptionManager instance

A SubscriptionManager, as the name suggests, allows your code to easily manage subscription-related events. It will handle all the underlying communication for you, such that you only have to give it a reference to your existing PhotoshopConnection, and then call addEventListener (or removeEventListener). You may listen for any SubscriptionEvent, and the SubscriptionManager will inform Photoshop that you wish to receive updates about related user events.

The pattern should be familiar by now: you begin by adding a SubscriptionManager variable to the Model:

[Bindable] public var subscriptionManager:SubscriptionManager;

Inside of your home View, add the following code to the initialization handler, which creates a new SubscriptionManager:

m.subscriptionManager = new SubscriptionManager(m.photoshopConn);

Step 2: Create a Button and a Rect

You now need to create two components: A new s:Button, which will attach event listeners to the SubscriptionManager, and a Rect, which will display the color returned from Photoshop. Make the new Button a sibling of the createNewDocument button you created earlier, and make both of them children of a new VGroup. Your MXML should look something like this:

<s:VGroup width="100%" height="100%"> <s:Button id="createNewDocument" label="Create a New Document" click="createNewDocument_clickHandler(event)"/> <s:Button id="subscribeForegroundColor" label="Subscribe to Foreground Color Changes" click="subscribeForegroundColor_clickHandler(event)"/> </s:VGroup>

With the button created, you will now add another sibling to the VGroup: a s:Rect with a Fill, the color of which will change as soon as Photoshop sends us foreground color data.

<s:Rect id="foregroundColorRect" width="20" height="20"> <s:fill> <s:SolidColor id="foregroundColorRectFill" color="0xFFFFFF"/> </s:fill> </s:Rect>

When we want to change the color, you'll simply set the foregroundColorRectFill.color property. You'll do this inside of the event handler for the SubscriptionManager. Before you can do that, however, you have to actually attach an event listener.

Step 3: Attach an Event Listener for Foreground Color Changes

Attaching an event listener is relatively straightforward. Inside of the click handler for our new subscribeForegroundColor button, call addEventListener on the SubscriptionManager instance. The event type will be a SubscriptionEvent.FOREGROUND_COLOR_CHANGED_EVENT:

Model.getInstance().subscriptionManager.addEventListener(SubscriptionEvent.FOREGROUND_COLOR_CHAN¬GED_EVENT,onForegroundColorChange);

Next, create the onForegroundColorChange function, which will be called whenever the SubscriptionManager determines that Photoshop is sending us relevant data. You should also remove the event listener either in the cleanUp() method, or in the click handler for an unsubscribe button.

Step 4: Display the new color

Photoshop will send data when it determines that the foreground color has changed, which the API will dispatch in a SubscriptionEvent. At this point, you can now grab the returned color and display it in the s:Rect that we created earlier. Add the following to your onForegroundColorChange handler:

private function onForegroundColorChange(se:SubscriptionEvent):void { trace("The foreground color changed to " + se.data + "!"); this.foregroundColorRectFill.color = new uint("0x" + se.data as String); }

Note that se.data is an undefined type, which you're treating as a String. In order to turn it into a uint HEX representation of a color, you've concatenated it with the String "0x". Thus, Photoshop may return the color red as #FF0000, which is represented by "FF0000". The code new uint("0xFF0000") is then called, and the returned uint is set as the Fill color. The data type of the data variable may change based on the type of data Photoshop returns, but its most common use is a String. At this time, I don't believe there are any other data types Photoshop returns for subscriptions.

You now have the ability to listen for subscription events. For a full list of these events, see the SubscriptionEvent entry in the ASDocs. Subscription events are largely useful if you want to maintain an internal representation of the Photoshop state, and perform application logic when the user starts changing things. For example, you should listen for tool change events if you have an application that always displays the currently selected tool, and you should update a thumbnail if your application displays the canvas that the user is currently changing.

If you're following along, you may want to see the project at its current state in the tutorial. Download the sample code and open the project in the code_step3 folder (or import the FXP file to Flash Builder 4.5).

Code: Sending Custom Messages

The Photoshop Touch SDK for AS3 provides the MessageDispatcher class for sending preconfigured messages to Photoshop, but the range of supported messages may be insufficient for what your application needs to do. In this case, you'll have to write your own JavaScript code that the Photoshop SDK supports, and send it using the SDK. Fortunately, this process isn't too difficult, and the Photoshop ScriptListener plug-in makes it much easier. In this section, you'll add the ability to set the brush size from your application, which requires custom JavaScript.

The process of determining and then sending custom messages can usually be accomplished with the following steps:

  1. Install the ScriptListener plug-in in Photoshop.
  2. Open Photoshop and manually run the action you wish to perform. Open the output log of the ScriptListener plug-in. This log will have the JavaScript commands that will cause the desired action in Photoshop.
  3. In your application, create a new TextMessage and fill it with the JavaScript you obtained.
  4. Use the MessageDispatcher to send the Message.

Step 1: Install the ScriptListener plug-in

To install the plug-in follow these steps:

  1. With Photoshop closed, open your Photoshop directory in the file browser of your choice, and navigate to the <Photoshop path>\Scripting\Utilities directory.

    For example, your full path may look like:

C:\apps\imagery\Adobe Photoshop CS5.1 (64 Bit)\Scripting\Utilities

  1. Copy the ScriptListener.8li file.
  2. Open <Photoshop path>\Plug-ins directory. Your full path may look like:

C:\apps\imagery\Adobe Photoshop CS5.1 (64 Bit)\Plug-ins

  1. Paste the ScriptListener.8li file into this directory.

Once you restart Photoshop and perform an action (for example, creating a new document), you should see the files ScriptingListenerJS.log and ScriptingListenerVB.log created on your desktop.

To avoid a small performance hit, you should remove the ScriptListener plug-in when you're not actively using it.

Step 2: Perform the Desired Action, and grab the JavaScript

You're going to set the brush size in Photoshop, and then copy the resulting JavaScript from the ScriptingListenerJS.log file. The important step is to differentiate between the JavaScript you're looking for and unrelated code that may have been generated by other actions. An application such as Unix "tail" is quite helpful in monitoring the log in real-time; otherwise, you'll have to use your intuition to parse the log.

  1. Open Photoshop and select the brush tool. Verify that the ScriptingListenerJS.log file has been created on your desktop.
  2. Note the contents of the ScriptingListenerJS.log file, or monitor it with tail.
  3. In Photoshop, use the Brush panel or the Options panel to change the brush size (see Figure 3).
The Options and Brush panel.
  1. Look at the latest entries in the ScriptListenerJS.log file and copy the relevant code. In this case, the code for changing the brush size is as follows:
var idsetd = charIDToTypeID( "setd" ); var desc4 = new ActionDescriptor(); var idnull = charIDToTypeID( "null" ); var ref3 = new ActionReference(); var idBrsh = charIDToTypeID( "Brsh" ); var idOrdn = charIDToTypeID( "Ordn" ); var idTrgt = charIDToTypeID( "Trgt" ); ref3.putEnumerated( idBrsh, idOrdn, idTrgt ); desc4.putReference( idnull, ref3 ); var idT = charIDToTypeID( "T " ); var desc5 = new ActionDescriptor(); var idmasterDiameter = stringIDToTypeID( "masterDiameter" ); var idPxl = charIDToTypeID( "#Pxl" ); desc5.putUnitDouble( idmasterDiameter, idPxl, 58.000000 ); var idBrsh = charIDToTypeID( "Brsh" ); desc4.putObject( idT, idBrsh, desc5 ); executeAction( idsetd, desc4, DialogModes.NO );

Note that the value 58.000000 is the brush size I set in Photoshop. You'll have to modify this value in your application, which you'll do in the following steps.

Step 3: Create the TextMessage and dispatch it

You'll now paste the copied JavaScript into a String constant in our HomeView Component, add a new button, and create and dispatch the TextMessage.

  1. Code the following to define a new String variable:
<fx:Declarations> <fx:String id="MESSAGE_TEXT_BRUSH_SIZE_SET">... </fx:String> </fx:Declarations>
  1. Replace the ellipses ("...") above with the JavaScript you obtained earlier. Replace the numerical brush size value (58.000000) with the placeholder token of $1 (dollar-sign one). At runtime, you'll use the SDK's Util.replaceParams() function to replace the token with a value.
  2. Add a new Button with the label "Set Brush Size," and create an event listener for the click event.
  3. Inside of the Button's event handler, there are a few lines of code you need to write. The tasks that need to be accomplished are:
    • Replace the $1 token with a String representation of a numerical value. In this case, you'll use "30.0":
var messageText:String = Util.replaceParams(this.MESSAGE_TEXT_BRUSH_SIZE_SET,"30.0");
  • Create a new TextMessage and set the message property:
var tm:TextMessage = new TextMessage(); tm.message = messageText;
  • Set the TextMessage transaction ID. You'll use the SDK's TransactionManager to do this, which makes grabbing the next available transaction ID easy. Should you choose the ID carelessly, it's possible you'd pick one that's already in use by a Subscription. This would confuse the SubscriptionManager, and result in error events.
tm.transactionID = TransactionManager.getInstance().getNextTransactionID();
  • Finally, you'll dispatch the message!
Model.getInstance().messageDisp.sendMessage(tm);

You should test this new functionality. Change the brush size to something other than 30.0, click the new s:Button, and you should see the brush size change. Photoshop will respond with a TextMessage after accepting your command, the body of which should contain [ActionDescriptor].

Feel free to experiment with your new skills. Try creating an HSlider that changes the brush size as the user scrubs the thumb, or, if you're feeling ambitious, a component that lets you use the touchscreen to arbitrarily rotate Photoshop's canvas.

The code for this step in the project is in the code_step4 folder; open the src folder or import the FXP into Flash Builder 4.5.

Where to go from here.

The Photoshop Touch SDK allows developers to control Photoshop remotely, and the Photoshop Touch SDK for AS3 lets Flash, AIR, and Flex apps easily establish and manage this communication.

In this tutorial you've learned how to integrate and use this API in your own AS3 and Flex projects. You should now be able to use the MessageDispatcher, SubscriptionManager, TransactionManager, and other major classes of the SDK, as well as the ScriptListener plug-in for Photoshop.

For more information, you can contact me via my blog or follow me on Twitter: @antiChipotle

I'd love to get feedback on the Photoshop Touch SDK, as well as suggestions for future SDK updates.