零基础的 PhotoShop CEP 6 开发教程 「 5 」事

2015-11-05  本文已影响1710人  不知语冰

《零基础的 PhotoShop CEP 6 开发教程》系列目录

「 0 」目录
「 1 」配置开发环境
「 2 」CEP 文件结构
「 3 」CEP 的运行机制
「 4 」Hello World !
「 5 」事件(EVENTS)
「 6 」调用 JSX 并传递信息
「 7 」UI - HTML 开发的一些细节
「 8 」API - 文件读写与二进制数据
「 9 」签名打包与 ZXPSignCmd
「 X 」CEP 更新到 6.1版了


CEP 扩展通过事件(Event)来捕获 PhotoShop 的各种操作和状态的变化,同时也可作为 JAX 和 CEP JavaScript 之间传递信息的工具。

事件机制

当宿主应用(如 PhotoShop) 进行各种操作和状态的变化时就会发送事件,在 CEP 的 JavaScript 中通过监听器把方法和事件类型绑定,每当事件发生,就会执行绑定的方法。

同时也可以发送自定义的事件,而且在 JSX 中也可以发送事件,这就可以在 JAX 与 CEP 的 JavaScript 间传递信息和数据了。

事件属性

事件(Event)作为一个对象,有以下属性:

属性 名称 作用
type 类型 用来识别事件的名称
scope 作用范围 可设置为"APPLICATION" (当前宿主应用)或者 "GLOBAL" (全局)
appId 应用 ID 生成事件的宿主应用的识别名称。可选
extensionId 扩展 ID 生成事件的扩展的识别名称。可选
data 数据 事件携带的数据,用来传递信息

事件分为 2 种:

监听事件

监听事件需要 csInterface.js 前几期已经提到过了,不在繁述。

通过csInterface.js提供的 addEventListener(type,function) 把一个方法绑定给一种事件,每当这种事件发生,就调用这个方法,并传递此次事件的 Event 对象。

Event 对象的属性在前面已经说过了, event.data 属性中会有事件的信息,如果是宿主程序事件一般是 XML 字符串,而 ExtendScript 事件是 JSON 字符串。

下面这个示例把方法 PSCallback()绑定给了 documentAfterActivate(文档被激活)事件,当 PhotoShop 中切换到某个文档时就会收到调用PSCallback(),并且传递事件对象,通过访问事件对象的 .data 属性会得到类似这样的数据:"<documentAfterActivate><name>2个VM差别</name><url>file:///E:/工作/Adobe 扩展开发/2 个 VM 差别.psd</url></documentAfterActivate>"


var cs = new CSInterface();
cs.addEventListener("documentAfterActivate" , PSCallback); //applicationActivate : 文档被激活

function PSCallback(event) //处理事件的函数,会接受到一个 Event 对象
{
    alert(event.data);/***  <documentAfterActivate><name>2个VM差别</name><url>file:///E:/工作/Adobe 扩展开发/2 个 VM 差别.psd</url></documentAfterActivate>  ***/
}

另外 addEventListener()也支持匿名函数,上面的例子可以简化为

    new CSInterface().addEventListener(
        "documentAfterActivate", function (event){ alert(event.data) ;}
    )

取消监听

通过 removeEventListener( ) 可以取消监听绑定

var cs = new CSInterface();
cs.removeEventListener("documentAfterActivate" , PSCallback);

发送事件

除了监听宿主应用的事件,我们自己也可以发送事件

CEP JavaScript 端

通过创建一个 Event 对象再使用 CSInterface 的 dispatchEvent() 方法,就可以发送一个事件:

    var cs = new CSInterface();
    var event = new CSEvent(); // 创建一个事件对象
    event.type = "com.nullice.event.test"; //设定一个类型名称
    event.scope = "APPLICATION";// 限定在宿主应用范围内
    event.data = " good bye! @whitesincerely "; // 事件要传递的信息
    cs.dispatchEvent(event); // GO ! 发送事件

这样发送的信息根据事件 type 就能简单的捕获。

JAX 端

在 JAX 端,由于 ExtendScript 默认没有支持事件处理,需要手动载入一个库:new ExternalObject("lib:\PlugPlugExternalObject") ,载入后就可以通过创建 CSXSEvent() 对象来创建并发送事件了:

try {
    var loadSuccess = new ExternalObject("lib:\PlugPlugExternalObject"); //载入所需对象,loadSuccess 记录是否成功载入
} catch (e) {
    alert(e);// 如果载入失败,输出错误信息
}
 
if (loadSuccess) { 
var eventJAX = new CSXSEvent(); //创建事件对象
        eventJAX.type = "com.nullice.event.test"; //设定一个类型名称
        eventJAX.data = " (⋟﹏⋞) !!!"; // 事件要传递的信息
        eventJAX.dispatch(); // GO ! 发送事件
}


以上事件都可以在 CEP 的 JavaScript 中通过下面这个示例代码监听:

  cs.addEventListener("com.nullice.event.test2",
        function (Event)
        {
            alert(Event.type +" : " + Event.data);
        }
    );
在 Adobe ExtendScript Toolkit 中执行可以立即看到结果

ExtendScript 事件监听

在 PhotoShop 中创建、移动一个图层、复制、粘贴内容等操作产生的事件就属于 ExtendScript 事件,ExtendScript 事件与不同其他事件,不能简单通过事件的 type 来捕捉,而需要注册想要捕捉的事件后统一捕捉并处理。

ExtendScript eventID

每种 ExtendScript 事件有不同 eventID ,比如创建图层是 1298866208, 复制是 1668247673

在 JSX 中有个方法 charIDToTypeID( ) 可以把事件名转换成 eventID ,

    charIDToTypeID( "copy" )  // 返回 1668247673

事件名可以在 Adobe 官方文档:《ADOBE PHOTOSHOP CC 2014 JAVASCRIPT SCRIPTING REFERENCE》
的附录中找到。

不过我推荐这些事件名和 eventID 的对照表。:
Photoshop Events (CC2015 ver.16)
Photoshop Constants Rosetta Stone

注册想要监听的 ExtendScript 事件

监听 ExtendScript 事件得先发送一个com.adobe.PhotoshopRegisterEvent 类型的 CEP 事件,来告诉宿主你要监听的 ExtendScript 事件。这个 “注册事件” 的 .data 就填写你要监听的 ExtendScript 事件的 eventID :


    var cs= new CSInterface();
    var event = new CSEvent("com.adobe.PhotoshopRegisterEvent", "APPLICATION");  //创建一个“注册事件”
    event.extensionId = cs.getExtensionID(); //设置“注册事件” extensionId 为你扩展的扩展ID
    event.data = "1298866208"; // 想要监听的 ExtendScript 事件 eventID , 这里是创建图层对象事件: "Mk  "=1298866208
    cs.dispatchEvent(event); //发送“注册事件”,完成注册

事件绑定 开始监听

注册完事件,就可以绑定方法了,通过 cs.addEventListener() ,监听一个 type 为 "com.adobe.PhotoshopJSONCallback + 你的扩展ID"的事件,就能接收到 ExtendScript 事件了:

    var cs= new CSInterface();
    cs.addEventListener("com.adobe.PhotoshopJSONCallback" + cs.getExtensionID(), PSCallback);

可以看到,所有 ExtendScript 事件都通过这个 "com.adobe.PhotoshopJSONCallback + 你的扩展ID"的 CEP 事件来接收,ExtendScript 事件对象 JSON 化的字符串被放在 "com.adobe.PhotoshopJSONCallback + 你的扩展ID".data

下面是上面示例代码中接收的事件的 .data(为了展示已经格式化,原本没有换行):

ver1, {
    "eventID": 1298866208, "eventData": {
        "layerID": 16, "null": {"_ref": "contentLayer"}, "using": {
            "_obj": "contentLayer", "shape": {
                "_obj": "customShape", "bottom": {"_unit": "distanceUnit", "_value": 73.9907},
                "left": {"_unit": "distanceUnit", "_value": 54.9931}, "name": "箭头 5",
                "right": {"_unit": "distanceUnit", "_value": 107.986},
                "top": {"_unit": "distanceUnit", "_value": 34.9956}
            }, "strokeStyle": {
                "_obj": "strokeStyle", "fillEnabled": true, "strokeEnabled": false,
                "strokeStyleBlendMode": {"_enum": "blendMode", "_value": "normal"},
                "strokeStyleContent": {"_obj": "solidColorLayer", "color": {"_obj": "grayscale", "gray": 0}},
                "strokeStyleLineAlignment": {"_enum": "strokeStyleLineAlignment", "_value": "strokeStyleAlignInside"},
                "strokeStyleLineCapType": {"_enum": "strokeStyleLineCapType", "_value": "strokeStyleButtCap"},
                "strokeStyleLineDashOffset": {"_unit": "pointsUnit", "_value": 0}, "strokeStyleLineDashSet": [],
                "strokeStyleLineJoinType": {"_enum": "strokeStyleLineJoinType", "_value": "strokeStyleMiterJoin"},
                "strokeStyleLineWidth": {"_unit": "pointsUnit", "_value": 4}, "strokeStyleMiterLimit": 100,
                "strokeStyleOpacity": {"_unit": "percentUnit", "_value": 100}, "strokeStyleResolution": 72.009,
                "strokeStyleScaleLock": false, "strokeStyleStrokeAdjust": false, "strokeStyleVersion": 2
            }, "type": {"_obj": "solidColorLayer", "color": {"_obj": "grayscale", "gray": 33.8823}}
        }
    }
} 

可以看到我们绑定给 "com.adobe.PhotoshopJSONCallback + 你的扩展ID"事件的方法(例子中的 PSCallback()),需要解析得到的 CEP 事件的 .data 中 JSON 来获得 ExtendScript 事件,并自己判断得到的 ExtendScript 事件类型:

    function PSCallbackevent)
    {
        event.data = event.data.replace("ver1,{", "{"); //去掉前缀 “ver1,”
        var esEvent = JSON.parse(event.data); //把  JSON 字符串转换成对象
        alert(esEvent.eventID + "\n" + esEvent.eventData); //使用 eventID 属性判断事件类型,eventData 为事件数据
    }


取消监听

要取消一个 ExtendScript 事件的监听,就是要取消其注册。与注册基本一样,只是这次发送的是 com.adobe.PhotoshopUnRegisterEvent 类型的消息:


   var cs= new CSInterface();
   var event = new CSEvent("com.adobe.PhotoshopUnRegisterEvent", "APPLICATION");  //创建一个“取消注册事件”
   event.extensionId = cs.getExtensionID(); //设置“取消注册事件” extensionId 为你扩展的扩展ID
   event.data = "1298866208"; // 要取消注册事件的 id
   cs.dispatchEvent(event); //发送“取消注册事件”,取消注册


至此 CEP 的事件(EVENTS)及其用法已经介绍完了,接下来会介绍从 JSX 与 CEP JavaScript 之间调用和传递数据的各种方法

上一篇下一篇

猜你喜欢

热点阅读