|
19 | 19 | arrayAccessFormPaths: ['xmpmeta.RDF.Description.RecommendedFrames.Bag.li'] |
20 | 20 | }; |
21 | 21 | }) |
22 | | - .controller('MainController', ['$scope', 'csInterface', 'rmdBridge', 'rmdDefault', 'lodash', |
23 | | - function ($scope, csInterface, RMD, rmdDefault, _) { |
| 22 | + .controller('MainController', ['$scope', 'csInterface', 'rmdBridge', |
| 23 | + 'rmdDefault', 'lodash', 'psEvent', |
| 24 | + function ($scope, csInterface, RMD, rmdDefault, _, psEvent) { |
| 25 | + |
| 26 | + var activeArea = null; |
| 27 | + var gExtensionID = csInterface.getExtensionID(); |
| 28 | + |
| 29 | + // Tell Photoshop to not unload us when closed |
| 30 | + function Persistent(inOn) { |
| 31 | + gStartDate = new Date(); |
| 32 | + var event; |
| 33 | + if (inOn) { |
| 34 | + event = new CSEvent("com.adobe.PhotoshopPersistent", "APPLICATION"); |
| 35 | + } else { |
| 36 | + event = new CSEvent("com.adobe.PhotoshopUnPersistent", "APPLICATION"); |
| 37 | + } |
| 38 | + event.extensionId = gExtensionID; |
| 39 | + csInterface.dispatchEvent(event); |
| 40 | + SetResultTime(); |
| 41 | + } |
| 42 | + // Tell Photoshop the events we want to listen for |
| 43 | + var _register = function(inOn, inEvents) { |
| 44 | + var event; |
| 45 | + if (inOn) { |
| 46 | + event = new CSEvent("com.adobe.PhotoshopRegisterEvent", "APPLICATION"); |
| 47 | + } else { |
| 48 | + event = new CSEvent("com.adobe.PhotoshopUnRegisterEvent", "APPLICATION"); |
| 49 | + } |
| 50 | + event.extensionId = gExtensionID; |
| 51 | + event.data = inEvents; |
| 52 | + console.log('dispatching event: ', event); |
| 53 | + csInterface.dispatchEvent(event); |
| 54 | + }; |
| 55 | + |
| 56 | + /** |
| 57 | + * Toggle the 'set' event (Area mark) listener. |
| 58 | + * @param status - True or false -> on or off. |
| 59 | + */ |
| 60 | + var selectListener = function(status) { |
| 61 | + _register(status, psEvent.set.toString()); |
| 62 | + }; |
| 63 | + // deactivate leftover listeners on startup |
| 64 | + selectListener(false); |
24 | 65 |
|
25 | | - $scope.greeting = 'Hallo'; |
26 | 66 | $scope.rmd = RMD.xmp.xmpmeta.RDF.Description; |
| 67 | + $scope.documentSize = {}; |
27 | 68 |
|
28 | 69 | // TODO: Remove debugging exposures. |
29 | 70 | global._scope = $scope; |
30 | 71 | global.RMD = RMD; |
31 | 72 |
|
| 73 | + // store the original image size |
| 74 | + csInterface.evalScript('getDocumentSize()', function(value) { |
| 75 | + $scope.documentSize = JSON.parse(value); |
| 76 | + }); |
| 77 | + |
| 78 | + |
| 79 | + /** |
| 80 | + * Event callback for Photoshop Events. Currently only the 'set' event. |
| 81 | + * @param csEvent Photoshop Event. |
| 82 | + */ |
| 83 | + var PhotoshopCallbackUnique = function(csEvent) { |
| 84 | + // console.log('receiving Callback: ', csEvent); |
| 85 | + if (typeof csEvent.data === "string") { |
| 86 | + var eventData = csEvent.data.replace("ver1,{", "{"); |
| 87 | + var data = JSON.parse(eventData); |
| 88 | + console.log(data); |
| 89 | + if(data.eventData.null._property === 'selection' && data.eventID === psEvent.set |
| 90 | + && data.eventData.to._obj === 'rectangle' && activeArea){ |
| 91 | + if(data.eventData.to.top._unit === 'pixelsUnit'){ |
| 92 | + setAreaValues(data.eventData.to); |
| 93 | + } else { |
| 94 | + alert('Please set the units to Pixels. Other units are currently not supported.'); |
| 95 | + } |
| 96 | + } |
| 97 | + } else { |
| 98 | + console.error("PhotoshopCallbackUnique expecting string for csEvent.data!"); |
| 99 | + } |
| 100 | + }; |
| 101 | + |
| 102 | + /** |
| 103 | + * Get the RMD object node for the given area key. |
| 104 | + * @returns {*} RMD node. |
| 105 | + */ |
| 106 | + var getNodeForActiveArea = function() { |
| 107 | + if(activeArea === 'default') { |
| 108 | + return $scope.rmd.CropArea; |
| 109 | + } else if (activeArea === 'safe') { |
| 110 | + return $scope.rmd.SafeArea; |
| 111 | + } else { |
| 112 | + return $scope.rmd.RecommendedFrames.Bag.li[activeArea] |
| 113 | + } |
| 114 | + }; |
| 115 | + |
| 116 | + /** |
| 117 | + * Sets the values returned by a Photoshop event in the RMD node. |
| 118 | + * @param ps_data Photoshop event property. |
| 119 | + */ |
| 120 | + var setAreaValues = function(ps_data) { |
| 121 | + var node, x, y, width, height; |
| 122 | + node = getNodeForActiveArea(); |
| 123 | + // PS returns the are as left, top, width height. |
| 124 | + // The RMD standard requires centerX, centerY, width height. |
| 125 | + width = ps_data.right._value - ps_data.left._value; |
| 126 | + height = ps_data.bottom._value - ps_data.top._value; |
| 127 | + x = ps_data.left._value + width/2; |
| 128 | + y = ps_data.top._value + height/2; |
| 129 | + node.x.__text = (x / $scope.documentSize.width).toString(); |
| 130 | + node.y.__text = (y / $scope.documentSize.height).toString(); |
| 131 | + node.w.__text = (width / $scope.documentSize.width).toString(); |
| 132 | + node.h.__text = (height / $scope.documentSize.height).toString(); |
| 133 | + $scope.$apply(); |
| 134 | + }; |
| 135 | + |
| 136 | + var setSelectionFromRmd = function() { |
| 137 | + var x, y, width, height, left, top, coords; |
| 138 | + var node = getNodeForActiveArea(); |
| 139 | + x = parseFloat(node.x.__text) * $scope.documentSize.width; |
| 140 | + y = parseFloat(node.y.__text) * $scope.documentSize.height; |
| 141 | + width = parseFloat(node.w.__text) * $scope.documentSize.width; |
| 142 | + height = parseFloat(node.h.__text) * $scope.documentSize.height; |
| 143 | + left = parseInt(x - width/2); |
| 144 | + top = parseInt(y - height/2); |
| 145 | + |
| 146 | + coords = { |
| 147 | + left: left, |
| 148 | + top: top, |
| 149 | + right: parseInt(left + width), |
| 150 | + bottom: parseInt(top + height) |
| 151 | + }; |
| 152 | + csInterface.evalScript('makeSelection(' + JSON.stringify(coords) + ')'); |
| 153 | + }; |
| 154 | + |
| 155 | + // all callbacks need to be unique so only your panel gets them |
| 156 | + // for Photoshop specific add on the id of your extension |
| 157 | + csInterface.addEventListener("com.adobe.PhotoshopJSONCallback" + gExtensionID, PhotoshopCallbackUnique); |
| 158 | + |
| 159 | + /** |
| 160 | + * Adds a new crop region to the metadata. There are three types: The default crop area, |
| 161 | + * the safety area and a list of recommended crop areas |
| 162 | + * @param name - the name of the area. One of 'default', 'safe' or a number. |
| 163 | + */ |
32 | 164 | $scope.addCropArea = function(name) { |
33 | 165 | if(name === undefined) { |
34 | 166 | $scope.rmd.RecommendedFrames.Bag.li.push(_.cloneDeep(rmdDefault.xmpmeta.RDF.Description.SafeArea)); |
|
38 | 170 | $scope.rmd.SafeArea = _.cloneDeep(rmdDefault.xmpmeta.RDF.Description.SafeArea); |
39 | 171 | } |
40 | 172 | }; |
| 173 | + /** |
| 174 | + * Removes the crop area from the metadata. |
| 175 | + * @param index - the name of the area to remove. One of 'default', 'safe' or a number. |
| 176 | + */ |
41 | 177 | $scope.removeCropArea = function(index) { |
| 178 | + // deactivate area |
| 179 | + if(activeArea === index) { |
| 180 | + $scope.setActiveArea(null); |
| 181 | + } |
42 | 182 | if(index === 'default') { |
43 | 183 | delete $scope.rmd.CropArea; |
44 | 184 | } else if(index === 'safe') { |
|
47 | 187 | $scope.rmd.RecommendedFrames.Bag.li.splice(index, 1); |
48 | 188 | } |
49 | 189 | }; |
| 190 | + /** |
| 191 | + * Check if the given area is active (listening to events) |
| 192 | + * @param area - the name of the area. |
| 193 | + * @returns {boolean} |
| 194 | + */ |
| 195 | + $scope.isAreaActive = function(area) { |
| 196 | + return area === activeArea; |
| 197 | + }; |
| 198 | + /** |
| 199 | + * Sets the given area as active. |
| 200 | + * @param area - the name of the area. |
| 201 | + */ |
| 202 | + $scope.setActiveArea = function(area) { |
| 203 | + csInterface.evalScript('clearSelection()'); |
| 204 | + if(activeArea === area || area === null) { |
| 205 | + // turn it off |
| 206 | + selectListener(false); |
| 207 | + activeArea = null; |
| 208 | + } else { |
| 209 | + if(!activeArea) { |
| 210 | + selectListener(true); |
| 211 | + } |
| 212 | + activeArea = area; |
| 213 | + setSelectionFromRmd(); |
| 214 | + } |
| 215 | + } |
50 | 216 |
|
51 | 217 | } |
52 | 218 | ]); |
|
0 commit comments