零基础的 PhotoShop CEP 6 开发教程 「 5 」事件(EVENTS)监听/发起

《零基础的 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 种:

  • CEP 事件

  • 宿主程序事件
    PhotoShop 启动、打开文档等会产生的这类事件,
    这种事件有自己的类型(type),例如:
    applicationActivatedocumentAfterActivate

  • 自定义事件
    用户自己创建并发送的 CEP 事件。

  • ExtendScript 事件
    也是宿主活动产生的事件,但与前 1 种并不一样,你不能从某个类型(type)来识别和捕获这种事件,而必须注册要监听的事件,并通过com.adobe.PhotoshopJSONCallback 事件集中监听 ExtendScript 事件,并自己通过 eventID 判断接受到的是何种事件。
    可以说 ExtendScript 事件是另一套事件系统,而它实际上通过 CEP 事件来传递。

监听事件

监听事件需要 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 之间调用和传递数据的各种方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容