Skip to content

Commit c9d3624

Browse files
committed
xmp reader working
1 parent 1f5b1e1 commit c9d3624

File tree

12 files changed

+936
-52
lines changed

12 files changed

+936
-52
lines changed

CSXS/manifest.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@
3030
<Type>Panel</Type>
3131
<Menu>Universal Images</Menu>
3232
<Geometry>
33-
<Size>
33+
<!--Size>
3434
<Height>480</Height>
3535
<Width>720</Width>
36-
<!--<MinSize>
37-
<Height>550</Height>
38-
<Width>400</Width>
39-
</MinSize>
40-
<MaxSize>
41-
<Height>550</Height>
42-
<Width>400</Width>
43-
</MaxSize>-->
44-
</Size>
36+
</Size-->
37+
<MinSize>
38+
<Height>480</Height>
39+
<Width>320</Width>
40+
</MinSize>
41+
<MaxSize>
42+
<Height>550</Height>
43+
<Width>640</Width>
44+
</MaxSize>
4545
</Geometry>
4646
<Icons>
4747
<Icon Type="Normal">./icons/iconNormal.png</Icon>

app/app.js

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,50 @@
1-
(function() {
1+
(function(global) {
2+
themeManager.init();
23

3-
var app = angular.module('app', []);
4+
var app = angular.module('app', ['ngLodash']);
45

5-
app.controller('MainController', ['$scope', 'csInterface', 'themeManager',
6-
function ($scope, csInterface, themeManager) {
7-
themeManager.init();
6+
app.controller('MainController', ['$scope', 'csInterface', 'RMD',
7+
function ($scope, csInterface, RMD) {
88

99
// csInterface.evalScript('sayHello()');
1010

1111
$scope.greeting = 'Hallo';
12-
}]);
13-
}());
12+
$scope.rmd = RMD.rmd;
13+
14+
// TODO: Remove debugging exposures.
15+
global._scope = $scope;
16+
global.RMD = RMD;
17+
18+
}
19+
])
20+
.directive('xmpExtract', ['XMPBridge', 'xmlNamespaces', function(XMPBridge, ns){
21+
return {
22+
restrict: 'A',
23+
link: function(scope, elm, attrs){
24+
25+
scope.allowedDerivates_Crop = true;
26+
27+
XMPBridge.onInit(function(state) {
28+
if(!state.isError) {
29+
// retrieve a descriptive name for the active target item (e.g. active document, footage, ...)
30+
XMPBridge.getTargetName(function(targetName) {
31+
scope.targetName = targetName;
32+
scope.$apply();
33+
});
34+
XMPBridge.read(ns.exif, 'PixelXDimension', function(value){
35+
scope.xDimension = value;
36+
scope.$apply();
37+
});
38+
global.bridge = XMPBridge;
39+
global.ns = ns;
40+
41+
42+
} else {
43+
throw new Error('Failed to load XMP Bridge.');
44+
}
45+
});
46+
}
47+
}
48+
}]);
49+
50+
}(window));

app/constants.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
angular.module('app')
2+
.constant('psEvent', {
3+
make: 1298866208,
4+
delete: 1147958304,
5+
close: 1131180832,
6+
select: 1936483188,
7+
set: 1936028772
8+
})
9+
.constant('xmlNamespaces', {
10+
xmp: 'http://ns.adobe.com/xap/1.0/',
11+
rmd: 'http://universalimages.github.io/rmd/',
12+
stDim: 'http://ns.adobe.com/xap/1.0/sType/Dimensions#',
13+
stArea: 'http://ns.adobe.com/xmp/sType/Area#',
14+
exif: 'http://ns.adobe.com/exif/1.0/',
15+
dc: 'http://purl.org/dc/elements/1.1/' // Dublin Core
16+
})
17+
;

app/services/csinterface.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,66 @@
1+
(function(){
2+
3+
function PhotoshopCallbackUnique(csEvent) {
4+
try {
5+
if (typeof csEvent.data === "string") {
6+
var eventData = csEvent.data.replace("ver1,{", "{");
7+
var eventDataParse = JSON.parse(eventData);
8+
var jsonStringBack = JSON.stringify(eventDataParse);
9+
10+
console.log(eventDataParse);
11+
//SetResultLabel("PhotoshopCallbackUnique: " + jsonStringBack);
12+
//JSLogIt("PhotoshopCallbackUnique: " + jsonStringBack);
13+
//
14+
//var uiItemToUpdate = null;
15+
//if (eventDataParse.eventID === eventMake)
16+
// uiItemToUpdate = lblMake;
17+
//else if (eventDataParse.eventID === eventDelete)
18+
// uiItemToUpdate = lblDelete;
19+
//else if (eventDataParse.eventID === eventClose)
20+
// uiItemToUpdate = lblClose;
21+
//else if (eventDataParse.eventID === eventSelect)
22+
// uiItemToUpdate = lblSelect;
23+
//else if (eventDataParse.eventID === eventSet)
24+
// uiItemToUpdate = lblSet;
25+
//
26+
//if (uiItemToUpdate !== null) {
27+
// var count = Number(uiItemToUpdate.innerHTML) + 1;
28+
// uiItemToUpdate.innerHTML = " " + count;
29+
//}
30+
//
31+
//// if you just made a text layer, let me check my object for something
32+
//// interesting to dump to log
33+
//if (eventDataParse &&
34+
// eventDataParse.eventData.null &&
35+
// eventDataParse.eventData.null._ref &&
36+
// eventDataParse.eventData.null._ref === "textLayer") {
37+
// JSLogIt("Got a text layer, trying to find paragraphStyleRange");
38+
// if (eventDataParse.eventData.using &&
39+
// eventDataParse.eventData.using.paragraphStyleRange) {
40+
// JSLogIt("paragraphStyleRange:" + eventDataParse.eventData.using.paragraphStyleRange);
41+
// JSLogIt("paragraphStyleRange typeof :" + typeof eventDataParse.eventData.using.paragraphStyleRange);
42+
// JSLogIt("paragraphStyleRange[0].from: " + eventDataParse.eventData.using.paragraphStyleRange[0].from);
43+
// }
44+
//}
45+
} else {
46+
console.error("PhotoshopCallbackUnique expecting string for csEvent.data!");
47+
}
48+
} catch(e) {
49+
console.error("PhotoshopCallbackUnique catch:" + e);
50+
}
51+
}
52+
153

254
angular.module('app')
355
.factory('csInterface', function(){
4-
return new CSInterface();
56+
var csInterface = new CSInterface();
57+
var gExtensionID = csInterface.getExtensionID();
58+
59+
// all callbacks need to be unique so only your panel gets them
60+
// for Photoshop specific add on the id of your extension
61+
csInterface.addEventListener("com.adobe.PhotoshopJSONCallback" + gExtensionID, PhotoshopCallbackUnique);
62+
console.log('Adding Event Listener for ', gExtensionID);
63+
return csInterface;
564
});
65+
66+
}());

app/services/rmd.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
angular.module('app')
2+
.factory('RMD', ['XMPBridge', 'xmlNamespaces', 'lodash',
3+
function(XMPBridge, Namespaces, _) {
4+
5+
// TODO: store metadata for different targets (=files)
6+
var targets = {};
7+
var ns = Namespaces.rmd;
8+
9+
var RMD = function() {
10+
this._asyncOps = 0;
11+
this.rmd = {
12+
'AppliedToDimensions' : {
13+
'stDim:w': 0,
14+
'stDim:h': 0,
15+
'stDim:unit': 'pixel'
16+
},
17+
'AllowedDerivates': {
18+
Crop: 'all'
19+
},
20+
'SafeArea': {
21+
'stArea:x': 0,
22+
'stArea:y': 0,
23+
'stArea:w': 1,
24+
'stArea:h': 1,
25+
'stArea:unit': 'normalized'
26+
},
27+
'PivotPoint': {
28+
'stArea:x': 0.5,
29+
'stArea:y': 0.5
30+
}
31+
};
32+
33+
this.getFromXMP = function() {
34+
var self = this;
35+
var xmpKey;
36+
XMPBridge.onInit(function(state) {
37+
if(!state.isError) {
38+
XMPBridge.getTargetName(function(targetName) {
39+
self.targetName = targetName;
40+
});
41+
_.forOwn(self.rmd, function getXMPValue(value, key, obj, parent) {
42+
if(value instanceof Array) {
43+
// skip for now. TODO: implement this.
44+
} else if(typeof value === 'object') { // value is a struct
45+
_.forOwn(value, function(v, k, o) {
46+
getXMPValue(v, k, o, key);
47+
});
48+
} else { // value is a base type
49+
xmpKey = parent === undefined ? key : xmpKey = parent + '/' + key;
50+
console.log('getting value for ' + xmpKey);
51+
XMPBridge.read(ns, xmpKey, function(value) {
52+
obj[key] = value;
53+
});
54+
}
55+
});
56+
} else {
57+
throw new Error('Failed to load XMP Bridge.');
58+
}
59+
});
60+
61+
};
62+
};
63+
64+
var rmd = new RMD();
65+
rmd.getFromXMP();
66+
67+
return rmd;
68+
69+
}]);

app/services/xmpbridge.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
angular.module('app')
2+
.factory('XMPBridge', function() {
3+
return XMPBridge;
4+
});

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
],
1717
"dependencies": {
1818
"angular": "~1.4.8",
19-
"topcoat": "~0.8.0"
19+
"topcoat": "~0.8.0",
20+
"ng-lodash": "~0.3.0"
2021
}
2122
}

0 commit comments

Comments
 (0)