• CEP

HTML Panels Tips: #7 Photoshop Events, Take 1

This tip shows you the first way to make an HTML Panel listen and react to Photoshop Events: via PhotoshopRegisterEvent. Back in the Flash land, there were two ways to register callbacks for Photoshop Events: using either a PSHosttAdapter library, or an ExternalInterface object and PhotoshopCallback. Today’s tip is about the latter (see Tip #8 for the PSHostAdapter libraries). What we used to write in ActionScript was something like:

// Set TypeID for desired events
private const COPY_INT:int = Photoshop.app.charIDToTypeID(’copy’);
private const PASTE_INT:int = Photoshop.app.charIDToTypeID(’past’);

// Register for events
CSInterface.PhotoshopRegisterEvent(COPY_INT + "," + PASTE_INT);
// attach a callback
ExternalInterface.addCallback("PhotoshopCallback" + CSInterface.getExtensionId(), myPhotoshopCallback);
// Define the callback
private function myPhotoshopCallback(eventID:Number, descID:Number):void {
//
}

Things are slightly different now in Javascript. and are based on CSInterface and the dispatching of a custom Event. As follows the mechanism in a nutshell, then I’ll show you an actual example:

var csInterface = new CSInterface();

// Create a new Event
var event = new CSEvent("com.adobe.PhotoshopRegisterEvent", "APPLICATION");

// Set Event properties: extension id
event.extensionId = "com.example.psevents";

// Set Event properties: data (as Type ID string, comma separated)
// 1668247673 = charIDToTypeID( "copy" ) = copy
// 1885434740 = charIDToTypeID( "past" ) = paste
// 1668641824 = charIDToTypeID( "cut " ) = cut
event.data = "1668247673, 1885434740, 1668641824";

// Dispatch the Event
csInterface.dispatchEvent(event);

// Attach a callback
csInterface.addEventListener("PhotoshopCallback", PSCallback);

// Define the callback
function PSCallback(csEvent) {
  // ...
}

Example

PSEvents

This Panel has a switch to turn ON/OFF the listener for few PS Events (cut, copy, paste). When the listener is active and the user cuts, copies or pastes, the Event’s StringID is written in the text area. In case you need a refresh of HTML Panels related topics to go through this one, here’s the whole list. You might need a refresh because this example uses Topcoat CSS (see HTML Panels Tip #6) and communication between HTML and JSX (Tip #4).

HTML

The Panel uses boilerplate code by David Deraedt with the addition of Topcoat CSS (refer to HTML Panels Tip #6 for the details). I’ve set up a Topcoat Switch and a Text Area:

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <link id="hostStyle" rel="stylesheet" href="css/theme.css" />
  <link id="theme" rel="stylesheet" href="css/light.css" />
  <title></title>
</head>

<body>
  <div style="width: 80%; margin:0 auto">
    <h3 class="center">PS Events</h3>
    <label class="topcoat-switch">
      <input id="registerEvent" type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <input type="text" id="result" class="topcoat-text-input" style="margin-left:10px" placeholder="Listen for Events" value="">
  </div>

  <script src="js/libs/CSInterface-4.0.0.js"></script>
  <script src="js/libs/jquery-2.0.2.min.js"></script>
  <script src="js/themeManager.js"></script>
  <script src="js/main.js"></script>

</body>

</html>

Javascript

In main.js it’s defined the Register() function that attaches (or remove) the listener, dispatching a CSEvent as you’ve already seen. A jQuery function binds the switch to Register() and finally a PSCallback function is defined: there, the Event data String is split and passed for evaluation to JSX (see Tip #4 for details about HTML to JSX data exchange). The evalScript callback (that is, the JSX return value) is displayed in the Text Area.

(function() {
  'use strict';

  var csInterface = new CSInterface();

  function Register(inOn) {

    if (inOn) {
      var event = new CSEvent("com.adobe.PhotoshopRegisterEvent", "APPLICATION");
    } else {
      var event = new CSEvent("com.adobe.PhotoshopUnRegisterEvent", "APPLICATION");
    }
    event.extensionId = "com.example.psevents";

    // some events:
    // 1668247673 = charIDToTypeID( "copy" ) = copy
    // 1885434740 = charIDToTypeID( "past" ) = paste
    // 1668641824 = charIDToTypeID( "cut " ) = cut
    event.data = "1668247673, 1885434740, 1668641824";
    csInterface.dispatchEvent(event);
  }

  function init() {

    themeManager.init();

    // Switch onChange callback
    $('#registerEvent').change(function() {
      Register($(this).is(':checked')); // true or false
    });
  }

  function PSCallback(csEvent) {
    var dataArray = csEvent.data.split(",");
    // send to JSX to convert typeIDs to stringIDs
    csInterface.evalScript('convertTypeID(' + JSON.stringify(dataArray\[0\]) + ')', function(res) {
      $('#result').val(res.toString());
    });
  }

  init();
  csInterface.addEventListener("PhotoshopCallback", PSCallback);

}());

JSX

In the JSX file there’s just a function, that converts the TypeID to StringID and returns it.

function convertTypeID (typeArray) {
  return typeIDToStringID(Number(typeArray));
}

The Photoshop HTML Panels Development Course

Photoshop HTML Panels Development course
Updated to CC 2019.

If you’re reading here, you might be interested in my Photoshop Panels development – so let me inform you that I’ve authored a full course:

  • 300 pages PDF
  • 3 hours of HD screencasts
  • 28 custom Panels with commented code

Check it out! Please help me spread the news – I’ll be able to keep producing more exclusive content on this blog. Thank you!