diff --git a/.vscode/launch.json b/.vscode/launch.json index fee2ebd..7bf362d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,16 +4,18 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - + { "type": "extendscript-debug", "request": "attach", - "name": "Attach to ExtendScript Engine" + "name": "Attach to ExtendScript Engine", + "hostAppSpecifier": "aftereffects-26.0" }, { "type": "extendscript-debug", "request": "launch", - "name": "Launch Script in ExtendScript Engine" + "name": "Launch Script in ExtendScript Engine", + "hostAppSpecifier": "aftereffects-26.0" } ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6dbe1e4..0000000 --- a/package-lock.json +++ /dev/null @@ -1,324 +0,0 @@ -{ - "name": "ae-library-template", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "ae-library-template", - "version": "1.0.0", - "license": "MIT", - "devDependencies": { - "docdash": "^2.0.2", - "jsdoc": "^4.0.4" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", - "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.27.1" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", - "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@jsdoc/salty": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.9.tgz", - "integrity": "sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=v12.0.0" - } - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true - }, - "node_modules/@types/markdown-it": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", - "dev": true, - "dependencies": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/docdash": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/docdash/-/docdash-2.0.2.tgz", - "integrity": "sha512-3SDDheh9ddrwjzf6dPFe1a16M6ftstqTNjik2+1fx46l24H9dD2osT2q9y+nBEC1wWz4GIqA48JmicOLQ0R8xA==", - "dev": true, - "dependencies": { - "@jsdoc/salty": "^0.2.1" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dev": true, - "dependencies": { - "xmlcreate": "^2.0.4" - } - }, - "node_modules/jsdoc": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz", - "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.15", - "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^14.1.1", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.2", - "klaw": "^3.0.0", - "markdown-it": "^14.1.0", - "markdown-it-anchor": "^8.6.7", - "marked": "^4.0.10", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "underscore": "~1.13.2" - }, - "bin": { - "jsdoc": "jsdoc.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, - "dependencies": { - "uc.micro": "^2.0.0" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/markdown-it-anchor": { - "version": "8.6.7", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "dev": true, - "peerDependencies": { - "@types/markdown-it": "*", - "markdown-it": "*" - } - }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/requizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", - "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true - }, - "node_modules/underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", - "dev": true - }, - "node_modules/xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 7fac238..0000000 --- a/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ae-library-template", - "version": "1.0.0", - "description": "A utility library for ExtendScript / After Effects scripting", - "scripts": { - "docs": "jsdoc -c jsdoc.json" - }, - "keywords": [], - "author": "kyle harter", - "license": "MIT", - "devDependencies": { - "docdash": "^2.0.2", - "jsdoc": "^4.0.4" - } -} diff --git a/src/.DS_Store b/src/.DS_Store index 99d5606..593a47d 100644 Binary files a/src/.DS_Store and b/src/.DS_Store differ diff --git a/src/library/json2.js b/src/library/json2.js new file mode 100644 index 0000000..b43526d --- /dev/null +++ b/src/library/json2.js @@ -0,0 +1,530 @@ +// json2.js +// 2023-05-10 +// Public Domain. +// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + +// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO +// NOT CONTROL. + +// This file creates a global JSON object containing two methods: stringify +// and parse. This file provides the ES5 JSON capability to ES3 systems. +// If a project might run on IE8 or earlier, then this file should be included. +// This file does nothing on ES5 systems. + +// JSON.stringify(value, replacer, space) +// value any JavaScript value, usually an object or array. +// replacer an optional parameter that determines how object +// values are stringified for objects. It can be a +// function or an array of strings. +// space an optional parameter that specifies the indentation +// of nested structures. If it is omitted, the text will +// be packed without extra whitespace. If it is a number, +// it will specify the number of spaces to indent at each +// level. If it is a string (such as "\t" or " "), +// it contains the characters used to indent at each level. +// This method produces a JSON text from a JavaScript value. +// When an object value is found, if the object contains a toJSON +// method, its toJSON method will be called and the result will be +// stringified. A toJSON method does not serialize: it returns the +// value represented by the name/value pair that should be serialized, +// or undefined if nothing should be serialized. The toJSON method +// will be passed the key associated with the value, and this will be +// bound to the value. + +// For example, this would serialize Dates as ISO strings. + +// Date.prototype.toJSON = function (key) { +// function f(n) { +// // Format integers to have at least two digits. +// return (n < 10) +// ? "0" + n +// : n; +// } +// return this.getUTCFullYear() + "-" + +// f(this.getUTCMonth() + 1) + "-" + +// f(this.getUTCDate()) + "T" + +// f(this.getUTCHours()) + ":" + +// f(this.getUTCMinutes()) + ":" + +// f(this.getUTCSeconds()) + "Z"; +// }; + +// You can provide an optional replacer method. It will be passed the +// key and value of each member, with this bound to the containing +// object. The value that is returned from your method will be +// serialized. If your method returns undefined, then the member will +// be excluded from the serialization. + +// If the replacer parameter is an array of strings, then it will be +// used to select the members to be serialized. It filters the results +// such that only members with keys listed in the replacer array are +// stringified. + +// Values that do not have JSON representations, such as undefined or +// functions, will not be serialized. Such values in objects will be +// dropped; in arrays they will be replaced with null. You can use +// a replacer function to replace those with JSON values. + +// JSON.stringify(undefined) returns undefined. + +// The optional space parameter produces a stringification of the +// value that is filled with line breaks and indentation to make it +// easier to read. + +// If the space parameter is a non-empty string, then that string will +// be used for indentation. If the space parameter is a number, then +// the indentation will be that many spaces. + +// Example: + +// text = JSON.stringify(["e", {pluribus: "unum"}]); +// // text is '["e",{"pluribus":"unum"}]' + +// text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t"); +// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + +// text = JSON.stringify([new Date()], function (key, value) { +// return this[key] instanceof Date +// ? "Date(" + this[key] + ")" +// : value; +// }); +// // text is '["Date(---current time---)"]' + +// JSON.parse(text, reviver) +// This method parses a JSON text to produce an object or array. +// It can throw a SyntaxError exception. + +// The optional reviver parameter is a function that can filter and +// transform the results. It receives each of the keys and values, +// and its return value is used instead of the original value. +// If it returns what it received, then the structure is not modified. +// If it returns undefined then the member is deleted. + +// Example: + +// // Parse the text. Values that look like ISO date strings will +// // be converted to Date objects. + +// myData = JSON.parse(text, function (key, value) { +// var a; +// if (typeof value === "string") { +// a = +// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); +// if (a) { +// return new Date(Date.UTC( +// +a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6] +// )); +// } +// return value; +// } +// }); + +// myData = JSON.parse( +// "[\"Date(09/09/2001)\"]", +// function (key, value) { +// var d; +// if ( +// typeof value === "string" +// && value.slice(0, 5) === "Date(" +// && value.slice(-1) === ")" +// ) { +// d = new Date(value.slice(5, -1)); +// if (d) { +// return d; +// } +// } +// return value; +// } +// ); + +// This is a reference implementation. You are free to copy, modify, or +// redistribute. + +/*jslint + eval, for, this +*/ + +/*property + JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== "object") { + JSON = {}; +} + +(function () { + "use strict"; + + var rx_one = /^[\],:{}\s]*$/; + var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; + var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + var rx_four = /(?:^|:|,)(?:\s*\[)+/g; + var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + + function f(n) { + // Format integers to have at least two digits. + return (n < 10) + ? "0" + n + : n; + } + + function this_value() { + return this.valueOf(); + } + + if (typeof Date.prototype.toJSON !== "function") { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? ( + this.getUTCFullYear() + + "-" + + f(this.getUTCMonth() + 1) + + "-" + + f(this.getUTCDate()) + + "T" + + f(this.getUTCHours()) + + ":" + + f(this.getUTCMinutes()) + + ":" + + f(this.getUTCSeconds()) + + "Z" + ) + : null; + }; + + Boolean.prototype.toJSON = this_value; + Number.prototype.toJSON = this_value; + String.prototype.toJSON = this_value; + } + + var gap; + var indent; + var meta; + var rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + rx_escapable.lastIndex = 0; + return rx_escapable.test(string) + ? "\"" + string.replace(rx_escapable, function (a) { + var c = meta[a]; + return typeof c === "string" + ? c + : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4); + }) + "\"" + : "\"" + string + "\""; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i; // The loop counter. + var k; // The member key. + var v; // The member value. + var length; + var mind = gap; + var partial; + var value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if ( + value + && typeof value === "object" + && typeof value.toJSON === "function" + ) { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === "function") { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case "string": + return quote(value); + + case "number": + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return (isFinite(value)) + ? String(value) + : "null"; + + case "boolean": + case "null": + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce "null". The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is "object", we might be dealing with an object or an array or +// null. + + case "object": + +// Due to a specification blunder in ECMAScript, typeof null is "object", +// so watch out for that case. + + if (!value) { + return "null"; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === "[object Array]") { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || "null"; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? "[]" + : gap + ? ( + "[\n" + + gap + + partial.join(",\n" + gap) + + "\n" + + mind + + "]" + ) + : "[" + partial.join(",") + "]"; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === "object") { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === "string") { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + ( + (gap) + ? ": " + : ":" + ) + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + ( + (gap) + ? ": " + : ":" + ) + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? "{}" + : gap + ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" + : "{" + partial.join(",") + "}"; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== "function") { + meta = { // table of character substitutions + "\b": "\\b", + "\t": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "\"": "\\\"", + "\\": "\\\\" + }; + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ""; + indent = ""; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === "number") { + for (i = 0; i < space; i += 1) { + indent += " "; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === "string") { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== "function" && ( + typeof replacer !== "object" + || typeof replacer.length !== "number" + )) { + throw new Error("JSON.stringify"); + } + +// Make a fake root object containing our value under the key of "". +// Return the result of stringifying the value. + + return str("", {"": value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== "function") { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k; + var v; + var value = holder[key]; + if (value && typeof value === "object") { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + rx_dangerous.lastIndex = 0; + if (rx_dangerous.test(text)) { + text = text.replace(rx_dangerous, function (a) { + return ( + "\\u" + + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) + ); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with "()" and "new" +// because they can cause invocation, and "=" because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we +// replace all simple value tokens with "]" characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or "]" or +// "," or ":" or "{" or "}". If that is so, then the text is safe for eval. + + if ( + rx_one.test( + text + .replace(rx_two, "@") + .replace(rx_three, "]") + .replace(rx_four, "") + ) + ) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The "{" operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval("(" + text + ")"); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return (typeof reviver === "function") + ? walk({"": j}, "") + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError("JSON.parse"); + }; + } +}()); diff --git a/src/reference/omSettings.json b/src/reference/omSettings.json new file mode 100644 index 0000000..ccb22e1 --- /dev/null +++ b/src/reference/omSettings.json @@ -0,0 +1,246 @@ +({ + "Audio Bit Depth": {type: "int", enums: { + "8 Bit": 1, + "16 Bit": 2, + "32 Bit": 4 + }, + "enums-reverse": { + 1: "8 Bit", + 2: "16 Bit", + 4: "32 Bit" + }, range: [ + 1, + 4 + ] + }, + "Audio Channels": {type: "int", enums: {Mono: 1, Stereo: 2 + }, + "enums-reverse": { + 1: "Mono", + 2: "Stereo" + }, range: [ + 1, + 2 + ] + }, + "Audio Sample Rate": {type: "int", enums: { + "8.000 kHz": 8000, + "11.025 kHz": 11025, + "16.000 kHz": 16000, + "22.050 kHz": 22050, + "24.000 kHz": 24000, + "32.000 kHz": 32000, + "44.100 kHz": 44100, + "48.000 kHz": 48000 + }, + "enums-reverse": { + 8000: "8.000 kHz", + 11025: "11.025 kHz", + 16000: "16.000 kHz", + 22050: "22.050 kHz", + 24000: "24.000 kHz", + 32000: "32.000 kHz", + 44100: "44.100 kHz", + 48000: "48.000 kHz" + }, range: [ + 8000, + 48000 + ] + }, Channels: {type: "int", enums: {RGB: 0, + "RGB + Alpha": 1, Alpha: 2 + }, + "enums-reverse": { + 0: "RGB", + 1: "RGB + Alpha", + 2: "Alpha" + }, range: [ + 0, + 2 + ] + }, Color: {type: "int", enums: { + "Straight (Unmatted)": 0, + "Premultiplied (Matted)": 1 + }, + "enums-reverse": { + 0: "Straight (Unmatted)", + 1: "Premultiplied (Matted)" + }, range: [ + 0, + 1 + ] + }, Crop: {type: "bool" + }, + "Crop Bottom": {type: "int" + }, + "Crop Left": {type: "int" + }, + "Crop Right": {type: "int" + }, + "Crop Top": {type: "int" + }, Depth: {type: "int", enums: { + "Floating Point Gray": -32, + "256 Colors": 8, + "Millions of Colors": 24, + "Millions of Colors+": 32, + "256 Grays": 40, + "Trillions of Colors": 48, + "Trillions of Colors+": 64, + "Floating Point": 96, + "Floating Point+": 128 + }, + "enums-reverse": { + -32: "Floating Point Gray", + 8: "256 Colors", + 24: "Millions of Colors", + 32: "Millions of Colors+", + 40: "256 Grays", + 48: "Trillions of Colors", + 64: "Trillions of Colors+", + 96: "Floating Point", + 128: "Floating Point+" + }, range: [ + -32, + 128 + ] + }, Format: {type: "int", enums: {AIFF: 0, + "DPX/Cineon Sequence": 1, + "H.264": 2, + "IFF Sequence": 3, + "JPEG Sequence": 4, MP3: 5, + "OpenEXR Sequence": 6, + "PNG Sequence": 7, + "Photoshop Sequence": 8, QuickTime: 9, + "Quicktime NotchLC Format": 10, + "Radiance Sequence": 11, + "SGI Sequence": 12, + "TIFF Sequence": 13, + "Targa Sequence": 14, WAV: 15 + }, + "enums-reverse": { + 0: "AIFF", + 1: "DPX/Cineon Sequence", + 2: "H.264", + 3: "IFF Sequence", + 4: "JPEG Sequence", + 5: "MP3", + 6: "OpenEXR Sequence", + 7: "PNG Sequence", + 8: "Photoshop Sequence", + 9: "QuickTime", + 10: "Quicktime NotchLC Format", + 11: "Radiance Sequence", + 12: "SGI Sequence", + 13: "TIFF Sequence", + 14: "Targa Sequence", + 15: "WAV" + }, range: [ + 0, + 15 + ] + }, + "Include Project Link": {type: "bool" + }, + "Include Source XMP Metadata": {type: "bool" + }, + "Lock Aspect Ratio": {type: "bool" + }, + "Output Audio": {type: "int", enums: {Off: 1, On: 2, Auto: 3 + }, + "enums-reverse": { + 1: "Off", + 2: "On", + 3: "Auto" + }, range: [ + 1, + 3 + ] + }, + "Output File Info": {type: { + "Full Flat Path": "string", + "Base Path": "string", + "Subfolder Path": "string", + "File Name": "string", + "File Template": "string" + } + }, + "Post-Render Action": {type: "int", enums: {None: 0, Import: 1, + "Import & Replace Usage": 2, + "Set Proxy": 3 + }, + "enums-reverse": { + 0: "None", + 1: "Import", + 2: "Import & Replace Usage", + 3: "Set Proxy" + }, range: [ + 0, + 3 + ] + }, Resize: {type: "bool" + }, + "Resize Quality": {type: "int", enums: {Low: 0, High: 1 + }, + "enums-reverse": { + 0: "Low", + 1: "High" + }, range: [ + 0, + 1 + ] + }, + "Resize to": {type: "{\"x\": , \"y\": }", enums: { + "Cineon Full \u2022 3656x2664 \u2022 24 fps": "3656,2664", + "Cineon Half \u2022 1828x1332 \u2022 24 fps": "1828,1332", Custom: "x,y", Custom2: "{\"x\": , \"y\": }", Custom3: "[,]", + "DVCPRO HD \u2022 1280x1080 (1.5) \u2022 29.97 fps": "1280,1080", + "DVCPRO HD \u2022 1440x1080 (1.33) \u2022 25 fps": "1440,1080", + "DVCPRO HD \u2022 960x720 (1.33) \u2022 23.976 fps": "960,720", + "DVCPRO HD \u2022 960x720 (1.33) \u2022 25 fps": "960,720", + "DVCPRO HD \u2022 960x720 (1.33) \u2022 29.97 fps": "960,720", + "Film (2K) \u2022 2048x1556 \u2022 24 fps": "2048,1556", + "Film (4K) \u2022 4096x3112 \u2022 24 fps": "4096,3112", + "HD \u2022 1920x1080 \u2022 24 fps": "1920,1080", + "HD \u2022 1920x1080 \u2022 25 fps": "1920,1080", + "HD \u2022 1920x1080 \u2022 29.97 fps": "1920,1080", + "HDV \u2022 1440x1080 (1.33) \u2022 25 fps": "1440,1080", + "HDV \u2022 1440x1080 (1.33) \u2022 29.97 fps": "1440,1080", + "HDV/HDTV \u2022 1280x720 \u2022 25 fps": "1280,720", + "HDV/HDTV \u2022 1280x720 \u2022 29.97 fps": "1280,720", + "Social Media Landscape \u2022 1280x720 \u2022 30 fps": "1280,720", + "Social Media Landscape HD \u2022 1920x1080 \u2022 30 fps": "1920,1080", + "Social Media Portrait \u2022 720x1280 \u2022 30 fps": "720,1280", + "Social Media Portrait HD \u2022 1080x1920 \u2022 30 fps": "1080,1920", + "Social Media Square \u2022 1080x1080 \u2022 30 fps": "1080,1080", + "UHD (4K) \u2022 3840x2160 \u2022 23.976 fps": "3840,2160", + "UHD (4K) \u2022 3840x2160 \u2022 25 fps": "3840,2160", + "UHD (4K) \u2022 3840x2160 \u2022 29.97 fps": "3840,2160", + "UHD (8K) \u2022 7680x4320 \u2022 23.976 fps": "7680,4320" + }, + "enums-reverse": { + "3656,2664": "Cineon Full • 3656x2664 • 24 fps", + "1828,1332": "Cineon Half • 1828x1332 • 24 fps", + "x,y": "Custom", + "{\"x\": , \"y\": }": "Custom2", + "[,]": "Custom3", + "1280,1080": "DVCPRO HD • 1280x1080 (1.5) • 29.97 fps", + "1440,1080": "HDV • 1440x1080 (1.33) • 29.97 fps", + "960,720": "DVCPRO HD • 960x720 (1.33) • 29.97 fps", + "2048,1556": "Film (2K) • 2048x1556 • 24 fps", + "4096,3112": "Film (4K) • 4096x3112 • 24 fps", + "1920,1080": "Social Media Landscape HD • 1920x1080 • 30 fps", + "1280,720": "Social Media Landscape • 1280x720 • 30 fps", + "720,1280": "Social Media Portrait • 720x1280 • 30 fps", + "1080,1920": "Social Media Portrait HD • 1080x1920 • 30 fps", + "1080,1080": "Social Media Square • 1080x1080 • 30 fps", + "3840,2160": "UHD (4K) • 3840x2160 • 29.97 fps", + "7680,4320": "UHD (8K) • 7680x4320 • 23.976 fps" + } + }, + "Starting #": {type: "int" + }, + "Use Comp Frame Number": {type: "bool" + }, + "Use Region of Interest": {type: "bool" + }, + "Video Output": {type: "bool" + } +}) \ No newline at end of file diff --git a/src/reference/rd_GimmePropPath.jsx b/src/reference/rd_GimmePropPath.jsx new file mode 100644 index 0000000..e59a2bf --- /dev/null +++ b/src/reference/rd_GimmePropPath.jsx @@ -0,0 +1,1007 @@ +// rd_GimmePropPath.jsx +// Copyright (c) 2006-2013 redefinery (Jeffrey R. Almasol). All rights reserved. +// check it: www.redefinery.com +// +// Name: rd_GimmePropPath +// Version: 3.0 +// +// Description: +// This script displays the scripting and expression code needed to access +// the selected property or property group. Use this information to +// access the selection correctly in your code. +// +// Select only a single property or property group; selection of some +// properties also select the parent property group, which is fine. +// Selection of multiple properties or property groups at the same +// property depth are not allowed. However, for multiple properties or +// property groups of different depths, the deepest property or property +// group will be used. +// +// You can control the root object used in the generated code, how +// properties and property groups are referenced (and if index numbers +// should be used, when available), and how the composition or layer is +// referenced in the expression code. +// +// The generated scripting and expression code can be copied for use +// in your scripts or expressions. You can also test the generated +// script code to make sure it will access the correct property or +// property group. +// +// Note: If the Root Object = Layer and Expression References = Relative, +// the displayed expression code will work only if it is used on the +// same layer. +// +// Note: For properties such as Custom Value types that cannot +// be targeted via expressions, a "NOT FUNCTIONAL" label will appear +// above the Via Expression area. +// +// Note: This version of the script requires After Effects CS5 +// or later. It can be used as a dockable panel by placing the +// script in a ScriptUI Panels subfolder of the Scripts folder, +// and then choosing this script from the Window menu. +// +// Thanks to Dan Ebberts for the idea for this script and help in +// reviewing it. +// +// Legal stuff: +// This script is provided "as is," without warranty of any kind, expressed +// or implied. In no event shall the author be held liable for any damages +// arising in any way from the use of this script. +// +// In other words, I'm just trying to share knowledge with and help out my +// fellow AE script heads, so don't blame me if my code doesn't rate. :-) + + + + +// rd_GimmePropPath() +// +// Description: +// This function contains the main logic for this script. +// +// Parameters: +// thisObj - "this" object. +// +// Returns: +// Nothing. +// +(function rd_GimmePropPath(thisObj) +{ + // Globals + + var rd_GimmePropPathData = new Object(); // Store globals in an object + rd_GimmePropPathData.scriptName = "rd: Gimme Prop Path"; + rd_GimmePropPathData.scriptTitle = rd_GimmePropPathData.scriptName + " v3.0"; + + rd_GimmePropPathData.lastQueriedProp = null; + + rd_GimmePropPathData.strRootObj = {en: "Root Object:"}; + rd_GimmePropPathData.strRootObjApp = {en: "Application"}; + rd_GimmePropPathData.strRootObjComp = {en: "Composition"}; + rd_GimmePropPathData.strRootObjLayer = {en: "Layer"}; + rd_GimmePropPathData.strRefMode = {en: "Expression References:"}; + rd_GimmePropPathData.strRefModeAbs = {en: "Absolute"}; + rd_GimmePropPathData.strRefModeRel = {en: "Relative"}; + rd_GimmePropPathData.strPropNameRefs = {en: "Properties Referenced By:"}; + rd_GimmePropPathData.strPropNameRefsByMatchName = {en: "Match Name"}; + rd_GimmePropPathData.strPropNameRefsByName = {en: "Name"}; + rd_GimmePropPathData.strPropNameRefsByIndex = {en: "Use index number for group properties"}; + rd_GimmePropPathData.strPropNameCompactEnglish = {en: "Use compact English syntax"}; + rd_GimmePropPathData.strScriptRefs = {en: "Scripting References:"}; + rd_GimmePropPathData.strScriptRefCollapse = {en: "Collapse \".property()\" syntax"}; + rd_GimmePropPathData.strViaScripting = {en: "Via Scripting:"}; + rd_GimmePropPathData.strViaExpression = {en: "Via Expression:"}; + rd_GimmePropPathData.strGetPropPath = {en: "Get Property Path"}; + rd_GimmePropPathData.strTest = {en: "Test"}; + rd_GimmePropPathData.strHelp = {en: "?"}; + rd_GimmePropPathData.strErrNoCompSel = {en: "Cannot perform operation. Please select or open a single composition in the Project window, and try again."}; + rd_GimmePropPathData.strErrNoSinglePropSel = {en: "Cannot perform operation. Please select only one property or property group, and try again."}; + rd_GimmePropPathData.strErrTextScriptCode = {en: "Cannot test script code. Be sure the selected or active composition contains the selected property in the displayed code, and try again."}; + rd_GimmePropPathData.strMinAE100 = {en: "This script requires Adobe After Effects CS5 or later."}; + rd_GimmePropPathData.strErrExprNotFunc = {en: "NOT FUNCTIONAL"}; + rd_GimmePropPathData.strHelpText = + { + en: "Copyright (c) 2006-2013 redefinery (Jeffrey R. Almasol). \n" + + "All rights reserved.\n" + + "\n" + + "This script displays the scripting and expression code needed to access the selected property or property group. Use this information to access the selection correctly in your code.\n" + + "\n" + + "Select only a single property or property group; selection of some properties also select the parent property group, which is fine. Selection of multiple properties or property groups at the same property depth are not allowed. However, for multiple properties or property groups of different depths, the deepest property or property group will be used.\n" + + "\n" + + "You can control the root object used in the generated code, how properties and property groups are referenced (and if index numbers should be used, when available), and how the composition or layer is referenced in the expression code.\n" + + "\n" + + "The generated scripting and expression code can be copied for use in your scripts or expressions. You can also test the generated script code to make sure it will access the correct property or property group.\n" + + "\n" + + "Note: If the Root Object = Layer and Expression References = Relative, the displayed expression code will work only if it is used on the same layer.\n" + + "\n" + + "Note: For properties such as Custom Value types that cannot be targeted via expressions, a \"NOT FUNCTIONAL\" label will appear above the Via Expression area.\n" + + "\n" + + "Note: This version of the script requires After Effects CS5 or later. It can be used as a dockable panel by placing the script in a ScriptUI Panels subfolder of the Scripts folder, and then choosing this script from the Window menu.\n" + + "\n" + + "Thanks to Dan Ebberts for the idea for this script and help in reviewing it." + }; + + // Associative array that converts property match names to their compact English expression statements. + // For simple conversions, quote the result! + // + var propCompactEnglishExprs = + { + "ADBE Transform Group": "'transform'", + // Handle camera/light vs. AV layers + "ADBE Anchor Point": "((prop.propertyGroup(prop.propertyDepth).property('intensity')!=null) || (prop.propertyGroup(prop.propertyDepth).property('zoom')!=null)) ? '.pointOfInterest' : '.anchorPoint'", + "ADBE Position": "'.position'", + "ADBE Scale": "'.scale'", + "ADBE Orientation": "'.orientation'", + "ADBE Rotate X": "'.xRotation'", + "ADBE Rotate Y": "'.yRotation'", + // Handle 3D vs. 2D layers + "ADBE Rotate Z": "(prop.propertyGroup(prop.propertyDepth).threeDLayer || (prop.propertyGroup(prop.propertyDepth).property('intensity')!=null) || (prop.propertyGroup(prop.propertyDepth).property('zoom')!=null)) ? '.zRotation' : '.rotation'", + "ADBE Opacity": "'.opacity'", + + "ADBE Material Options Group": "'materialOption'", + "ADBE Casts Shadows": "'.castsShadows'", + "ADBE Light Transmission": "'.lightTransmission'", + "ADBE Accepts Shadows": "'.acceptsShadows'", + "ADBE Accepts Lights": "'.acceptsLights'", + "ADBE Ambient Coefficient": "'.ambient'", + "ADBE Diffuse Coefficient": "'.diffuse'", + "ADBE Specular Coefficient": "'.specular'", + "ADBE Shininess Coefficient": "'.shininess'", + "ADBE Metal Coefficient": "'.metal'", + + "ADBE Light Options Group": "'lightOption'", + "ADBE Light Intensity": "'.intensity'", + "ADBE Light Color": "'.color'", + "ADBE Light Cone Angle": "'.coneAngle'", + "ADBE Light Cone Feather 2": "'.coneFeather'", + //"ADBE Casts Shadows": "'.castsShadows'", // Already covered previously + "ADBE Light Shadow Darkness": "'.shadowDarkness'", + "ADBE Light Shadow Diffusion": "'.shadowDiffusion'", + + "ADBE Camera Options Group": "'cameraOption'", + "ADBE Camera Zoom": "'.zoom'", + "ADBE Camera Depth of Field": "'.depthOfField'", + "ADBE Camera Focus Distance": "'.focusDistance'", + "ADBE Camera Aperture": "'.aperture'", + "ADBE Camera Blur Level": "'.blurLevel'", + + "ADBE Text Properties": "'text'", + "ADBE Text Document": "'.sourceText'", + "ADBE Text Path Options": "'.pathOption'", + "ADBE Text Path": "'.path'", + "ADBE Text Reverse Path": "'.reversePath'", + "ADBE Text Perpendicular To Path": "'.perpendicularToPath'", + "ADBE Text Force Align Path": "'.forceAlignment'", + "ADBE Text First Margin": "'.firstMargin'", + "ADBE Text Last Margin": "'.lastMargin'", + "ADBE Text More Options": "'.moreOption'", + "ADBE Text Anchor Point Option": "'.anchorPointGrouping'", + "ADBE Text Anchor Point Align": "'.groupingAlignment'", + "ADBE Text Render Order": "'.fillANdStroke'", + "ADBE Text Character Blend Mode": "'.interCharacterBlending'", + + "ADBE Text Animators": "'.animator'", + //"ADBE Text Animator": "''", // No equivalent + "ADBE Text Selectors": "'.selector'", + //"ADBE Text Selector": "''", // No equivalent + "ADBE Text Percent Start": "'.start'", + "ADBE Text Percent End": "'.end'", + "ADBE Text Percent Offset": "'.offset'", + "ADBE Text Index Start": "'.start'", + "ADBE Text Index End": "'.end'", + "ADBE Text Index Offset": "'.offset'", + "ADBE Text Range Advanced": "'.advanced'", + "ADBE Text Range Units": "'.units'", + "ADBE Text Range Type2": "'.basedOn'", + "ADBE Text Selector Mode": "'.mode'", + "ADBE Text Selector Max Amount": "'.amount'", + "ADBE Text Range Shape": "'.shape'", + "ADBE Text Selector Smoothness": "'.smoothness'", + "ADBE Text Levels Max Ease": "'.easeHigh'", + "ADBE Text Levels Min Ease": "'.easeLow'", + "ADBE Text Randomize Order": "'.randomizeOrder'", + "ADBE Text Random Seed": "'.randomSeed'", + //"ADBE Text Wiggly Selector": "''", // No equivalent + "ADBE Text Selector Mode": "'.mode'", + "ADBE Text Wiggly Max Amount": "'.maxAmount'", + "ADBE Text Wiggly Min Amount": "'.minAmount'", + "ADBE Text Range Type2": "'.basedOn'", + "ADBE Text Temporal Freq": "'.wigglesSecond'", + "ADBE Text Character Correlation": "'.correlation'", + "ADBE Text Temporal Phase": "'.temporalPhase'", + "ADBE Text Spatial Phase": "'.spatialPhase'", + "ADBE Text Wiggly Lock Dim": "'.lockDimensions'", + "ADBE Text Wiggly Random Seed": "'.randomSeed'", + //"ADBE Text Expressible Selector": "''", // No equivalent + "ADBE Text Range Type2": "'.basedOn'", + "ADBE Text Expressible Amount": "'.amount'", + "ADBE Text Animator Properties": "'.property'", + "ADBE Text Anchor Point 3D": "'.anchorPoint'", + "ADBE Text Position 3D": "'.position'", + "ADBE Text Scale 3D": "'.scale'", + "ADBE Text Skew": "'.skew'", + "ADBE Text Skew Axis": "'.skewAxis'", + "ADBE Text Rotation X": "'.xRotation'", + "ADBE Text Rotation Y": "'.yRotation'", + "ADBE Text Rotation": "'.zRotation'", + "ADBE Text Opacity": "'.opacity'", + "ADBE Text Fill Opacity": "'.fillOpacity'", + "ADBE Text Fill Color": "'.fillColor'", + "ADBE Text Fill Hue": "'.fillHue'", + "ADBE Text Fill Saturation": "'.fillSaturation'", + "ADBE Text Fill Brightness": "'.fillBrightness'", + "ADBE Text Stroke Opacity": "'.strokeOpacity'", + "ADBE Text Stroke Color": "'.strokeColor'", + "ADBE Text Stroke Hue": "'.strokeHue'", + "ADBE Text Stroke Saturation": "'.strokeSaturation'", + "ADBE Text Stroke Brightness": "'.strokeBrightness'", + "ADBE Text Stroke Width": "'.strokeWidth'", + "ADBE Text Line Anchor": "'.lineAnchor'", + "ADBE Text Line Spacing": "'.lineSpacing'", + "ADBE Text Track Type": "'.trackingType'", + "ADBE Text Tracking Amount": "'.trackingAmount'", + "ADBE Text Character Change Type": "'.characterAlignment'", + "ADBE Text Character Range": "'.characterRange'", + "ADBE Text Character Replace": "'.characterValue'", + "ADBE Text Character Offset": "'.characterOffset'", + "ADBE Text Blur": "'.blur'", + + "ADBE Mask Parade": "'mask'", + "ADBE Mask Shape": "'.maskPath'", + "ADBE Mask Feather": "'.maskFeather'", + "ADBE Mask Opacity": "'.maskOpacity'", + "ADBE Mask Offset": "'.maskExpansion'", + + "ADBE Effect Parade": "'effect'", + + //"ADBE Paint": "''", + //"ADBE Paint On Transparent": "''", + "ADBE Paint Group": "'.stroke'", + //"ADBE Paint Atom": "''", + //"ADBE Paint Transfer Mode": "''", + //"ADBE Paint Duration": "''", + "ADBE Paint Shape": "'.path'", + "ADBE Paint Properties": "'.strokeOption'", + "ADBE Paint Begin": "'.start'", + "ADBE Paint End": "'.end'", + "ADBE Paint Color": "'.color'", + "ADBE Paint Diameter": "'.diameter'", + "ADBE Paint Angle": "'.angle'", + "ADBE Paint Hardness": "'.hardness'", + "ADBE Paint Roundness": "'.roundness'", + "ADBE Paint Tip Spacing": "'.spacing'", + "ADBE Paint Target Channels": "'.channels'", + "ADBE Paint Opacity": "'.opacity'", + "ADBE Paint Flow": "'.flow'", + "ADBE Paint Clone Layer": "'.cloneSource'", + "ADBE Paint Clone Position": "'.clonePosition'", + "ADBE Paint Clone Time": "'.cloneTime'", + "ADBE Paint Clone Time Shift": "'.cloneTimeShift'", + //"ADBE Paint Clone Source Type": "''", + "ADBE Paint Transform": "'.transform'", + "ADBE Paint Anchor Point": "'.anchorPoint'", + "ADBE Paint Position": "'.position'", + "ADBE Paint Scale": "'.scale'", + "ADBE Paint Rotation": "'.rotation'", + //"ADBE Paint Nibbler Group": "''", + + "ADBE MTrackers": "'motionTracker'", + "ADBE MTracker Pt Feature Center": "'.featureCenter'", + "ADBE MTracker Pt Feature Size": "'.featureSize'", + "ADBE MTracker Pt Search Ofst": "'.searchOffset'", + "ADBE MTracker Pt Search Size": "'.searchSize'", + "ADBE MTracker Pt Confidence": "'.confidence'", + "ADBE MTracker Pt Attach Pt": "'.attachPoint'", + "ADBE MTracker Pt Attach Pt Ofst": "'.attachPointOffset'", + + "ADBE Audio Group": "'audio'", + "ADBE Audio Levels": "'.audioLevels'", + + "ADBE Time Remapping": "'timeRemap'", + + "ADBE Layer Styles": "'layerStyle'", + "ADBE Blend Options Group": "'.blendingOption'", + "ADBE Global Angle2": "'.globalLightAngle'", + "ADBE Global Altitude2": "'.globalLightAltitude'", + "ADBE Adv Blend Group": "'.advancedBlending'", + "ADBE Layer Fill Opacity2": "'.fillOpacity'", + "ADBE R Channel Blend": "'.red'", + "ADBE G Channel Blend": "'.green'", + "ADBE B Channel Blend": "'.blue'", + "ADBE Blend Interior": "'.blendInteriorStylesAsGroup'", + "ADBE Blend Ranges": "'.useBlendRangesFromSource'", + "dropShadow/enabled": "'.dropShadow'", + "dropShadow/mode2": "'.blendMode'", + "dropShadow/color": "'.color'", + "dropShadow/opacity": "'.opacity'", + "dropShadow/useGlobalAngle": "'.useGlobalLight'", + "dropShadow/localLightingAngle": "'.angle'", + "dropShadow/distance": "'.distance'", + "dropShadow/chokeMatte": "'.spread'", + "dropShadow/blur": "'.size'", + "dropShadow/noise": "'.noise'", + "dropShadow/layerConceals": "'.layerKnocksOutDropShadow'", + "innerShadow/enabled": "'.innerShadow'", + "innerShadow/mode2": "'.blendMode'", + "innerShadow/color": "'.color'", + "innerShadow/opacity": "'.opacity'", + "innerShadow/useGlobalAngle": "'.useGlobalLight'", + "innerShadow/localLightingAngle": "'.angle'", + "innerShadow/distance": "'.distance'", + "innerShadow/chokeMatte": "'.choke'", + "innerShadow/blur": "'.size'", + "innerShadow/noise": "'.noise'", + "outerGlow/enabled": "'.outerGlow'", + "outerGlow/mode2": "'.blendMode'", + "outerGlow/opacity": "'.opacity'", + "outerGlow/noise": "'.noise'", + "outerGlow/AEColorChoice": "'.colorType'", + "outerGlow/color": "'.color'", + //"outerGlow/gradient": "'.'", // No equivalent + "outerGlow/gradientSmoothness": "'.gradientSmoothness'", + "outerGlow/glowTechnique": "'.technique'", + "outerGlow/chokeMatte": "'.spread'", + "outerGlow/blur": "'.size'", + "outerGlow/inputRange": "'.range'", + "outerGlow/shadingNoise": "'.jitter'", + "innerGlow/enabled": "'.innerGlow'", + "innerGlow/mode2": "'.blendMode'", + "innerGlow/opacity": "'.opacity'", + "innerGlow/noise": "'.noise'", + "innerGlow/AEColorChoice": "'.colorType'", + "innerGlow/color": "'.color'", + //"innerGlow/gradient": "'.'", // No equivalent + "innerGlow/gradientSmoothness": "'.gradientSmoothness'", + "innerGlow/glowTechnique": "'.technique'", + "innerGlow/innerGlowSource": "'.source'", + "innerGlow/chokeMatte": "'.choke'", + "innerGlow/blur": "'.size'", + "innerGlow/inputRange": "'.range'", + "innerGlow/shadingNoise": "'.jitter'", + "bevelEmboss/enabled": "'.bevelAndEmboss'", + "bevelEmboss/bevelStyle": "'.style'", + "bevelEmboss/bevelTechnique": "'.technique'", + "bevelEmboss/strengthRatio": "'.depth'", + "bevelEmboss/bevelDirection": "'.direction'", + "bevelEmboss/blur": "'.size'", + "bevelEmboss/softness": "'.soften'", + "bevelEmboss/useGlobalAngle": "'.useGlobalLight'", + "bevelEmboss/localLightingAngle": "'.angle'", + "bevelEmboss/localLightingAltitude": "'.altitude'", + "bevelEmboss/highlightMode": "'.highlightMode'", + "bevelEmboss/highlightColor": "'.highlightColor'", + "bevelEmboss/highlightOpacity": "'.highlightOpacity'", + "bevelEmboss/shadowMode": "'.shadowMode'", + "bevelEmboss/shadowColor": "'.shadowColor'", + "bevelEmboss/shadowOpacity": "'.shadowOpacity'", + "chromeFX/enabled": "'.satin'", + "chromeFX/mode2": "'.blendMode'", + "chromeFX/color": "'.color'", + "chromeFX/opacity": "'.opacity'", + "chromeFX/localLightingAngle": "'.angle'", + "chromeFX/distance": "'.distance'", + "chromeFX/blur": "'.size'", + "chromeFX/invert": "'.invert'", + "solidFill/enabled": "'.colorOverlay'", + "solidFill/mode2": "'.blendMode'", + "solidFill/color": "'.color'", + "solidFill/opacity": "'.opacity'", + "gradientFill/enabled": "'.gradientOverlay'", + "gradientFill/mode2": "'.blendMode'", + "gradientFill/opacity": "'.opacity'", + //"gradientFill/gradient": "'.'", // No equivalent + "gradientFill/gradientSmoothness": "'.gradientSmoothness'", + "gradientFill/angle": "'.angle'", + "gradientFill/type": "'.style'", + "gradientFill/reverse": "'.reverse'", + "gradientFill/align": "'.alignWithLayer'", + "gradientFill/scale": "'.scale'", + "gradientFill/offset": "'.offset'", + "patternFill/enabled": "'.patternOverlay'", + "patternFill/mode2": "'.blendMode'", + "patternFill/opacity": "'.opacity'", + "patternFill/align": "'.linkWithLayer'", + "patternFill/scale": "'.scale'", + "patternFill/phase": "'.offset'", + "frameFX/enabled": "'.stroke'", + "frameFX/mode2": "'.blendMode'", + "frameFX/color": "'.color'", + "frameFX/size": "'.size'", + "frameFX/opacity": "'.opacity'", + "frameFX/style": "'.position'", + }; + + // Array that converts property match names to their compact English scripting statements. + // + var propCompactEnglishScriptingExprs = + { + "ADBE Text Animator Properties": "", + }; + + + + + // rd_GimmePropPath_localize() + // + // Description: + // This function localizes the given string variable based on the current locale. + // + // Parameters: + // strVar - The string variable's name. + // + // Returns: + // String. + // + function rd_GimmePropPath_localize(strVar) + { + return strVar["en"]; + } + + + + + // rd_GimmePropPath_buildUI() + // + // Description: + // This function builds the user interface. + // + // Parameters: + // thisObj - Panel object (if script is launched from Window menu); null otherwise. + // + // Returns: + // Window or Panel object representing the built user interface. + // + function rd_GimmePropPath_buildUI(thisObj) + { + var pal = (thisObj instanceof Panel) ? thisObj : new Window("palette", rd_GimmePropPathData.scriptName, undefined, {resizeable:true}); + + if (pal !== null) + { + var res = + "group { \ + orientation:'column', alignment:['fill','fill'], \ + header: Group { \ + alignment:['fill','top'], \ + title: StaticText { text:'" + rd_GimmePropPathData.scriptName + "', alignment:['fill','center'] }, \ + help: Button { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strHelp) +"', maximumSize:[30,20], alignment:['right','center'] }, \ + }, \ + rootObj: Group { \ + alignment:['fill','top'], alignChildren:['left','center'], \ + lbl: StaticText { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRootObj) + "' }, \ + rootObjApp: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRootObjApp) + "', value:true }, \ + rootObjComp: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRootObjComp) + "' }, \ + rootObjLayer: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRootObjLayer) + "' }, \ + }, \ + propNameRefs: Group { \ + alignment:['fill','top'], alignChildren:['left','center'], \ + lbl: StaticText { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strPropNameRefs) + "' }, \ + propNameRefsByMatchName: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strPropNameRefsByMatchName) + "' }, \ + propNameRefsByName: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strPropNameRefsByName) + "', value:true }, \ + }, \ + propNameOpts: Group { \ + orientation:'column', alignment:['left','top'], alignChildren:['left','top'], spacing:5, \ + propNameRefsByIndex: Checkbox { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strPropNameRefsByIndex) + "' }, \ + propNameCompactEnglish: Checkbox { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strPropNameCompactEnglish) + "' }, \ + }, \ + scriptRefMode: Group { \ + alignment:['fill','top'], alignChildren:['left','center'], \ + lbl: StaticText { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strScriptRefs) + "' }, \ + scriptRefCollapse: Checkbox { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strScriptRefCollapse) + "' }, \ + }, \ + refMode : Group { \ + alignment:['fill','top'], alignChildren:['left','bottom'], \ + lbl: StaticText { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRefMode) + "' }, \ + refModeAbs: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRefModeAbs) + "', value:true }, \ + refModeRel: RadioButton { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strRefModeRel) + "' }, \ + }, \ + viaScript : Group { \ + orientation:'column', alignment:['fill','fill'], spacing:5, \ + heading: Group { \ + alignment:['fill','top'], \ + lbl: StaticText { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strViaScripting) + "', alignment:['left','bottom'] }, \ + viaScriptCodeTest: Button { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strTest) + "', enabled:false, alignment:['right','bottom'], preferredSize:[-1,20] }, \ + }, \ + viaScriptCode: EditText { text:'', properties:{'multiline':true}, alignment:['fill','fill'], minimumSize:[100,20] }, \ + }, \ + viaExpr : Group { \ + orientation:'column', alignment:['fill','fill'], spacing:5, \ + heading: Group { \ + alignment:['fill','top'], \ + lbl: StaticText { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strViaExpression) + "', alignment:['fill','bottom'] }, \ + viaExprMsg: StaticText { text:'', alignment:['right','bottom'], characters:15 }, \ + }, \ + viaExprCode: EditText { text:'', properties:{'multiline':true}, alignment:['fill','fill'], minimumSize:[100,20] }, \ + }, \ + cmds: Group { \ + alignment:['fill','bottom'], \ + getPropPathBtn: Button { text:'" + rd_GimmePropPath_localize(rd_GimmePropPathData.strGetPropPath) + "', alignment:['right','top'], preferredSize:[-1,20] }, \ + }, \ + } \ + "; + pal.grp = pal.add(res); + + pal.grp.rootObj.lbl.preferredSize = + pal.grp.scriptRefMode.lbl.preferredSize = + pal.grp.refMode.lbl.preferredSize = pal.grp.propNameRefs.lbl.preferredSize; + pal.grp.rootObj.rootObjApp.preferredSize = + pal.grp.refMode.refModeAbs.preferredSize = pal.grp.propNameRefs.propNameRefsByMatchName.preferredSize; + pal.grp.propNameRefs.margins.top = + pal.grp.scriptRefMode.margins.top = 5; + pal.grp.propNameOpts.indent = pal.grp.rootObj.lbl.preferredSize.width + pal.grp.rootObj.spacing; + + pal.layout.layout(true); + pal.grp.minimumSize = pal.grp.size; + pal.layout.resize(); + pal.onResizing = pal.onResize = function () {this.layout.resize();} + + pal.grp.rootObj.rootObjApp.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.rootObj.rootObjComp.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.rootObj.rootObjLayer.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.propNameRefs.propNameRefsByMatchName.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.propNameRefs.propNameRefsByName.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.propNameOpts.propNameRefsByIndex.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.propNameOpts.propNameCompactEnglish.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.scriptRefMode.scriptRefCollapse.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.refMode.refModeAbs.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.refMode.refModeRel.onClick = function () {rd_GimmePropPath_buildPropPath(this.parent.parent.parent);} + pal.grp.viaScript.heading.viaScriptCodeTest.onClick = function () + { + if (this.parent.parent.viaScriptCode.text !== "") + { + var code = this.parent.parent.viaScriptCode.text; + + // Check if code is using composition or layer as the root object, and adjust accordingly so that the test will work + if (code[0] === "i") // Comp-relative (starts with "item") + code = "app.project." + code; + else if (code[0] === "l") // Layer-relative (starts with "layer") + { + var compItemNum = rd_GimmePropPath_findCompItemNum(app.project.activeItem); + if (compItemNum === 0) + { + alert(rd_GimmePropPath_localize(rd_GimmePropPathData.strErrTextScriptCode), rd_GimmePropPathData.scriptName); + return; + } + + code = "app.project.item(" + compItemNum + ")." + code; + } + + // Evaluate the script code + code = "var prop = " + code + "; if ((prop.propertyType === PropertyType.PROPERTY) && (prop.propertyValueType !== PropertyValueType.CUSTOM_VALUE)) alert(prop.name+\" = \"+prop.value.toString()); else alert(prop.name);"; + try + { + eval(code); + } + catch (e) + { + alert(e.toString() + "\n\n" + rd_GimmePropPath_localize(rd_GimmePropPathData.strErrTextScriptCode), rd_GimmePropPathData.scriptName); + } + } + } + + pal.grp.header.help.onClick = function () {alert(rd_GimmePropPathData.scriptTitle + "\n" + rd_GimmePropPath_localize(rd_GimmePropPathData.strHelpText), rd_GimmePropPathData.scriptName);} + pal.grp.cmds.getPropPathBtn.onClick = rd_GimmePropPath_doGetPropPath; + } + + return pal; + } + + + + + // rd_GimmePropPath_findCompItemNum() + // + // Description: + // This function determines the item number for the specified composiiton + // in the Project window. This number is used for accessing the composition + // via scripting. + // + // Parameters: + // comp - Composition object. + // + // Returns: + // Number representing the item number for the composition; or 0 if + // the composition item number cannot be identified. + // + function rd_GimmePropPath_findCompItemNum(comp) + { + var itemNum = 0, item; + + for (var i=1; i<=app.project.numItems; i++) + { + item = app.project.item(i); + if ((item instanceof CompItem) && (item === comp)) + { + itemNum = i; + break; + } + } + + return itemNum; + } + + + + + // rd_GimmePropPath_buildPropPath() + // + // Description: + // This function assembles the scripting and expression code for accessing + // the current (or last queried) property, updating the appropriate UI + // fields. + // + // Parameters: + // pal - Window or Panel object, representing the palette. + // + // Returns: + // Nothing. + // + function rd_GimmePropPath_buildPropPath(pal) + { + // rd_GimmePropPath_getPropCompactEnglishExpr() + // + // Description: + // This function looks up the specified property's compact English + // expression statement in the propCompactEnglishExprs associative + // array, if available. + // + // Parameters: + // prop - Property or PropertyGroup object. + // matchName - String representing the property's match name to + // use for lookup; in AE 6.5, this is overridden with the + // property's name. + // name - String representing the existing translation of the + // property name. + // + // Returns: + // String representing the compact English equivalent, if available. + // + function rd_GimmePropPath_getPropCompactEnglishExpr(prop, matchName, name) + { + var translatedName = propCompactEnglishExprs[matchName]; + + if (translatedName !== undefined) + return eval(translatedName); + else + return ("(" + name + ")"); + } + + + // rd_GimmePropPath_getPropCompactEnglishScriptExpr() + // + // Description: + // This function determines if the specified property has special + // naming when used via Scripting. Otherwise, it'll use the same + // as for expressions. + // + // Parameters: + // prop - Property or PropertyGroup object. + // matchName - String representing the property's match name to + // use for lookup. + // name - String representing the existing translation of the + // property name. + // + // Returns: + // String representing the compact English equivalent for Scripting, if available. + // + function rd_GimmePropPath_getPropCompactEnglishScriptExpr(prop, matchName, name) + { + var translatedName = propCompactEnglishScriptingExprs[matchName]; + + if (translatedName === undefined) + return rd_GimmePropPath_getPropCompactEnglishExpr(prop, matchName, name); + else + return ("(" + name + ")"); + } + + + var currProp = rd_GimmePropPathData.lastQueriedProp; + + if (currProp === null) + return; + + // Get the preferred root object, and set a value representing it + var rootObj; + if (pal.grp.rootObj.rootObjApp.value) + rootObj = 8; + else if (pal.grp.rootObj.rootObjComp.value) + rootObj = 6; + else if (pal.grp.rootObj.rootObjLayer.value) + rootObj = 4; + + var scriptRefCollapse = pal.grp.scriptRefMode.scriptRefCollapse.value; + var refModeAbs = pal.grp.refMode.refModeAbs.value; + var propNameRefsByMatchName = pal.grp.propNameRefs.propNameRefsByMatchName.value; + var propNameRefsByName = pal.grp.propNameRefs.propNameRefsByName.value; + var propNameRefsByIndex = pal.grp.propNameOpts.propNameRefsByIndex.value; + var propNameCompactEnglish = pal.grp.propNameOpts.propNameCompactEnglish.value; + + // Traverse up the property tree from the current property, until reaching the layer + var scriptCode = "", exprCode = ""; + var name, compactName, compactScriptName; + + while (currProp.parentProperty !== null) + { + // Reference by property index + if ((currProp.parentProperty.propertyType === PropertyType.INDEXED_GROUP) && propNameRefsByIndex) + name = currProp.propertyIndex; + else + { + // Reference by match name or name + if (propNameRefsByMatchName) // && (currProp.parentProperty.propertyType === PropertyType.NAMED_GROUP)) + name = "\"" + ((currProp.matchName !== "") ? currProp.matchName : currProp.name) + "\""; + else + name = "\"" + currProp.name + "\""; + } + + //alert('"'+currProp.name+'" = "'+currProp.matchName+'"; name="'+name+'", exprCode="'+exprCode+'"'); + + // For compact English conversion, check for compact English equivalent + if (propNameCompactEnglish) + { + compactName = rd_GimmePropPath_getPropCompactEnglishExpr(currProp, currProp.matchName, name); + compactScriptName = rd_GimmePropPath_getPropCompactEnglishScriptExpr(currProp, currProp.matchName, name); + + scriptCode = compactScriptName + scriptCode; + exprCode = compactName + exprCode; + } + else + { + scriptCode = (scriptRefCollapse ? "" : ".property") + "(" + name + ")" + scriptCode; + exprCode = "(" + name + ")" + exprCode; + } + + // Traverse up the property tree + currProp = currProp.parentProperty; + } + + // Prefix the layer reference, if requested + if (rootObj >= 4) // Root Object = Layer + { + name = (propNameRefsByIndex) ? currProp.index : "\"" + currProp.name + "\""; + + if (propNameCompactEnglish) + { + // If the sub-layer property is a property group, add the missing period + scriptCode = "layer(" + name + ")" + (((currProp !== null) && (currProp.propertyType !== PropertyType.PROPERTY)) ? "." : "") + scriptCode; + + if (rootObj > 4) + exprCode = "layer(" + name + ")." + exprCode; + else + exprCode = "thisLayer." + exprCode; + } + else + { + scriptCode = "layer(" + name + ")" + scriptCode; + + if (refModeAbs || (rootObj > 4)) + exprCode = "layer(" + name + ")" + exprCode; + else + exprCode = "thisLayer" + exprCode; + } + } + + // Prefix the comp reference, if requested + if (rootObj >= 6) // Root Object = Comp + { + // Determine the comp's item number in the Project window + var compItemNum = rd_GimmePropPath_findCompItemNum(app.project.activeItem); + //alert("item# "+compItemNum); + + scriptCode = "item(" + compItemNum + ")." + scriptCode; + if (refModeAbs) + exprCode = "comp(\"" + app.project.activeItem.name + "\")." + exprCode; + else + exprCode = "thisComp." + exprCode; + } + + // Prefix the application and project references, if requested, for the script code + if (rootObj >= 8) // Root Object = Application + scriptCode = "app.project." + scriptCode; + + // Update the code fields + pal.grp.viaScript.viaScriptCode.text = scriptCode; + pal.grp.viaExpr.viaExprCode.text = exprCode; + } + + + + + // rd_GimmePropPath_doGetPropPath() + // + // Description: + // This callback function retrieves the currently selected property or property + // group, and displays the corresponding scripting and expression code to + // access it. + // + // Parameters: + // None. + // + // Returns: + // Nothing. + // + function rd_GimmePropPath_doGetPropPath() + { + // rd_GimmePropPath_findDeepestSelectedProp() + // + // Description: + // This function determines the deepest selected property or property group. + // Assumes a single composition is selected or active. + // + // Parameters: + // None + // + // Returns: + // Property or PropertyGroup object if successful; null if no property or + // property group, or if multiple of them, are selected. + // + function rd_GimmePropPath_findDeepestSelectedProp() + { + var comp = app.project.activeItem; + var deepestProp, numDeepestProps = 0, deepestPropDepth = 0; + var prop; + + for (var i=0; i= deepestPropDepth) + { + if (prop.propertyDepth > deepestPropDepth) + numDeepestProps = 0; + deepestProp = prop; + numDeepestProps++; + deepestPropDepth = prop.propertyDepth; + } + else + continue; + } + + return (numDeepestProps > 1) ? null : deepestProp; + } + + + var prop; + var rootObj; + + // Check that a single comp is selected or active + if ((app.project.activeItem === null) || !(app.project.activeItem instanceof CompItem)) + { + alert(rd_GimmePropPath_localize(rd_GimmePropPathData.strErrNoCompSel), rd_GimmePropPathData.scriptName); + return; + } + + // Check that a single deep property is selected + prop = rd_GimmePropPath_findDeepestSelectedProp(); + if (prop === null) + { + alert(rd_GimmePropPath_localize(rd_GimmePropPathData.strErrNoSinglePropSel), rd_GimmePropPathData.scriptName); + return; + } + rd_GimmePropPathData.lastQueriedProp = prop; + + //alert("deepest prop/group = '"+prop.name+"' (depth="+prop.propertyDepth+")"); + + // Enable the Test button + this.parent.parent.viaScript.heading.viaScriptCodeTest.enabled = true; + + // Check if expression is usable + if ((prop.propertyType === PropertyType.PROPERTY) && (prop.propertyValueType === PropertyValueType.CUSTOM_VALUE)) + this.parent.parent.viaExpr.heading.viaExprMsg.text = rd_GimmePropPath_localize(rd_GimmePropPathData.strErrExprNotFunc); + else + this.parent.parent.viaExpr.heading.viaExprMsg.text = ""; + + // Build the property path + rd_GimmePropPath_buildPropPath(this.parent.parent.parent); + } + + + + + // main code: + // + + // Prerequisites check + if (parseFloat(app.version) < 10.0) + alert(rd_GimmePropPath_localize(rd_GimmePropPathData.strMinAE100), rd_GimmePropPathData.scriptName); + else + { + // Build and show the palette + var rdgppPal = rd_GimmePropPath_buildUI(thisObj); + if (rdgppPal !== null) + { + // Update UI values, if saved in the settings + if (app.settings.haveSetting("redefinery", "rd_GimmePropPath_rootObj")) + { + switch (app.settings.getSetting("redefinery", "rd_GimmePropPath_rootObj")) + { + case "app": + rdgppPal.grp.rootObj.rootObjApp.value = true; + break; + case "comp": + rdgppPal.grp.rootObj.rootObjComp.value = true; + break; + case "layer": + rdgppPal.grp.rootObj.rootObjLayer.value = true; + break; + default: + break; + } + } + if (app.settings.haveSetting("redefinery", "rd_GimmePropPath_propRefsBy")) + { + switch (app.settings.getSetting("redefinery", "rd_GimmePropPath_propRefsBy")) + { + case "matchName": + rdgppPal.grp.propNameRefs.propNameRefsByMatchName.value = true; + break; + case "name": + rdgppPal.grp.propNameRefs.propNameRefsByName.value = true; + break; + default: + break; + } + } + if (app.settings.haveSetting("redefinery", "rd_GimmePropPath_propRefsByIndex")) + rdgppPal.grp.propNameOpts.propNameRefsByIndex.value = (app.settings.getSetting("redefinery", "rd_GimmePropPath_propRefsByIndex") === "false") ? false : true; + if (app.settings.haveSetting("redefinery", "rd_GimmePropPath_propNameCompactEnglish")) + rdgppPal.grp.propNameOpts.propNameCompactEnglish.value = (app.settings.getSetting("redefinery", "rd_GimmePropPath_propNameCompactEnglish") === "false") ? false : true; + if (app.settings.haveSetting("redefinery", "rd_GimmePropPath_scriptRefCollapse")) + rdgppPal.grp.scriptRefMode.scriptRefCollapse.value = (app.settings.getSetting("redefinery", "rd_GimmePropPath_scriptRefCollapse") === "false") ? false : true; + + if (app.settings.haveSetting("redefinery", "rd_GimmePropPath_exprRefMode")) + { + switch (app.settings.getSetting("redefinery", "rd_GimmePropPath_exprRefMode")) + { + case "abs": + rdgppPal.grp.refMode.refModeAbs.value = true; + break; + case "rel": + rdgppPal.grp.refMode.refModeRel.value = true; + break; + default: + break; + } + } + + // Save current UI settings upon closing the palette + rdgppPal.onClose = function() + { + var value = ""; + if (rdgppPal.grp.rootObj.rootObjApp.value) + value = "app"; + else if (rdgppPal.grp.rootObj.rootObjComp.value) + value = "comp"; + else if (rdgppPal.grp.rootObj.rootObjLayer.value) + value = "layer"; + app.settings.saveSetting("redefinery", "rd_GimmePropPath_rootObj", value); + + value = ""; + if (rdgppPal.grp.propNameRefs.propNameRefsByMatchName.value) + value = "matchName"; + else if (rdgppPal.grp.propNameRefs.propNameRefsByName.value) + value = "name"; + app.settings.saveSetting("redefinery", "rd_GimmePropPath_propRefsBy", value); + + app.settings.saveSetting("redefinery", "rd_GimmePropPath_propRefsByIndex", rdgppPal.grp.propNameOpts.propNameRefsByIndex.value); + app.settings.saveSetting("redefinery", "rd_GimmePropPath_propNameCompactEnglish", rdgppPal.grp.propNameOpts.propNameCompactEnglish.value); + app.settings.saveSetting("redefinery", "rd_GimmePropPath_scriptRefCollapse", rdgppPal.grp.scriptRefMode.scriptRefCollapse.value); + + value = ""; + if (rdgppPal.grp.refMode.refModeAbs.value) + value = "abs"; + else if (rdgppPal.grp.refMode.refModeRel.value) + value = "rel"; + app.settings.saveSetting("redefinery", "rd_GimmePropPath_exprRefMode", value); + } + + if (rdgppPal instanceof Window) + { + // Show the palette + rdgppPal.center(); + rdgppPal.show(); + } + else + rdgppPal.layout.layout(true); + } + } +})(this); diff --git a/src/reference/renderSettings.json b/src/reference/renderSettings.json new file mode 100644 index 0000000..aa4e08d --- /dev/null +++ b/src/reference/renderSettings.json @@ -0,0 +1,202 @@ +( +{ + "3:2 Pulldown": {type: "int", enums: {Off: 0, WSSWW: 1, SSWWW: 2, SWWWS: 3, WWWSS: 4, WWSSW: 5 + }, + "enums-reverse": { + 0: "Off", + 1: "WSSWW", + 2: "SSWWW", + 3: "SWWWS", + 4: "WWWSS", + 5: "WWSSW" + }, range: [ + 0, + 5 + ] + }, + "Color Depth": {type: "int", enums: { + "Current Settings": -1, + "8 bits per channel": 0, + "16 bits per channel": 1, + "32 bits per channel": 2 + }, + "enums-reverse": { + -1: "Current Settings", + 0: "8 bits per channel", + 1: "16 bits per channel", + 2: "32 bits per channel" + }, range: [ + -1, + 2 + ] + }, + "Disk Cache": {type: "int", enums: { + "Read Only": 0, + "Current Settings": 2 + }, + "enums-reverse": { + 0: "Read Only", + 2: "Current Settings" + }, range: [ + 0, + 2 + ] + }, Effects: {type: "int", enums: { + "All Off": 0, + "All On": 1, + "Current Settings": 2 + }, + "enums-reverse": { + 0: "All Off", + 1: "All On", + 2: "Current Settings" + }, range: [ + 0, + 2 + ] + }, + "Field Render": {type: "int", enums: {Off: 0, + "Upper Field First": 1, + "Lower Field First": 2 + }, + "enums-reverse": { + 0: "Off", + 1: "Upper Field First", + 2: "Lower Field First" + }, range: [ + 0, + 2 + ] + }, + "Frame Blending": {type: "int", enums: { + "Off for All Layers": 0, + "On for Checked Layers": 1, + "Current Settings": 2 + }, + "enums-reverse": { + 0: "Off for All Layers", + 1: "On for Checked Layers", + 2: "Current Settings" + }, range: [ + 0, + 2 + ] + }, + "Frame Rate": {type: "int", enums: { + "Use comp's frame rate": 0, + "Use this frame rate": 1 + }, + "enums-reverse": { + 0: "Use comp's frame rate", + 1: "Use this frame rate" + }, range: [ + 0, + 1 + ] + }, + "Guide Layers": {type: "int", enums: { + "All Off": 0, + "Current Settings": 2 + }, + "enums-reverse": { + 0: "All Off", + 2: "Current Settings" + }, range: [ + 0, + 2 + ] + }, + "Motion Blur": {type: "int", enums: { + "Off for All Layers": 0, + "On for Checked Layers": 1, + "Current Settings": 2 + }, + "enums-reverse": { + 0: "Off for All Layers", + 1: "On for Checked Layers", + 2: "Current Settings" + }, range: [ + 0, + 2 + ] + }, + "Proxy Use": {type: "int", enums: { + "Use No Proxies": 0, + "Use All Proxies": 1, + "Current Settings": 2, + "Use Comp Proxies Only": 3 + }, + "enums-reverse": { + 0: "Use No Proxies", + 1: "Use All Proxies", + 2: "Current Settings", + 3: "Use Comp Proxies Only" + }, range: [ + 0, + 3 + ] + }, Quality: {type: "int", enums: { + "Current Settings": -1, Wireframe: 0, Draft: 1, Best: 2 + }, + "enums-reverse": { + -1: "Current Settings", + 0: "Wireframe", + 1: "Draft", + 2: "Best" + }, range: [ + -1, + 2 + ] + }, Resolution: {type: "{\"x\": , \"y\": }", enums: { + "Current Settings": "0,0", Custom: "x,y", Custom2: "{\"x\": , \"y\": }", Custom3: "[,]", Full: "1,1", Half: "2,2", Quarter: "4,4", Third: "3,3" + }, + "enums-reverse": { + "0,0": "Current Settings", + "x,y": "Custom", + "{\"x\": , \"y\": }": "Custom2", + "[,]": "Custom3", + "1,1": "Full", + "2,2": "Half", + "4,4": "Quarter", + "3,3": "Third" + } + }, + "Skip Existing Files": {type: "bool" + }, + "Solo Switches": {type: "int", enums: { + "All Off": 0, + "Current Settings": 2 + }, + "enums-reverse": { + 0: "All Off", + 2: "Current Settings" + }, range: [ + 0, + 2 + ] + }, + "Time Span": {type: "int", enums: { + "Length of Comp": 0, + "Work Area Only": 1, Custom: 2 + }, + "enums-reverse": { + 0: "Length of Comp", + 1: "Work Area Only", + 2: "Custom" + }, range: [ + 0, + 2 + ] + }, + "Time Span Duration": {type: "double" + }, + "Time Span End": {type: "double" + }, + "Time Span Start": {type: "double" + }, + "Use comp's frame rate": {type: "double" + }, + "Use this frame rate": {type: "double" + } +} +) \ No newline at end of file diff --git a/src/scripts/km-expression-reference.jsx b/src/scripts/km-expression-reference.jsx new file mode 100644 index 0000000..e029134 --- /dev/null +++ b/src/scripts/km-expression-reference.jsx @@ -0,0 +1,106 @@ +/** + * @description a script wiyh a UI that will do something really cool in AE + * @name km-scriptname + * @author Kyle Harter + * @version 1.0.0 + * + * @license This script is provided "as is," without warranty of any kind, expressed or implied. In + * no event shall the author be held liable for any damages arising in any way from the use of this + * script. + * + * + * + * +*/ + + +(function(thisObj){ + + //@include "../library/km_helperFunctions.jsx"; + //@include "../library/km_scriptUI_functions.jsx"; + //@include "../library/km_utilityFunctions.jsx"; + //@include "../library/km_textAnimators.jsx"; + //@include "../library/km_systemFunctions.jsx"; + + var scriptName = "Script Name"; + + createUI(thisObj) + + function createUI(thisObj){ + var win = thisObj instanceof Panel + ? thisObj + : new Window("window", scriptName, undefined, { + resizeable: true + }) + + win.orientation = 'column'; + win.alignChildren = ["left", "top"]; + + var mainGroup = win.add("group", undefined, "Main Group"); + mainGroup.orientation = 'column'; + + var applyGroup = mainGroup.add("group", undefined, "Apply Group"); + applyGroup.orientation = 'row'; + var applyButton = applyGroup.add("button", undefined, "Apply"); + applyButton.preferredSize = [-1,30]; + applyButton.helpTip = "Click: Apply markers to selected layers.\rShift+Click: Apply markers to beginning of a comp." + + + applyButton.onClick = function(){ + try { + app.beginUndoGroup("What script does"); + + var km = kmFunction; + var kmScript = kmScriptUI; + var kmUtils = kmUtilityFunctions; + var kmTextAnims = KMTextAnimatorsLib; + + var comp = km.getActiveComp(app.project); + var selLayers = km.getSelectedLayers(comp); + var selProp = km.getSelectedProperties(selLayers)[0]; + + alert(getPropertyPath(selLayers[0],selProp)) + + } catch(error) { + alert("An error occured on line: " + error.line + "\nError message: " + error.message); + } finally { + // this always runs no matter what + app.endUndoGroup() + } + + } + + + function getPropertyPath(layer,selProp){ + var propDepth = selProp.propertyDepth; + var props = ['(\'' + selProp.name + '\')']; + var containing_layer = selProp.propertyGroup(selProp.propertyDepth); + for(var i = 1; i + * @version 1.0.0 + * + * @license This script is provided "as is," without warranty of any kind, expressed or implied. In + * no event shall the author be held liable for any damages arising in any way from the use of this + * script. + * + * + * + * + */ + +(function () { + //@include "../library/km_helperFunctions.jsx"; + //@include "../library/km_scriptUI_functions.jsx"; + //@include "../library/km_utilityFunctions.jsx"; + //@include "../library/km_textAnimators.jsx"; + //@include "../library/km_systemFunctions.jsx"; + try { + app.beginUndoGroup("what does this script do?"); + var km = kmFunction; + var kmScript = kmScriptUI; + var kmUtils = kmUtilityFunctions; + var kmTextAnims = KMTextAnimatorsLib; + var kmSystems = kmSystemsLib; + + var activeComp = km.getActiveComp(app.project); + if(!activeComp) return + var selLayers = km.getSelectedLayers(activeComp); + if(!selLayers) return + var selProps = km.getSelectedProperties(selLayers); + if(!selProps) return + var posProps = getPositionProps(selProps); + + var alertMessage = 'Keyframe Stats\r'; + + for(var m = 0; m 0){ + for(var k = 1; k<=prop.numKeys; k++){ + var key = k; + propEases.push({ + keyVal: prop.keyValue(key), + keyTime: prop.keyTime(key), + keyInInterpType: prop.keyInInterpolationType(key).speed, + keyInSpatialTan: prop.keyInSpatialTangent(key).speed, + keyInTempEase: prop.keyInTemporalEase(key).speed, + keyOutInterpType: prop.keyOutInterpolationType(key).speed, + keyOutSpatialTan: prop.keyOutSpatialTangent(key).speed, + keyOutTempEase: prop.keyOutTemporalEase(key).speed, + } + + ) + } + } + + positionProps.push({ + propName: prop.name, + propKeys: prop.numKeys, + propEases: propEases + }) + } + + } + + return positionProps; + } +})(); diff --git a/src/scripts/km-sparks-renderHelper.jsx b/src/scripts/km-sparks-renderHelper.jsx new file mode 100644 index 0000000..2ef7fe0 --- /dev/null +++ b/src/scripts/km-sparks-renderHelper.jsx @@ -0,0 +1,659 @@ + /** + * @description a script with a UI that will automate rendering process for multiple screens + * @name show-render-helper + * @author Kyle Harter + * + * @license This script is provided "as is," without warranty of any kind, expressed or implied. In + * no event shall the author be held liable for any damages arising in any way from the use of this + * script. + * + * + * + * +*/ + + +(function(thisObj){ + + //@include "../library/km_helperFunctions.jsx"; + //@include "../library/km_scriptUI_functions.jsx"; + //@include "../library/km_utilityFunctions.jsx"; + //@include "../library/km_textAnimators.jsx"; + //@include "../library/km_systemFunctions.jsx"; + //@include "../library/OS.jsx"; + //@include "../library/json2.js" + + var versionNumber = '0.1.0'; + var scriptName = "Show Render Helper" + ' v' + versionNumber; + + createUI(thisObj) + + function createUI(thisObj){ + + var win = thisObj instanceof Panel + ? thisObj + : new Window("window", scriptName, undefined, { + resizeable: true + }) + + win.orientation = 'column'; + win.alignChildren = ["fill", "top"]; + + var tabMargins = [16,15,16,0]; + var panelMargins = 16; + + var proj = null; + // if(!proj) return + if(app.project){ + proj = app.project; + } + var DEFAULT_SETTINGS = { + settings:{ + defaultOutputPath: proj && proj.file ? proj.file.parent.fsName + '/renders' : null, + qcExports: true + } + } + + var savedSettings = readSettingsFile(); + if(savedSettings.settings){ + for(var key in savedSettings.settings){ + if(savedSettings.settings.hasOwnProperty(key) && typeof savedSettings.settings !== 'undefined'){ + DEFAULT_SETTINGS.settings[key] = savedSettings.settings[key] + } + } + } + + var mainTabbedPanel = win.add("tabbedpanel", undefined, undefined); + mainTabbedPanel.orientation = 'column'; + mainTabbedPanel.alignChildren = ['fill', 'fill'] + // mainTabbedPanel.size = [350,450]; + + var renderTab = mainTabbedPanel.add('tab', undefined, 'Render'); + renderTab.orientation = 'column'; + renderTab.alignChildren = ['fill', 'top']; + renderTab.margins = tabMargins; + renderTab.spacing = 10; + + + // WALLSELECTPANEL + // =============== + var wallSelectPanel = renderTab.add("panel", undefined, undefined, {name: "wallSelectPanel"}); + wallSelectPanel.text = "Select Walls"; + wallSelectPanel.orientation = "column"; + wallSelectPanel.alignChildren = ["fill","center"]; + wallSelectPanel.margins = panelMargins; + + // WALLSGROUP + // ========== + var wallsGroup = wallSelectPanel.add("group", undefined, {name: "wallsGroup"}); + wallsGroup.orientation = "row"; + wallsGroup.alignChildren = ["fill","fill"]; + wallsGroup.spacing = 20; + + // TOPROW + // ====== + var leftColumn = wallsGroup.add("group", undefined, {name: "leftColumn"}); + leftColumn.orientation = "column"; + leftColumn.alignChildren = ["left","center"]; + leftColumn.spacing = 20; + + + + var wallA = leftColumn.add("checkbox", undefined, undefined, {name: "wallA"}); + wallA.text = "Notch LC Wall A"; + wallA.value = true; + + var wallC = leftColumn.add("checkbox", undefined, undefined, {name: "wallC"}); + wallC.text = "Notch LC Wall C"; + wallC.value = true; + + // BOTTOMROW + // ========= + var rightColumn = wallsGroup.add("group", undefined, {name: "rightColumn"}); + rightColumn.orientation = "column"; + rightColumn.alignChildren = ["right","center"]; + rightColumn.spacing = 20; + + var wallB = rightColumn.add("checkbox", undefined, undefined, {name: "wallB"}); + wallB.text = "Notch LC Wall B"; + wallB.value = true; + + var wallD = rightColumn.add("checkbox", undefined, undefined, {name: "wallD"}); + wallD.text = "Notch LC Wall D"; + wallD.value = true; + var allWalls = wallSelectPanel.add("checkbox", undefined, undefined, {name: "selectAllWalls"}); + allWalls.alignment = ['center', 'top']; + allWalls.text = "Deselect All Walls"; + allWalls.value = true; + + // ALPHAROW + // ======== + var utilityPanel = renderTab.add("panel", undefined, 'Utility', {name: "utlityPanel"}); + utilityPanel.orientation = "row"; + utilityPanel.alignChildren = ["fill","center"]; + utilityPanel.margins = panelMargins; + + var wallAlpha = utilityPanel.add("checkbox", undefined, undefined, {name: "wallAlpha"}); + wallAlpha.text = "Walls on Alpha"; + var qcExports = utilityPanel.add("checkbox", undefined, undefined); + qcExports.text = "QC Exports in AE"; + qcExports.alignment = ['right', 'center'] + qcExports.value = DEFAULT_SETTINGS.settings.qcExports; + + // OUTPUTPANEL + // =========== + var locationPanel = renderTab.add("panel", undefined, 'Output Location', {name: "locationPanel"}); + locationPanel.orientation = "column"; + locationPanel.alignChildren = ["fill","center"]; + locationPanel.spacing = 10; + locationPanel.margins = panelMargins; + + var locationButton = locationPanel.add("button", undefined, undefined, {name: "locationButton"}); + locationButton.text = "Choose Location..."; + var renderLocationText = locationPanel.add("statictext", undefined, undefined, {name: "renderLocationText"}); + renderLocationText.text = truncateFilePath(DEFAULT_SETTINGS.settings.defaultOutputPath); + renderLocationText.characters = 25; + + + var renderPanel = renderTab.add('panel', undefined,''); + renderPanel.orientation = 'row'; + renderPanel.alignChildren = ['fill', 'top']; + renderPanel.margins = panelMargins; + var renderButton = renderPanel.add("button", undefined, 'Render', {name: "renderButton"}); + // var testButton = renderPanel.add("button", undefined, 'Test', {name: "renderButton"}); + + + // HELP TAB + // ========== + var helpTab = mainTabbedPanel.add('tab', undefined, 'Help') + helpTab.orientation = 'column'; + helpTab.alignChildren = ['fill', 'top']; + helpTabspacing = 10; + helpTab.margins = tabMargins; + var helpGroup = helpTab.add('group', undefined, 'Help Group'); + helpGroup.alignChildren = ['fill', 'top'] + helpGroup.orientation = 'column'; + var helpEditText = helpGroup.add('edittext', undefined, undefined,{multiline: true, readonly: true ,scrollable: true}); + helpEditText.text = 'Help instructions loading'; + helpEditText.preferredSize.height = 325; + // helpEditText.alignment = ['fill', 'fill']; + var omButtonGroup = helpTab.add('group', undefined, 'Output Modules Source Button Group'); + omButtonGroup.orientation = 'row'; + omButtonGroup.alignChildren = ['fill', 'top']; + var omSourceButton = omButtonGroup.add('button', undefined, 'Get Output Modules'); + // omSourceButton.alignment = ['fill', 'fill']; + + // Settings TAB + // ========== + var settingsTab = mainTabbedPanel.add('tab', undefined, 'Settings') + settingsTab.orientation = 'column'; + settingsTab.alignChildren = ['fill', 'fill']; + settingsTab.margins = tabMargins; + + var settingsGroup = settingsTab.add("group", undefined, undefined, {name: "settingsGroup"}); + settingsGroup.orientation = "column"; + settingsGroup.alignChildren = ["fill","top"]; + settingsGroup.spacing = 15; + + var settingsLocationPanel = settingsGroup.add('panel', undefined, undefined); + settingsLocationPanel.orientation = 'column' + settingsLocationPanel.alignChildren = ['fill', 'fill']; + settingsLocationPanel.margins = panelMargins; + + var settingsLocationButton = settingsLocationPanel.add("button", undefined, undefined, {name: "settingsLocationButton"}); + settingsLocationButton.text = "Choose Default Location..."; + var settingsLocationText = settingsLocationPanel.add("statictext", undefined, undefined, {name: "settingsLocationText"}); + settingsLocationText.text = truncateFilePath(DEFAULT_SETTINGS.settings.defaultOutputPath); + + var settingsQCPanel = settingsGroup.add('panel', undefined, undefined); + settingsQCPanel.orientation = 'column' + settingsQCPanel.alignChildren = ['fill', 'fill']; + settingsQCPanel.margins = panelMargins; + + var settingsQCCB = settingsQCPanel.add("checkbox", undefined, undefined); + settingsQCCB.text = "Import Exports for QC"; + settingsQCCB.value = DEFAULT_SETTINGS.settings.qcExports; + + var saveSettingsPanel = settingsGroup.add('panel', undefined, undefined); + saveSettingsPanel.orientation = 'row'; + // saveSettingsPanel.alignment = ['fill', 'bottom']; + saveSettingsPanel.alignChildren = ['fill', 'fill']; + saveSettingsPanel.margins = panelMargins; + var saveSettingsButton = saveSettingsPanel.add("button", undefined, undefined, {name: "saveSettingsButton"}); + saveSettingsButton.text = "Save Settings"; + + + settingsLocationButton.addEventListener('mousedown', function(){ + var updatedDefaultLocation = Folder.selectDialog('Select a default output location'); + if(updatedDefaultLocation !== null){ + var truncatedDisplayText = truncateFilePath(updatedDefaultLocation.fsName); + settingsLocationText.text = truncatedDisplayText; + renderLocationText.text = truncatedDisplayText; + DEFAULT_SETTINGS.settings.defaultOutputPath = updatedDefaultLocation.fsName + } + return + }) + + function syncQCExports(newVal){ + settingsQCCB.value = newVal; + qcExports.value = newVal; + DEFAULT_SETTINGS.settings.qcExports = newVal; + } + + + settingsQCCB.onClick = function(){ + qcExports.value = settingsQCCB.value; + DEFAULT_SETTINGS.settings.qcExports = settingsQCCB.value; + } + + saveSettingsButton.addEventListener('mousedown', function(){ + saveSettingsButton.text = 'Saving...' + if(writeSettingsFile(DEFAULT_SETTINGS)){ + alert('Settings saved.') + } + saveSettingsButton.text = "Save Settings" + }) + + + // Opens URL in browser for AOM file + + omSourceButton.addEventListener('mousedown', function(){ + var userOS = OS; + var launchCode = userOS.openUrl("https://drive.google.com/file/d/1Ur8bSu7RD8pjf2dVTLmkqlXyIz6ehtnU/view") + }) + + helpEditText.text = setHelpMessage(scriptName, versionNumber); + + + var topWalls = leftColumn.children; + var bottomWalls = rightColumn.children; + var wallsArray = [topWalls[0], topWalls[1], bottomWalls[0], bottomWalls[1]]; + + + allWalls.onClick = function(){ + + if(allWalls.value == false){ + allWalls.text = 'Select all walls' + } else { + allWalls.text = 'Deselect all walls' + } + for(var c = 0; c 0){ + while(renderQueue.numItems > 0){ + renderQueue.item(renderQueue.numItems).remove() + } + } + + var renderPipeline = buildRenderPipeline(renderComps,renderQueue,templateArray,renderFolderPath); + // RENDERRRRR // + app.endUndoGroup() + + + if(proj.bitsPerChannel < 16){ + proj.bitsPerChannel = 16; + } + renderQueue.render(); + + + var completedComps = []; + var completedNames = []; + var failedComps = []; + + for(var r = 0; r 0){ + if(qcExports.value){ + var aeFolders = createImportFolders('zz_QC', completedComps, km.getOrCreateFolder); + alert('Renders complete!\rYour exports will be imported into AE inside the folder named zz_QC for quality control'); + importExportsIntoAE(proj, aeFolders, renderFolderPath, renderPipeline.outputFileNames) + } else { + alert('Success!\rYour files were exported to:\r\r' + renderFolderPath) + var outputFolder = new Folder(renderFolderPath); + outputFolder.execute() + } + } +/* + switch(renderPipeline.rqItems[0].status){ + case RQItemStatus.DONE: + if(qcExports.value){ + var aeFolders = createImportFolders('zz_QC', renderPipeline.rqComps, km.getOrCreateFolder); + alert('Renders complete!\rYour exports will imported into AE inside of the folder named z_QC for quality control'); + importExportsIntoAE(proj, aeFolders, renderFolderPath, renderPipeline.outputFileNames) + } else { + alert('Success!\rYou\'re files were exported to:\r\r' + renderFolderPath) + var outputFolder = new Folder(renderFolderPath); + outputFolder.execute() + } + break; + case RQItemStatus.USER_STOPPED: + alert('Render cancelled.\rNo files were exported'); + break; + case RQItemStatus.ERR_STOPPED: + alert('Render stopped due to an error.\rCheck the render queue for details'); + break; + default: + alert('Render did not complete.\rStatus: ' + renderPipeline.rqItems[0].status); + break; + } + */ + + } catch(error) { + alert("An error occured on line: " + error.line + "\nError message: " + error.message); + } + + } + + // HELPER FUNCTIONS + + + function importExportsIntoAE(proj, folders, location, names){ + var exports = getExports(location, names); + var compFolders = folders.compFolders; + for(var e = 0; e