├── Version_Execad
├── AppName.txt
├── AppTitle.txt
├── AppID.txt
├── PresetsFolderName.txt
├── SettingsLayerName.txt
└── Presets
│ └── ExecAd Standard Export.seprops
├── Version_Standard
├── AppName.txt
├── AppTitle.txt
├── AppID.txt
├── SettingsLayerName.txt
├── PresetsFolderName.txt
└── Presets
│ └── Android Icons - Launcher (From 512x512).seprops
├── SmartCore
├── icons
│ ├── eye.png
│ ├── cross.png
│ ├── null.png
│ ├── tick.png
│ ├── export.png
│ ├── import.png
│ ├── upArrow.png
│ ├── downArrow.png
│ ├── leftArrow.png
│ ├── rightArrow.png
│ ├── dropdownArrow.png
│ ├── checkbox_disabled.png
│ ├── checkbox_selected.png
│ └── checkbox_unselected.png
├── Constants.jsx
├── closure.jsx
├── ExportItem.jsx
├── ExportBundle.jsx
├── DocCloser.jsx
├── ImportDialog.jsx
├── FileFilter.jsx
├── NumberControl.jsx
├── RangeControl.jsx
├── Tokens.jsx
├── SettingsPanel.jsx
├── StringControl.jsx
├── ExportDialog.jsx
├── ExportPanel.jsx
├── SaveSettingsDialog.jsx
├── FilePatternControl.jsx
├── PreviewFilesPanel.jsx
├── Queue.jsx
├── SymbolPanel.jsx
├── TabbedPanel.jsx
├── ArtboardPanel.jsx
├── MainTabbedPanel.jsx
├── MarginControl.jsx
├── Button.jsx
├── ColorPicker.jsx
├── LayerPanel.jsx
├── FormatSettings.jsx
├── SymbolBundler.jsx
├── PresetPanel.jsx
├── ArtboardBundler.jsx
├── Exporter.jsx
├── Dropdown.jsx
├── PropertiesPanel.jsx
├── ElementPanel.jsx
├── ExportSettings.jsx
├── LayerBundler.jsx
├── ExportToolBuilder.jsx
└── DocUtils.jsx
├── assets
├── ExtensionIcon.ai
├── FeaturedImage.ai
├── Layer-22x22.png
├── Layer-30x30.png
├── Layer-60x60.png
├── Symbol-22x22.png
├── Symbol-30x30.png
├── Symbol-60x60.png
├── FeaturedImage.jpg
├── FeaturedImage.png
├── Layer-512x512.jpg
└── OutputStateIcons.ai
├── .gitignore
├── .debug
├── html
├── panel.html
└── previous.html
├── Templates
└── {AppTitle}.jsx
├── manifest.xml
└── README.md
/Version_Execad/AppName.txt:
--------------------------------------------------------------------------------
1 | ExecAdExport
--------------------------------------------------------------------------------
/Version_Execad/AppTitle.txt:
--------------------------------------------------------------------------------
1 | ExecAd Exporter
--------------------------------------------------------------------------------
/Version_Standard/AppName.txt:
--------------------------------------------------------------------------------
1 | SmartExport
--------------------------------------------------------------------------------
/Version_Standard/AppTitle.txt:
--------------------------------------------------------------------------------
1 | Smart Export
--------------------------------------------------------------------------------
/Version_Execad/AppID.txt:
--------------------------------------------------------------------------------
1 | org.tbyrne.ExecAdExport
--------------------------------------------------------------------------------
/Version_Standard/AppID.txt:
--------------------------------------------------------------------------------
1 | org.tbyrne.smartExport
--------------------------------------------------------------------------------
/Version_Standard/SettingsLayerName.txt:
--------------------------------------------------------------------------------
1 | Export Settings
--------------------------------------------------------------------------------
/Version_Execad/PresetsFolderName.txt:
--------------------------------------------------------------------------------
1 | ExecAd Export Presets
--------------------------------------------------------------------------------
/Version_Execad/SettingsLayerName.txt:
--------------------------------------------------------------------------------
1 | ExecAd Export Settings
--------------------------------------------------------------------------------
/Version_Standard/PresetsFolderName.txt:
--------------------------------------------------------------------------------
1 | Smart Export Presets
--------------------------------------------------------------------------------
/SmartCore/icons/eye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/eye.png
--------------------------------------------------------------------------------
/assets/ExtensionIcon.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/ExtensionIcon.ai
--------------------------------------------------------------------------------
/assets/FeaturedImage.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/FeaturedImage.ai
--------------------------------------------------------------------------------
/assets/Layer-22x22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Layer-22x22.png
--------------------------------------------------------------------------------
/assets/Layer-30x30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Layer-30x30.png
--------------------------------------------------------------------------------
/assets/Layer-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Layer-60x60.png
--------------------------------------------------------------------------------
/assets/Symbol-22x22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Symbol-22x22.png
--------------------------------------------------------------------------------
/assets/Symbol-30x30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Symbol-30x30.png
--------------------------------------------------------------------------------
/assets/Symbol-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Symbol-60x60.png
--------------------------------------------------------------------------------
/SmartCore/icons/cross.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/cross.png
--------------------------------------------------------------------------------
/SmartCore/icons/null.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/null.png
--------------------------------------------------------------------------------
/SmartCore/icons/tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/tick.png
--------------------------------------------------------------------------------
/assets/FeaturedImage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/FeaturedImage.jpg
--------------------------------------------------------------------------------
/assets/FeaturedImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/FeaturedImage.png
--------------------------------------------------------------------------------
/assets/Layer-512x512.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/Layer-512x512.jpg
--------------------------------------------------------------------------------
/SmartCore/icons/export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/export.png
--------------------------------------------------------------------------------
/SmartCore/icons/import.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/import.png
--------------------------------------------------------------------------------
/SmartCore/icons/upArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/upArrow.png
--------------------------------------------------------------------------------
/assets/OutputStateIcons.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/assets/OutputStateIcons.ai
--------------------------------------------------------------------------------
/SmartCore/icons/downArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/downArrow.png
--------------------------------------------------------------------------------
/SmartCore/icons/leftArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/leftArrow.png
--------------------------------------------------------------------------------
/SmartCore/icons/rightArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/rightArrow.png
--------------------------------------------------------------------------------
/SmartCore/icons/dropdownArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/dropdownArrow.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /ignore
2 | /build/signingtoolkit
3 | /build/cert.ppk
4 | /build/cert.p12
5 | /bin
6 | /build/password.txt
7 | /build/tools
8 |
--------------------------------------------------------------------------------
/SmartCore/icons/checkbox_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/checkbox_disabled.png
--------------------------------------------------------------------------------
/SmartCore/icons/checkbox_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/checkbox_selected.png
--------------------------------------------------------------------------------
/SmartCore/icons/checkbox_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TomByrne/IllustratorSmartExport/HEAD/SmartCore/icons/checkbox_unselected.png
--------------------------------------------------------------------------------
/SmartCore/Constants.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | var BoundsMode = {};
3 |
4 | BoundsMode.ARTBOARD = "artboard";
5 | BoundsMode.ARTWORK = "artwork";
6 | BoundsMode.ARTBOARD_AND_ARTWORK = "artboardAndArtwork";
7 |
8 | pack.BoundsMode = BoundsMode;
9 |
10 | })(smartExport)
--------------------------------------------------------------------------------
/.debug:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/SmartCore/closure.jsx:
--------------------------------------------------------------------------------
1 | closure = function(scope, meth, args, passArgs, passMethod){
2 | if(passArgs){
3 | var ret = function(){
4 | var args2 = Array.prototype.slice.call(arguments);
5 | return meth.apply(scope, args2.concat(args));
6 | }
7 | }else{
8 | if(!args) args = [];
9 | var ret = function(){
10 | return meth.apply(scope, args);
11 | }
12 | }
13 | if(passMethod){
14 | if(!args)args = [ret];
15 | else args.push(ret);
16 | }
17 | return ret;
18 | }
--------------------------------------------------------------------------------
/SmartCore/ExportItem.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function ExportItem(formatSettings, fileName){
3 | this.init(formatSettings, fileName);
4 | return this;
5 | }
6 |
7 | ExportItem.prototype={
8 |
9 | state:"waiting",
10 | formatSettings:null,
11 | fileName:null,
12 | names:null,
13 |
14 | init:function(formatSettings, fileName){
15 | this.names = [];
16 | this.formatSettings = formatSettings;
17 | this.fileName = fileName;
18 | }
19 | };
20 | pack.ExportItem = ExportItem;
21 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/ExportBundle.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function ExportBundle(prepareHandler, cleanupHandler){
3 | this.init(prepareHandler, cleanupHandler);
4 | return this;
5 | }
6 |
7 | ExportBundle.prototype={
8 | items:null,
9 | prepareHandler:null,
10 | cleanupHandler:null,
11 |
12 | init:function(prepareHandler, cleanupHandler){
13 | this.items = [];
14 | this.prepareHandler = prepareHandler;
15 | this.cleanupHandler = cleanupHandler;
16 | }
17 | };
18 | pack.ExportBundle = ExportBundle;
19 | })(smartExport)
--------------------------------------------------------------------------------
/html/panel.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/html/previous.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SmartCore/DocCloser.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | var DocCloser = {};
3 |
4 | DocCloser.setMainDoc = function(doc){
5 | DocCloser.mainDoc = doc;
6 | }
7 |
8 | DocCloser.closePending = function(){
9 | //alert("close: "+DocCloser.pendingClose);
10 | if(DocCloser.pendingClose){
11 | DocCloser.pendingClose.close(SaveOptions.DONOTSAVECHANGES);
12 | DocCloser.pendingClose = null;
13 | }
14 | }
15 |
16 | DocCloser.closeDocument = function(doc){
17 | DocCloser.closePending();
18 | DocCloser.pendingClose = doc;
19 | app.activeDocument = DocCloser.mainDoc;
20 | }
21 |
22 | pack.DocCloser = DocCloser;
23 |
24 | })(smartExport)
--------------------------------------------------------------------------------
/Version_Execad/Presets/ExecAd Standard Export.seprops:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | 0
6 | true
7 |
8 | true
9 | true
10 | true
11 |
12 |
13 |
14 | EPS
15 | false
16 | true
17 | artwork
18 |
19 | high
20 | true
21 |
22 | <DocName>_<LayerName>.<Ext>
23 | <DocName>_proof.<Ext>
24 | <SymbolName>.<Ext>
25 | <ArtboardName>_<ElementName>.<Ext>
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/SmartCore/ImportDialog.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function ImportDialog(){
3 | this.init();
4 | return this;
5 | }
6 | ImportDialog.prototype={
7 |
8 | controls:null,
9 |
10 | init:function(){
11 | var scopedThis = this;
12 |
13 | this.dialog = new Window('dialog', "Where to Import?");
14 | this.dialog.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
15 |
16 | this.dialog.add("statictext", undefined, "Import settings into presets or into current settings?");
17 |
18 |
19 |
20 | var buttonRow = this.dialog.add("group");
21 | buttonRow.orientation = "row";
22 | buttonRow.alignment = [ScriptUI.Alignment.CENTER, ScriptUI.Alignment.TOP];
23 |
24 | this.presetButton = buttonRow.add('button', undefined, 'Presets');
25 | this.presetButton.onClick = function() {
26 | scopedThis.dest = "presets";
27 | scopedThis.dialog.close();
28 | };
29 |
30 | this.saveButton = buttonRow.add('button', undefined, 'Current', {name:'ok'});
31 | this.saveButton.onClick = function() {
32 | scopedThis.dest = "current";
33 | scopedThis.dialog.close();
34 | };
35 |
36 | this.dialog.show();
37 | }
38 | };
39 | pack.ImportDialog = ImportDialog;
40 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/FileFilter.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function FileFilter(fileTypes, optimistic){
3 | this.init(fileTypes, optimistic);
4 | return this;
5 | }
6 |
7 |
8 |
9 | FileFilter.prototype={
10 | onChange:null,
11 |
12 | init:function(fileTypes, optimistic){
13 |
14 | this.fileTypes = fileTypes;
15 | this.optimistic = optimistic;
16 |
17 | this.filterStr = "";
18 | this.allowedExt = {};
19 | for(var i=0; i this.max)value = this.max;
42 | this.value = value;
43 | this.input.text = value+this.unit;
44 | this.slider.value = value;
45 | if(onChange)onChange();
46 | },
47 |
48 | getValue : function(){
49 | return this.value;
50 | }
51 | };
52 | pack.RangeControl = RangeControl;
53 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/Tokens.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | tokens = {};
3 |
4 | var heading = "--Tokens--";
5 |
6 | tokens.ARTBOARD_NUM_TOKEN = "";
7 | tokens.ARTBOARD_NAME_TOKEN = "";
8 |
9 | tokens.LAYER_NUM_TOKEN = "",
10 | tokens.LAYER_NAME_TOKEN = "";
11 |
12 | tokens.ELEMENT_PATH_TOKEN = "",
13 | tokens.ELEMENT_NAME_TOKEN = "";
14 |
15 | tokens.SYMBOL_NAME_TOKEN = "";
16 |
17 | tokens.FILE_EXT_TOKEN = "";
18 |
19 | tokens.DOC_NAME_TOKEN = "";
20 |
21 | tokens.ARTBOARD_TOKENS = [ heading,
22 | tokens.ARTBOARD_NUM_TOKEN,
23 | tokens.ARTBOARD_NAME_TOKEN,
24 | tokens.FILE_EXT_TOKEN,
25 | tokens.DOC_NAME_TOKEN
26 | ];
27 |
28 | tokens.LAYER_TOKENS = [ heading,
29 | tokens.ARTBOARD_NUM_TOKEN,
30 | tokens.ARTBOARD_NAME_TOKEN,
31 | tokens.LAYER_NUM_TOKEN,
32 | tokens.LAYER_NAME_TOKEN,
33 | tokens.FILE_EXT_TOKEN,
34 | tokens.DOC_NAME_TOKEN
35 | ];
36 |
37 | tokens.ELEMENT_TOKENS = [ heading,
38 | tokens.ARTBOARD_NUM_TOKEN,
39 | tokens.ARTBOARD_NAME_TOKEN,
40 | tokens.LAYER_NUM_TOKEN,
41 | tokens.LAYER_NAME_TOKEN,
42 | tokens.ELEMENT_PATH_TOKEN,
43 | tokens.ELEMENT_NAME_TOKEN,
44 | tokens.FILE_EXT_TOKEN,
45 | tokens.DOC_NAME_TOKEN
46 | ];
47 |
48 | tokens.SYMBOL_TOKENS = [ heading,
49 | tokens.SYMBOL_NAME_TOKEN,
50 | tokens.FILE_EXT_TOKEN,
51 | tokens.DOC_NAME_TOKEN
52 | ];
53 |
54 | pack.tokens = tokens;
55 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/SettingsPanel.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function SettingsPanel(container, exportSettings){
3 | this.init(container, exportSettings);
4 | return this;
5 | }
6 |
7 | SettingsPanel.prototype={
8 | onPatternChanged:null,
9 | onScalingChanged:null,
10 | onDirectoryChanged:null,
11 |
12 | init:function(container, exportSettings){
13 | var scopedThis = this;
14 | this.exportSettings = exportSettings;
15 |
16 | var row;
17 | var column = container.add('group')
18 | column.orientation = 'column';
19 | column.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
20 |
21 | // DIR GROUP
22 | row = column.add( 'group', undefined, '')
23 | row.orientation = 'row'
24 | row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP]
25 |
26 | var chooseBtn = row.add('button', undefined, 'Output Directory...' );
27 | chooseBtn.onClick = function() {
28 | var file = new Folder(scopedThis.exportSettings.directory).selectDlg();
29 | if(!file)return;
30 |
31 | scopedThis.directoryInput.text = file.fsName;
32 | scopedThis.directoryInput.onChange();
33 | }
34 |
35 | this.directoryInput = row.add('edittext', undefined, exportSettings.directory);
36 | this.directoryInput.size = [ 440,20 ];
37 | this.directoryInput.onChange = function(){
38 | scopedThis.exportSettings.directory = scopedThis.directoryInput.text;
39 | if(scopedThis.onDirectoryChanged)scopedThis.onDirectoryChanged();
40 | }
41 | },
42 |
43 | updateSettings:function(){
44 | this.directoryInput.text = this.exportSettings.directory;
45 | }
46 | };
47 | pack.SettingsPanel = SettingsPanel;
48 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/StringControl.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function StringControl(container, value, optional){
3 | this.init(container, value, optional);
4 | return this;
5 | }
6 |
7 |
8 |
9 | StringControl.prototype={
10 | onChange:null,
11 |
12 | init:function(container, value, optional){
13 | var scopedThis = this;
14 |
15 | if(value==null)value = "";
16 |
17 | this.value = value;
18 | this.optional = optional;
19 |
20 | var row = container.add("group");
21 | row.orientation = "row";
22 | row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.CENTER];
23 |
24 | var inputW;
25 | if(optional){
26 | this.checkbox = row.add('checkbox');
27 | this.checkbox.value = (value!=null && value!="");
28 | this.checkbox.size = [16, 16];
29 | this.checkbox.onClick = function(){
30 | scopedThis.input.enabled = scopedThis.checkbox.value;
31 | }
32 | inputW = 175;
33 | }else{
34 | inputW = 200;
35 | }
36 |
37 | this.input = row.add('edittext', undefined, value);
38 | this.input.preferredSize = [inputW, 20];
39 | this.input.onChange = function(){
40 | scopedThis.setValue(scopedThis.input.text);
41 | }
42 | if(optional){
43 | this.input.enabled = this.checkbox.value;
44 | }
45 | },
46 | setValue : function(value){
47 | this.value = value;
48 | this.input.text = value;
49 | if(this.optional){
50 | this.checkbox.value = (value!="");
51 | this.input.enabled = this.checkbox.value;
52 | }
53 | if(onChange)onChange();
54 | },
55 |
56 | getValue : function(){
57 | return !this.optional || this.checkbox.value?this.value:null;
58 | }
59 | };
60 | pack.StringControl = StringControl;
61 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/ExportDialog.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function ExportDialog(presetDir, settingsExt){
3 | this.presetDir = presetDir;
4 | this.settingsExt = settingsExt;
5 | this.init();
6 | return this;
7 | }
8 | ExportDialog.prototype={
9 |
10 | controls:null,
11 |
12 | init:function(){
13 | var scopedThis = this;
14 |
15 | this.dialog = new Window('dialog', "Export which settings?");
16 | this.dialog.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
17 |
18 | this.presetList = this.dialog.add ('ListBox', [0, 0, 200, 200], '',
19 | {numberOfColumns: 1, showHeaders: false, multiselect:false,
20 | columnTitles: ['Format'] });
21 |
22 | this.presetList.add("item", "--- Current Settings ---");
23 | var allFiles = this.presetDir.getFiles();
24 | this.files = [];
25 | for(var i=0; i
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ./panel.html
34 |
35 |
36 | false
37 |
38 |
39 |
40 | ModalDialog
41 |
42 |
43 |
44 | 200
45 | 200
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | ./previous.html
57 |
58 |
59 | false
60 |
61 |
62 |
63 | ModalDialog
64 |
65 |
66 |
67 | 200
68 | 200
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/SmartCore/ExportPanel.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function ExportPanel(container, exportSettings){
3 | this.init(container, exportSettings);
4 | return this;
5 | }
6 |
7 | ExportPanel.prototype={
8 | onCancelClicked:null,
9 | onSaveCloseClicked:null,
10 | onExportClicked:null,
11 | onIgnoreWarningsChanged:null,
12 |
13 | init:function(container, exportSettings){
14 | var scopedThis = this;
15 | this.exportSettings = exportSettings;
16 |
17 | // main row
18 | var mainRow = container.add('group', undefined, '');
19 | mainRow.size = [650, 30];
20 | mainRow.alignment = [ScriptUI.Alignment.RIGHT, ScriptUI.Alignment.TOP];
21 | mainRow.orientation = 'row'
22 |
23 |
24 | // options row
25 | var optionRow = mainRow.add('group', undefined, '');
26 | optionRow.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
27 | optionRow.orientation = 'row'
28 |
29 |
30 | this.ignoreCheckBox = optionRow.add('checkbox', undefined, 'Ignore Warnings');
31 | this.ignoreCheckBox.value = exportSettings.ignoreWarnings;
32 | this.ignoreCheckBox.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.BOTTOM];
33 | this.ignoreCheckBox.onClick = function() {
34 | scopedThis.exportSettings.ignoreWarnings = scopedThis.ignoreCheckBox.value;
35 | if(scopedThis.onIgnoreWarningsChanged)scopedThis.onIgnoreWarningsChanged();
36 | };
37 |
38 |
39 | // buttons row
40 | var buttonRow = mainRow.add('group', undefined, '');
41 | buttonRow.alignment = [ScriptUI.Alignment.RIGHT, ScriptUI.Alignment.TOP];
42 | buttonRow.orientation = 'row'
43 |
44 | var cancelBtn = buttonRow.add('button', undefined, 'Cancel', {name:'cancel'});
45 | cancelBtn.preferredSize = [80, 22];
46 | cancelBtn.onClick = function() {
47 | if(scopedThis.onCancelClicked)scopedThis.onCancelClicked();
48 | };
49 |
50 | // Save button
51 | var saveBtn = buttonRow.add('button', undefined, 'Done', {name:'save'});
52 | saveBtn.preferredSize = [100, 22];
53 | saveBtn.onClick = function() {
54 | if(scopedThis.onSaveCloseClicked)scopedThis.onSaveCloseClicked();
55 | };
56 |
57 | // OK button
58 | var exportBtn = buttonRow.add('button', undefined, 'Export', {name:'ok'});
59 | exportBtn.preferredSize = [100, 22];
60 | exportBtn.onClick = function() {
61 | if(scopedThis.onExportClicked)scopedThis.onExportClicked();
62 | };
63 | },
64 | updateSettings:function(){
65 | this.ignoreCheckBox.value = this.exportSettings.ignoreWarnings;
66 | }
67 | };
68 | pack.ExportPanel = ExportPanel;
69 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/SaveSettingsDialog.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function SaveSettingsDialog(){
3 | this.init();
4 | return this;
5 | }
6 | SaveSettingsDialog.prototype={
7 |
8 | controls:null,
9 |
10 | init:function(){
11 | var scopedThis = this;
12 |
13 | this.dialog = new Window('dialog', "Add New Preset");
14 | this.dialog.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
15 |
16 | var nameRow = this.dialog.add("group");
17 | nameRow.orientation = "row";
18 | nameRow.alignment = [ScriptUI.Alignment.CENTER, ScriptUI.Alignment.TOP];
19 |
20 | nameRow.add("statictext", undefined, "Preset name:");
21 |
22 | this.input = nameRow.add("edittext", undefined, "");
23 | this.input.preferredSize = [190, 22];
24 |
25 | this.generalCheckbox = this.dialog.add("checkbox", undefined, "Save Destination Folder");
26 | this.generalCheckbox.value = true;
27 | this.generalCheckbox.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
28 |
29 | this.formatCheckbox = this.dialog.add("checkbox", undefined, "Save Format Settings");
30 | this.formatCheckbox.value = true;
31 | this.formatCheckbox.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
32 | this.formatCheckbox.onClick = function(){
33 | scopedThis.patternCheckbox.enabled = scopedThis.formatCheckbox.value;
34 | }
35 |
36 | this.patternCheckbox = this.dialog.add("checkbox", undefined, "Save Filename Patterns");
37 | this.patternCheckbox.value = true;
38 | this.patternCheckbox.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
39 |
40 | var buttonRow = this.dialog.add("group");
41 | buttonRow.orientation = "row";
42 | buttonRow.alignment = [ScriptUI.Alignment.CENTER, ScriptUI.Alignment.TOP];
43 |
44 | this.cancelButton = buttonRow.add('button', undefined, 'Cancel', {name:'cancel'});
45 | this.cancelButton.onClick = function() {
46 | scopedThis.dialog.close();
47 | };
48 |
49 | this.saveButton = buttonRow.add('button', undefined, 'Save', {name:'ok'});
50 | this.saveButton.onClick = function() {
51 | if(!scopedThis.input.text){
52 | alert("Please choose a name for these settings");
53 | return;
54 | }
55 | scopedThis.text = scopedThis.input.text;
56 | scopedThis.patterns = scopedThis.patternCheckbox.value;
57 | scopedThis.generalSettings = scopedThis.generalCheckbox.value;
58 | scopedThis.formatSettings = scopedThis.formatCheckbox.value;
59 | scopedThis.dialog.close();
60 | };
61 |
62 | this.dialog.show();
63 | }
64 | };
65 | pack.SaveSettingsDialog = SaveSettingsDialog;
66 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/FilePatternControl.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function FilePatternControl(container, label, value, tokens){
3 | this.init(container, label, value, tokens);
4 | return this;
5 | }
6 |
7 |
8 |
9 | FilePatternControl.prototype={
10 | onChange:null,
11 |
12 | init:function(container, label, value, tokens){
13 | var scopedThis = this;
14 |
15 | if(value==null)value = "";
16 |
17 | this.value = value;
18 | this.tokens = tokens;
19 |
20 | // if(container.orientation == "column"){
21 | // var column = container;
22 | // }else{
23 | // var column = container.add('group');
24 | // column.orientation = "column";
25 | // row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
26 | // }
27 | var column = container;
28 |
29 | var row = column.add('group', undefined, '')
30 | row.orientation = 'row';
31 | row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
32 |
33 | this.label = row.add('statictext', undefined, label);
34 | this.label.size = [60,20];
35 |
36 | this.input = row.add('edittext', undefined, value);
37 | this.input.size = [ 360,20 ];
38 |
39 | this.dropdown = new pack.Dropdown(row, tokens);
40 | //this.dropdown = row.add('dropdownlist', undefined, tokens);
41 | this.dropdown.onChange = function() {
42 | scopedThis.addToken();
43 | };
44 | this.dropdown.setSize(110,20);
45 | this.dropdown.setSelection(0);
46 |
47 | // row = column.add('group', undefined, '')
48 | // row.orientation = 'row';
49 | // row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
50 |
51 | // this.input = row.add('edittext', undefined, value);
52 | // this.input.size = [ 340,20 ];
53 |
54 | this.input.onChange = function() {
55 | scopedThis.setValue(scopedThis.input.text);
56 | };
57 | this.input.addEventListener("keyup", this.input.onChange);
58 | },
59 | setValue : function(value){
60 | this.value = value;
61 | this.input.text = value;
62 | if(this.onChange)this.onChange();
63 | },
64 |
65 | getValue : function(){
66 | return this.value;
67 | },
68 |
69 | addToken:function(){
70 | if(this.dropdown.selection>0){
71 | var selected = Number(this.dropdown.selection);
72 | var token = this.tokens[selected];
73 | this.setValue(this.input.text + token);
74 | this.dropdown.setSelection(0);
75 | }
76 | },
77 | setEnabled : function(value){
78 | this.label.enabled = value;
79 | this.input.enabled = value;
80 | this.dropdown.setEnabled(value);
81 | }
82 | };
83 | pack.FilePatternControl = FilePatternControl;
84 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/PreviewFilesPanel.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function PreviewFilesPanel(container){
3 | this.init(container);
4 | return this;
5 | }
6 |
7 | PreviewFilesPanel.prototype={
8 | onPatternChanged:null,
9 | shown:false,
10 | invalid:false,
11 |
12 | init:function(container){
13 |
14 | this.list = container.add ('ListBox', [0, 0, 630, 470], 'asd',
15 | {numberOfColumns: 4, showHeaders: true,
16 | columnTitles: ['', '', '', 'Filename'] });
17 | },
18 | updateList:function(bundleList){
19 | this.bundleList = bundleList;
20 | this.refreshList();
21 | },
22 | refreshList:function(){
23 | if(!this.shown){
24 | this.invalid = true;
25 | return;
26 | }
27 |
28 | var lastArtboard;
29 | this.list.removeAll();
30 | var docRef = app.activeDocument;
31 | var lastNames = [];
32 | this.flattenedList = [];
33 | for(var i=0; i this.timeAllowance){
62 | this.timeDefecit -= this.timeAllowance;
63 | pack.Timer.addFrameHandler(this, this.doFrame);
64 | return;
65 | }
66 | //fl.trace("--------------FRAME------------ ");
67 | var maxTime = getTimer() + this.timeAllowance - this.timeDefecit;
68 | while(getTimer() < maxTime && this.queue.length){
69 | var curr = this.queue[0];
70 | this.label = curr.label + (curr.subLabel?" - "+curr.subLabel:"");
71 | curr.handler();
72 | if(curr != this.queue[0]){
73 | this.label = "";
74 | // was removed
75 | if(curr.run < curr.count)this.progress += curr.count-curr.run;
76 | }else{
77 | curr.run++;
78 | if(curr.run <= curr.count){
79 | this.progress++;
80 | if(curr.autoRemove && curr.run == curr.count){
81 | this.removeCurrent();
82 | }
83 | }
84 | }
85 | }
86 | this.timeDefecit = getTimer() - maxTime;
87 | if(this.queue.length){
88 | pack.Timer.addFrameHandler(this, this.doFrame);
89 | }else{
90 | this.label = "";
91 | this.progress = 0;
92 | this.total = 0;
93 | }
94 | this.updateProgress();
95 | },
96 | updateProgress:function(){
97 | if(this.progressHandler)this.progressHandler(this.progress, this.total);
98 | }
99 | };
100 | pack.Queue = Queue;
101 | })(smartExport)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Adobe Illustrator Smart Export
2 |
3 | ### (aka SmartLayerExport)
4 |
5 | This plugin is used to export Artboards/Layers/Symbols/Elements, these sources can be exported to multiple different formats (e.g. PNG, PDF, JPG, AI, etc).
6 |
7 | Once you have set up export settings for a document, these settings can be saved in the document so that you don't need to redo them.
8 |
9 | Export settings can also be saved as presets, which can be imported/exported for sharing.
10 |
11 | ***This plugin is no longer actively being maintained, please see below for contributing to the project.***
12 |
13 | ### Features:
14 |
15 | - Ability to scale output files for HiDPI (Retina) displays, or any other scale factor.
16 | - Can set up multiple export formats for a single file for easy regeneration of multiple asset sizes/types.
17 | - Settings are saved within Illustrator file so that settings are remembered next time you open the panel.
18 | - Layers can be trimmed down to the size of the layer itself or exported at the artboard's size.
19 | - File name pattern allows for full flexibility of output file names.
20 | - Can optionally export full Artboard images as well as individual layer images.
21 | - Can Load/Save/Import/Export settings.
22 | - Has a feature to 'Run Again' (CC only)
23 |
24 | ### Current Formats:
25 |
26 | - PNG 8
27 | - PNG 24
28 | - PDF
29 | - JPG
30 | - GIF
31 | - EPS
32 | - SVG
33 | - SVGZ
34 | - TIFF
35 | - AI
36 | - FXG (CS6 Only)
37 |
38 | ## Installation
39 |
40 | - Select latest release from [releases page](https://github.com/TomByrne/IllustratorSmartExport/releases)
41 | - Install with one of the following tools:
42 | - [ZXPInstaller](http://zxpinstaller.com/) (recommended)
43 | - Extension Manager (installed with Adobe applications)
44 | - [ExManCmd](https://www.adobeexchange.com/resources/28)
45 |
46 | ## Usage
47 |
48 | **For CS version:** Goto File > Scripts > Smart Layer Export
49 |
50 | **For CC version:** Goto Window > Extensions > Smart Export
51 |
52 | ## Build process
53 |
54 | At the moment, the build process is run locally, and it only works on Windows.
55 |
56 | This is done by double-clicking `build/BuildAll.bat`.
57 |
58 | There is the intention to migrate this to Travis CI at some point (but no resources).
59 |
60 | The build process currently spits out different versions of the plugin installer based on the `Version_*` folders, to support multiple vendors with different settings (e.g. plugin name, plugin ID, features available). Also this will likely be removed if the build process is reworked.
61 |
62 | The build process also generates two installers per `Version_*` folder, one for Illustrator CC, and one for Illustrator CS. The CC version gets installed in a slightly different way, which allows for multiple entry points.
63 |
64 | ## Contributing
65 |
66 | To contribute to the plugin, please create an issue in the Github issue tracker above, so that it's clear what needs to be resolved/improved.
67 |
68 | After making your changes in your own fork of the repo, create a Pull Request back into this repo named after the issue it intends to solve.
69 |
70 | If the changes are accepted a new build/release will be created on the Releases page.
--------------------------------------------------------------------------------
/SmartCore/SymbolPanel.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function SymbolPanel(container, selectAll, selectedNames){
3 | this.init(container, selectAll, selectedNames);
4 | return this;
5 | }
6 |
7 | SymbolPanel.prototype={
8 | onSelectedChanged:null,
9 |
10 | init:function(container, selectAll, selectedNames){
11 | this.selectAll = selectAll;
12 | this.selectedNames = selectedNames;
13 |
14 | var scopedThis = this;
15 | var column = container.add('group', undefined, '')
16 | column.orientation = 'column';
17 | column.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
18 |
19 | this.listbox = column.add ('ListBox', [0, 0, 630, 450], '',
20 | {numberOfColumns: 3, showHeaders: false, multiselect:true,
21 | columnTitles: ['', '', 'Symbol'] });
22 | this.listbox.onChange = function(){
23 | scopedThis.checkSelection();
24 | }
25 |
26 | var docRef = app.activeDocument;
27 | for(var i=0; i totalItems-1) selectedInd = totalItems-1;
31 | this.tabPanel.selection = selectedInd;
32 | },
33 | add:function(label){
34 | this.items.push(label);
35 | return this.tabPanel.add("tab", undefined, label);
36 | }
37 | };
38 |
39 | }else{
40 |
41 |
42 | function indexOf ( array, element ) {
43 | for(var i=0; i
2 | 4
3 |
4 |
5 | true
6 |
7 |
8 |
9 |
10 | PNG 24
11 | 100
12 | artboard
13 | false
14 | AndroidIcons
15 | high
16 | true
17 |
18 | <ArtboardName>_<LayerName>/launcher_store_512.<Ext>
19 | <ArtboardName>/launcher_store_512.<Ext>
20 | <SymbolName>/launcher_store_512.<Ext>
21 | <ArtboardName>_ElementName>/launcher_store_512.<Ext>
22 |
23 |
24 |
25 |
26 |
27 | PNG 24
28 | 37.5
29 | artboard
30 | false
31 | AndroidIcons
32 | high
33 | true
34 |
35 | <ArtboardName>_<LayerName>/launcher_xxxhdpi_192.<Ext>
36 | <ArtboardName>/launcher_xxxhdpi_192.<Ext>
37 | <SymbolName>/launcher_xxxhdpi_192.<Ext>
38 | <ArtboardName>_<ElementName>/launcher_xxxhdpi_192.<Ext>
39 |
40 |
41 |
42 |
43 |
44 | PNG 24
45 | 28.125
46 | artboard
47 | false
48 | AndroidIcons
49 | high
50 | true
51 |
52 | <ArtboardName>_<LayerName>/launcher_xxhdpi_144.<Ext>
53 | <ArtboardName>/launcher_xxhdpi_144.<Ext>
54 | <SymbolName>/launcher_xxhdpi_144.<Ext>
55 | <ArtboardName>_ElementName>/launcher_xxhdpi_144.<Ext>
56 |
57 |
58 |
59 |
60 |
61 | PNG 24
62 | 18.75
63 | artboard
64 | false
65 | AndroidIcons
66 | high
67 | true
68 |
69 | <ArtboardName>_<LayerName>/launcher_xhdpi_96.<Ext>
70 | <ArtboardName>/launcher_xhdpi_96.<Ext>
71 | <SymbolName>/launcher_xhdpi_96.<Ext>
72 | <ArtboardName>_<ElementName>/launcher_xhdpi_96.<Ext>
73 |
74 |
75 |
76 |
77 |
78 | PNG 24
79 | 14.0625
80 | artboard
81 | false
82 | AndroidIcons
83 | high
84 | true
85 |
86 | <ArtboardName>_<LayerName>/launcher_hdpi_72.<Ext>
87 | <ArtboardName>/launcher_hdpi_72.<Ext>
88 | <SymbolName>/launcher_hdpi_72.<Ext>
89 | <ArtboardName>_<ElementName>/launcher_hdpi_72.<Ext>
90 |
91 |
92 |
93 |
94 |
95 | PNG 24
96 | 9.375
97 | artboard
98 | false
99 | AndroidIcons
100 | high
101 | true
102 |
103 | <ArtboardName>_<LayerName>/launcher_mdpi_48.<Ext>
104 | <ArtboardName>/launcher_mdpi_48.<Ext>
105 | <SymbolName>/launcher_mdpi_48.<Ext>
106 | <ArtboardName>_<ElementName>/launcher_mdpi_48.<Ext>
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/SmartCore/ColorPicker.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function ColorPicker(container, color, optional){
3 | this.init(container, color, optional);
4 | return this;
5 | }
6 |
7 |
8 | function pad(str, count, pad){
9 | while(str.length < count){
10 | str = pad + str;
11 | }
12 | return str;
13 | }
14 |
15 | function parseColor(colStr){
16 | colStr = colStr.split("#").join("");
17 | if(colStr.length>6)colStr = colStr.substr(colStr.length - 6, colStr.length);
18 | return parseInt(colStr, 16);
19 | }
20 | function formatColor(col){
21 | if(col==null)col = 0;
22 | return "#" + pad(col.toString(16), 6, "0");
23 | }
24 | function colorToRGB(col){
25 | if(col==null)col = 0;
26 | var ret = [];
27 | ret[0] = ((col >> 16) & 0xff) / 0xff;
28 | ret[1] = ((col >> 8) & 0xff) / 0xff;
29 | ret[2] = (col & 0xff) / 0xff;
30 | return ret;
31 | }
32 | function rgbToColor(rgb){
33 | return Math.round(rgb[0] * 0xff)<<16 | Math.round(rgb[1] * 0xff)<<8 | Math.round(rgb[2] * 0xff);
34 | }
35 |
36 |
37 | /*
38 | The line width, in pixels, for the main color swatch.
39 | @type Number
40 | */
41 | var kSwatchBorderWidth = 1;
42 |
43 | function drawRGBSwatch (drawingStateObj)
44 | {
45 | var gfx = this.graphics;
46 | gfx.strokePath (this.fillPen, this.boxPath);
47 | gfx.strokePath (this.shadowPen, this.boxPath);
48 | }
49 | function updateSwatch (swatchGrp, swatchBtn, rgbValue)
50 | {
51 | var swatchGfx = swatchGrp.graphics;
52 | swatchGfx.backgroundColor = swatchGfx.newBrush (swatchGfx.BrushType.SOLID_COLOR, rgbValue);
53 | swatchGfx.disabledBackgroundColor = swatchGfx.backgroundColor;
54 | swatchBtn.fillPen = swatchGfx.newPen (swatchGfx.PenType.SOLID_COLOR, rgbValue, kSwatchBorderWidth);
55 | }
56 |
57 | ColorPicker.prototype={
58 | onChange:null,
59 |
60 | init:function(container, color, optional){
61 | var scopedThis = this;
62 |
63 | this.optional = optional;
64 |
65 | if(typeof(color)=="string")color = parseColor(color);
66 |
67 | var row = container.add("group");
68 | row.orientation = "row";
69 | row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.CENTER];
70 |
71 | if(optional){
72 | this.checkbox = row.add('checkbox');
73 | this.checkbox.value = (color!=null);
74 | this.checkbox.size = [16, 16];
75 | /*this.checkbox.onClick = function(){
76 | scopedThis.input.enabled = scopedThis.checkbox.value;
77 | scopedThis.button.enabled = scopedThis.checkbox.value;
78 | }*/
79 | }
80 |
81 | this.input = row.add('edittext', undefined, formatColor(color));
82 | this.input.preferredSize = [65, 20];
83 |
84 | this.group = row.add("group");
85 | this.group.size = [16, 16];
86 |
87 | this.button = this.group.add("button");
88 | this.button.size = [16, 16];
89 | this.button.onDraw = drawRGBSwatch;
90 |
91 | this.button.onClick = function(){
92 | var color = $.colorPicker();
93 | if(color!=-1){
94 | scopedThis.checkbox.value = true;
95 | scopedThis.setColor(color);
96 | }
97 | }
98 | this.input.onChange = function(){
99 | scopedThis.setColorStr(scopedThis.input.text);
100 | scopedThis.checkbox.value = true;
101 | }
102 | var gfx = this.button.graphics;
103 | var btnW = this.button.size.width;
104 | var btnH = this.button.size.height;
105 | // Define the top-left and bottom-right border paths
106 | var halfBorderW = kSwatchBorderWidth / 2;
107 | gfx.newPath();
108 | gfx.moveTo (halfBorderW, btnH - halfBorderW);
109 | gfx.lineTo (halfBorderW, halfBorderW);
110 | gfx.lineTo (btnW - halfBorderW, halfBorderW);
111 | gfx.lineTo (btnW - halfBorderW, btnH - halfBorderW);
112 | gfx.lineTo (halfBorderW, btnH - halfBorderW);
113 | this.button.boxPath = gfx.currentPath;
114 |
115 | this.button.shadowPen = gfx.newPen (gfx.PenType.SOLID_COLOR, [0, 0, 0, 1], kSwatchBorderWidth);
116 |
117 | /*if(optional && !this.checkbox.value){
118 | this.input.enabled = false;
119 | this.button.enabled = false;
120 | }*/
121 |
122 | this.rgbValue = colorToRGB(color);
123 | updateSwatch(this.group, this.button, this.rgbValue);
124 | },
125 |
126 | setColorStr : function(colStr){
127 | var color = parseColor(colStr);
128 | this.input.text = formatColor(color);
129 | this.rgbValue = colorToRGB(color);
130 | updateSwatch(this.group, this.button, this.rgbValue);
131 | if(this.onChange)this.onChange();
132 | },
133 |
134 | getColorStr : function(){
135 | return !this.optional || this.checkbox.value?formatColor(rgbToColor(this.rgbValue)):null;
136 | },
137 |
138 | setColor : function(color){
139 | this.input.text = formatColor(color);
140 | this.rgbValue = colorToRGB(color);
141 | updateSwatch(this.group, this.button, this.rgbValue);
142 | if(this.onChange)this.onChange();
143 | },
144 |
145 | getColor : function(){
146 | return !this.optional || this.checkbox.value?rgbToColor(this.rgbValue):null;
147 | }
148 | };
149 | pack.ColorPicker = ColorPicker;
150 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/LayerPanel.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function LayerPanel(container, selectAll, selectedIndices, ignoreLayerNames, ignoreOutOfBounds){
3 | this.init(container, selectAll, selectedIndices, ignoreLayerNames, ignoreOutOfBounds);
4 | return this;
5 | }
6 |
7 | LayerPanel.prototype={
8 | onSelectedChanged:null,
9 | onIgnoreOutOfBoundsChanged:null,
10 |
11 | init:function(container, selectAll, selectedIndices, ignoreLayerNames, ignoreOutOfBounds){
12 | this.selectAll = selectAll;
13 | this.selectedIndices = selectedIndices;
14 | this.ignoreOutOfBounds = ignoreOutOfBounds;
15 |
16 | var scopedThis = this;
17 | var column = container.add('group', undefined, '')
18 | column.orientation = 'column';
19 | column.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
20 |
21 | this.layerList = column.add ('ListBox', [0, 0, 420, 450], '',
22 | {numberOfColumns: 3, showHeaders: false, multiselect:true,
23 | columnTitles: ['', '', 'Layer'] });
24 | this.layerList.onChange = function(){
25 | scopedThis.checkSelection();
26 | }
27 |
28 | var docRef = app.activeDocument;
29 | var j = 0;
30 | for(var i=0; i');
41 | ret.appendChild( new XML(''+this.format+'') );
42 | if(this.hasProp("scaling") && this.scaling)ret.appendChild( new XML(''+this.scaling+'') );
43 | if(this.hasProp("ungroup"))ret.appendChild( new XML(''+this.ungroup+'') );
44 | if(this.hasProp("embedImage"))ret.appendChild( new XML(''+this.embedImage+'') );
45 | if(this.hasProp("boundsMode"))ret.appendChild( new XML(''+this.boundsMode+'') );
46 | if(this.hasProp("innerPadding"))ret.appendChild( new XML(''+this.innerPadding+'') );
47 | if(this.directory) ret.appendChild( new XML(''+this.directory+'') );
48 | if(this.fontHandling && this.fontHandling!="none") ret.appendChild( new XML(''+this.fontHandling+'') );
49 | if(this.colorSpace && this.colorSpace!="none") ret.appendChild( new XML(''+this.colorSpace+'') );
50 | if(this.rasterResolution && this.rasterResolution!="none") ret.appendChild( new XML(''+this.rasterResolution+'') );
51 | if(this.preset) ret.appendChild( new XML(''+this.preset+'') );
52 | if(this.active != null) ret.appendChild( new XML(''+this.active+'') );
53 |
54 | if(includePatterns){
55 | var patterns = new XML('');
56 | for(var i in this.patterns){
57 | patterns.appendChild( new XML('<'+i+'>'+this.xmlEncode(this.patterns[i])+''+i+'>') );
58 | }
59 | ret.appendChild(patterns);
60 | }
61 |
62 | var options = new XML('');
63 | for(var i in this.options){
64 | options.appendChild( new XML('<'+i+'>'+this.options[i]+''+i+'>') );
65 | }
66 | ret.appendChild(options);
67 | return ret;
68 | },
69 | xmlEncode:function(str){
70 | str = str.split("&").join("&");
71 | str = str.split("<").join("<");
72 | str = str.split(">").join(">");
73 | str = str.split('"').join(""");
74 | str = str.split("'").join("'");
75 | return str;
76 | },
77 |
78 | parseObjectNode:function(parentNode){
79 | var children = parentNode.children();
80 | var ret = {};
81 | for(var i=0; i 0 && (doc.layers.length!=1 || doc.layers[0].pageItems.length || doc.layers[0].layers.length);
95 |
96 | var artb = doc.artboards[0];
97 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
98 | var new_layer = pack.DocUtils.copyLayer(docRef, doc, artb, doc.artboards[0], artb.artboardRect, layer, doc.layers.add(), padding, doOutline, ungroup, docRef.rulerOrigin, exportSettings.ignoreWarnings, SymbolBundler.hasBoundErrorRef);
99 | return doc;
100 | }
101 |
102 |
103 | return null;
104 | }
105 | SymbolBundler.cleanupCopyDoc = function(docRef, exportSettings, exportBundle){
106 | //exportBundle.copyDoc.close(SaveOptions.DONOTSAVECHANGES);
107 | pack.DocCloser.closeDocument(exportBundle.copyDoc);
108 | exportBundle.copyDoc = null;
109 | SymbolBundler.testLayer.symbolItems.removeAll();
110 | }
111 | SymbolBundler.cleanupTempLayer = function(docRef, exportSettings, exportBundle){
112 | SymbolBundler.cleanupCopyDoc(docRef, exportSettings, exportBundle);
113 | SymbolBundler.testLayer.remove();
114 | SymbolBundler.testLayer = null;
115 | }
116 |
117 | SymbolBundler.makeFileName = function(pattern, ext, symbolName){
118 | var ret = pattern.split(pack.tokens.SYMBOL_NAME_TOKEN).join(symbolName);
119 | ret = ret.split(pack.tokens.FILE_EXT_TOKEN).join(ext);
120 | return ret;
121 | }
122 | SymbolBundler.indexOf = function ( array, element ) {
123 | for(var i=0; i= docRef.artboards.length) continue;
15 |
16 | var artboard = docRef.artboards[artI];
17 | var artboardName = artboard.name;
18 |
19 | var bundleMap = {};
20 |
21 | for (var x = 0; x < exportSettings.formats.length; x++ ) {
22 | var formatSettings = exportSettings.formats[x];
23 | var filePattern = formatSettings.patterns[patternName];
24 | if(!formatSettings.active || filePattern == '' || filePattern == null) continue;
25 |
26 | var format = formatSettings.formatRef;
27 | var bundle = this.getBundle(bundleMap, artI, formatSettings.innerPadding, formatSettings.scaling, formatSettings.boundsMode, format.copyBehaviour, formatSettings.fontHandling=="outline", formatSettings.ungroup, formatSettings.colorSpace, formatSettings.rasterResolution);
28 |
29 | var item = new pack.ExportItem(formatSettings, ArtboardBundler.makeFileName(filePattern, docRef.fullName.name, formatSettings.formatRef.ext, i, artboardName));
30 | item.names = ["Artboard "+(artI+1)];
31 | bundle.items.push(item);
32 |
33 | hasExports = true;
34 | }
35 |
36 | for(var j in bundleMap){
37 | bundle = bundleMap[j];
38 | if(bundle.items.length){
39 | bundles.push(bundle);
40 | }
41 | }
42 | }
43 |
44 | return hasExports;
45 | }
46 | ArtboardBundler.getBundle = function(bundleMap, artI, padding, scaling, boundsMode, forceCopy, doOutline, ungroup, colorSpace, rasterResolution){
47 | var trim = boundsMode!=pack.BoundsMode.ARTBOARD;
48 | if(doOutline || padding || trim || colorSpace) forceCopy = true;
49 |
50 | var key = (padding?"pad":"nopad")+"_"+(forceCopy?"copy":"nocopy")+"_"+(doOutline?"outline":"nooutline")+"_"+boundsMode + "_" + (colorSpace==null ? "" : "_"+colorSpace) + (rasterResolution==null ? "" : "_"+rasterResolution);
51 | var bundle = bundleMap[key];
52 | if(bundle){
53 | return bundle;
54 | }else if(!forceCopy){
55 | // export types which don't require a new document to be created just show/hide layers to complete export. (No pad, raster exports)
56 | bundle = new pack.ExportBundle();
57 | bundle.prepareHandler = closure(ArtboardBundler, ArtboardBundler.prepareRegular, [artI], true);
58 |
59 | }else{
60 | bundle = new pack.ExportBundle();
61 | bundle.prepareHandler = closure(ArtboardBundler, ArtboardBundler.prepareCopy, [artI, boundsMode, padding, doOutline, ungroup, colorSpace, rasterResolution], true);
62 | bundle.cleanupHandler = ArtboardBundler.cleanupCopy;
63 |
64 | }
65 | bundleMap[key] = bundle;
66 | return bundle;
67 | }
68 | ArtboardBundler.prepareRegular = function(docRef, exportSettings, exportBundle, artI){
69 | docRef.artboards.setActiveArtboardIndex(artI);
70 | return docRef;
71 | }
72 | ArtboardBundler.prepareCopy = function(docRef, exportSettings, exportBundle, artI, boundsMode, padding, doOutline, ungroup, colorSpace, rasterResolution){
73 | var artboard = docRef.artboards[artI];
74 | docRef.artboards.setActiveArtboardIndex(artI);
75 |
76 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
77 | var rect = artboard.artboardRect;
78 |
79 | var layerCheck = function(layer){
80 | return (layer.visible && DocUtils.indexOf(pack.IGNORE_LAYERS, layer.name)==-1);
81 | };
82 |
83 | var offset;
84 | if(boundsMode!=pack.BoundsMode.ARTBOARD){
85 | var allLayerBounds;
86 | for(var i=0; ilayerBounds[0]){
97 | allLayerBounds[0] = layerBounds[0];
98 | }
99 | if(allLayerBounds[1]layerBounds[3]){
106 | allLayerBounds[3] = layerBounds[3];
107 | }
108 | }
109 | }
110 | if(!allLayerBounds)return "skipped";
111 |
112 | // crop to artboard
113 | if(boundsMode==pack.BoundsMode.ARTBOARD_AND_ARTWORK){
114 | if(allLayerBounds[0]rect[1]){
118 | allLayerBounds[1] = rect[1];
119 | }
120 | if(allLayerBounds[2]>rect[2]){
121 | allLayerBounds[2] = rect[2];
122 | }
123 | if(allLayerBounds[3]1){
135 | var dirObj = Folder(path);
136 | if(!dirObj.exists){
137 | dirObj.create();
138 | }
139 | }
140 | }
141 |
142 | if(Folder.fs=="Windows"){
143 | fileName = fileName.split('/').join('\\');
144 | }
145 |
146 | // Center the view
147 | var bounds;
148 | if(copyDoc.artboards.length == 1){
149 | bounds = copyDoc.artboards[0].artboardRect;
150 | }else{
151 | bounds = copyDoc.geometricBounds;
152 | }
153 | var centerX = (bounds[0] + bounds[2]) / 2;
154 | var centerY = (bounds[1] + bounds[3]) / 2;
155 | copyDoc.activeView.centerPoint = [centerX, centerY];
156 |
157 | formatSettings.formatRef.saveFile(copyDoc, fileName, item.formatSettings.saveOptions );
158 | if(File(fileName).exists){
159 | item.state = "success";
160 | }else{
161 | failed.push(item);
162 | item.state = "failed";
163 | }
164 |
165 | }catch(e){
166 | alert("Save Failed: "+e);
167 | failed.push(item);
168 | item.state = "failed";
169 | }
170 | }
171 | this.updateProgress(++this.num_exported, this.num_to_export);
172 | this.updatedExportItem(item);
173 | //$.sleep(40) // Allows UI update;
174 | }
175 |
176 | if(copyDoc/* && copyDoc!="skipped" && copyDoc!="failed"*/){
177 | if(bundle.cleanupHandler)bundle.cleanupHandler(docRef, this.exportSettings, bundle);
178 | }
179 | }catch(e){
180 | alert(e);
181 | try{
182 | if(bundle.cleanupHandler)bundle.cleanupHandler(docRef, this.exportSettings, bundle);
183 | }catch(e){}
184 |
185 | for(i; i n) msg += "\nPlus "+(failed.length - n)+" more";
203 | msg += "\n\nTry again?";
204 | if(confirm(msg)){
205 | return this.doRun();
206 | }else{
207 | return this.doFinish(false, failed);
208 | }
209 | }else{
210 | return this.doFinish(true, failed);
211 | }
212 | },
213 |
214 | doFinish: function(success, failed){
215 | this.running = false;
216 | if(this.onExportFinished){
217 | if(success){
218 | this.onExportFinished(true, null);
219 | }else{
220 | this.onExportFinished(null, true);
221 | }
222 | }
223 | var successCount = this.num_exported - failed.length;
224 | // This alert prevents crashing
225 | if(success){
226 | alert(successCount + " exports were successful");
227 |
228 | }else if(successCount){
229 | alert(successCount + " exports were successful.\n" + failed.length + " exports failed.");
230 |
231 | }else{
232 | alert("All " + failed.length + "exports failed.");
233 | }
234 |
235 | pack.DocCloser.closePending();
236 | return success;
237 | },
238 |
239 | cancel:function(){
240 | this.cancelled = true;
241 | },
242 |
243 | indexOf: function ( array, element ) {
244 | for(var i=0; i6)colStr = colStr.substr(colStr.length - 6, colStr.length);
18 | return parseInt(colStr, 16);
19 | }
20 | function formatColor(col){
21 | if(col==null)col = 0;
22 | return "#" + pad(col.toString(16), 6, "0");
23 | }
24 | function colorToRGB(col){
25 | if(col==null)col = 0;
26 | var ret = [];
27 | ret[0] = ((col >> 16) & 0xff) / 0xff;
28 | ret[1] = ((col >> 8) & 0xff) / 0xff;
29 | ret[2] = (col & 0xff) / 0xff;
30 | return ret;
31 | }
32 | function rgbToColor(rgb){
33 | return Math.round(rgb[0] * 0xff)<<16 | Math.round(rgb[1] * 0xff)<<8 | Math.round(rgb[2] * 0xff);
34 | }
35 |
36 | Dropdown.useNative = ($.os.indexOf("Win")==-1);
37 |
38 | if(Dropdown.useNative){
39 | Dropdown.prototype={
40 | onChange:null,
41 |
42 | init:function(container, items, selectedInd){
43 | var scopedThis = this;
44 |
45 | this.dropdown = container.add("dropdownlist");
46 | this.dropdown.onChange = function(){
47 | scopedThis.onDropdownChange();
48 | };
49 |
50 | this.setItems(items);
51 | this.setSelection(selectedInd);
52 | },
53 | onDropdownChange:function(){
54 | if(this.selection == this.dropdown.selection.index) return;
55 | this.selection = this.dropdown.selection.index;
56 | if(this.onChange!=null) this.onChange();
57 | },
58 | setItems:function(items){
59 | this.items = items;
60 | this.dropdown.removeAll();
61 | if(items != null){
62 | for(var i=0; i totalItems-1) selectedInd = totalItems-1;
80 | this.dropdown.selection = selectedInd;
81 | },
82 | setEnabled:function(value){
83 | this.dropdown.enabled = value;
84 | },
85 | open:function(){
86 | // Not supported
87 | },
88 | close:function(){
89 | // Not supported
90 | }
91 | };
92 |
93 | }else{
94 |
95 | Dropdown.prototype={
96 | onChange:null,
97 | selection:-1,
98 |
99 | init:function(container, items, selectedInd){
100 | var scopedThis = this;
101 |
102 | this.selection = -1;
103 | this.showing = false;
104 |
105 | this.group = container.add("group");
106 | this.group.orientation = "row";
107 | this.group.alignChildren = ["right", "center"];
108 | this.group.margins = [0, 0, 0, 0];
109 | this.group.spacing = 0;
110 |
111 | this.button = this.group.add('button');
112 | //this.button.titleLayout = { margins: [5, 2, 2, 30] };
113 |
114 | this.icon = this.group.add('iconbutton', undefined, ScriptUI.newImage (File(pack.directory+"/icons/dropdownArrow.png")));
115 |
116 | /*this.button = container.add('iconbutton', undefined, ScriptUI.newImage (File(pack.directory+"/icons/dropdownArrow.png")));
117 | this.button.title = "Testing";
118 | this.button.titleLayout = { margins: [5, 2, 2, 3], alignment:["center", "center"] };*/
119 |
120 | this.button.onClick = function(){
121 | if(!scopedThis.showing){
122 | scopedThis.open();
123 | }
124 | }
125 |
126 |
127 | this.icon.onClick = this.button.onClick;
128 |
129 | this.listWindow = new Window("palette", undefined, undefined, {resizeable:false, closeButton:false, borderless:true});
130 |
131 | this.listbox = this.listWindow.add ('ListBox', [0, 0, 10, 10], '',
132 | {numberOfColumns: 1, showHeaders: false, multiselect:false });
133 | this.listbox.enabled = true;
134 | this.listbox.active = true;
135 |
136 | this.listbox.onChange = function(){
137 | if(scopedThis.ignoreChanges) return;
138 | scopedThis.setSelection(scopedThis.listbox.selection.index);
139 | }
140 |
141 | this.listWindow.addEventListener("blur", function(){
142 | if(scopedThis.showing) scopedThis.close();
143 | });
144 |
145 | this.button.window.addEventListener("move", function(){
146 | if(scopedThis.showing) scopedThis.positionWindow();
147 | });
148 |
149 | this.setItems(items);
150 | this.setSelection(selectedInd);
151 | },
152 | setItems:function(items){
153 | this.items = items;
154 | this.listbox.removeAll();
155 | var maxWidth = 0;
156 | var stackHeight = 0;
157 | if(items != null){
158 | for(var i=0; i= 0) this.setSelection(this.selection);
188 | },
189 | setSize:function(width, height){
190 | this.width = width;
191 | this.button.size = [width-this.icon.preferredSize[0], height];
192 | this.icon.size = [this.icon.preferredSize[0], height]
193 | },
194 | positionWindow:function(){
195 | //alert(this.button.window.frameLocation+"\n "+this.button.window.frameBounds+"\n"+this.button.window.frameSize+"\n"+this.button.window.bounds);
196 | var x = this.button.windowBounds[0] + this.button.window.bounds[0];
197 | var y = this.button.windowBounds[3] + this.button.window.bounds[1] + 10;
198 | this.listWindow.frameLocation = [x, y];
199 | },
200 | setSelection:function(selectedInd){
201 | this.close();
202 | var max = (this.items==null ? -1 : this.items.length-1);
203 | if(selectedInd > max){
204 | selectedInd = max;
205 | }
206 | if(this.selection == null) this.selection = -1;
207 | if(this.selection == selectedInd) return;
208 |
209 |
210 | this.selection = selectedInd;
211 | if(selectedInd == null || selectedInd == -1){
212 | this.button.text = "";
213 | }else{
214 | var item = this.items[selectedInd];
215 | this.button.text = item.label || item;
216 | }
217 | this.ignoreChanges = true;
218 | this.listbox.selection = this.items ? this.items[selectedInd] : null;
219 | this.ignoreChanges = false;
220 |
221 | try{
222 | if(this.onChange != null) this.onChange();
223 | }catch(e){
224 | alert(e);
225 | }
226 | },
227 | setEnabled:function(value){
228 | if(!value && this.showing) close();
229 | this.button.enabled = value;
230 | this.icon.enabled = value;
231 | },
232 | open:function(){
233 | this.showing = true;
234 | this.positionWindow();
235 | this.listWindow.show();
236 | this.listWindow.enabled = true;
237 | this.listbox.active = true;
238 |
239 | },
240 | close:function(){
241 | this.listWindow.enabled = false;
242 | this.listbox.active = false;
243 | this.showing = false;
244 | this.listWindow.hide();
245 |
246 | }
247 | };
248 | }
249 | pack.Dropdown = Dropdown;
250 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/PropertiesPanel.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | function PropertiesPanel(formatSettings){
3 | this.init(formatSettings);
4 | return this;
5 | }
6 | PropertiesPanel.prototype={
7 |
8 | controls:null,
9 | labelColumnW:130,
10 |
11 | init:function(formatSettings){
12 | var scopedThis = this;
13 |
14 | var categories = formatSettings.formatRef.more;
15 | var doCatList = (categories.length>1);
16 |
17 | this.dialog = new Window('dialog', formatSettings.formatRef.name+" Settings");
18 | this.dialog.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
19 | this.dialog.spacing = 9;
20 |
21 | this.formatSettings = formatSettings;
22 |
23 | var mainPanel;
24 | var firstPanel;
25 | if(doCatList){
26 |
27 | this.labelColumnW = 180;
28 |
29 | firstPanel = this.dialog.add("group");
30 | firstPanel.orientation = "column";
31 | firstPanel.alignment = [ScriptUI.Alignment.RIGHT, ScriptUI.Alignment.TOP];
32 |
33 | var row = this.dialog.add("group");
34 | row.orientation = "row";
35 | row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
36 |
37 | this.catList = row.add ('ListBox', [0, 0, 160, 345], '',
38 | {numberOfColumns: 1, showHeaders: false, multiselect:false,
39 | columnTitles: ['Category'] });
40 | this.catList.itemSize = [160, 42];
41 | this.catList.orientation = "column";
42 | this.catList.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP];
43 | for(var k=1; k 1 || !itemData.isGroup) return;
160 |
161 | var level = itemData.level + 1;
162 | if(itemData.childrenBuilt)
163 | {
164 | var childItems = itemData.childItems;
165 | for(var i=0; i 0);
196 |
197 | var item = parent.add(isGroup ? "node" : "item");
198 | var index = this.indexOf(this.baseSelectedPaths, path);
199 | if(index != -1){
200 | item.selected = true;
201 | this.baseSelectedPaths.splice(index, 1);
202 | }
203 | item.image = File(pack.directory+"/icons/checkbox_"+(item.selected?"":"un")+"selected.png");
204 |
205 | if(pageItem.name == ""){
206 | var type = pageItem.typename;
207 | if(type.lastIndexOf("Item") == type.length - 4){
208 | type = type.substr(0, type.length - 4);
209 | }
210 | item.text += type + ": " + path;
211 | }else{
212 | item.text = pageItem.name;
213 | }
214 |
215 | var index = this.indexOf(this.baseOpenPaths, path);
216 | var expanded = false;
217 | if(index != -1){
218 | expanded = isGroup;
219 | this.baseOpenPaths.splice(index, 1);
220 | }
221 |
222 | var subItems = isLayer ? DocUtils.getAllPageItems(doc, pageItem, true) : pageItem.pageItems;
223 |
224 | var visible = parentVis && ((isLayer && pageItem.visible) || (!isLayer && !pageItem.hidden));
225 | var itemData = { item:item, level:level, path:path, open:expanded, selected:item.selected, isGroup:isGroup, visible:visible, childrenBuilt:false, pageItems:subItems };
226 | item.itemData = itemData;
227 |
228 | childItems.push( itemData );
229 | this.items.push( itemData );
230 | itemsHere.push( itemData );
231 |
232 | if(isGroup){
233 | if(expanded) openLevel = level;
234 | this.createTreeElements(itemData, openLevel);
235 | item.expanded = expanded; // Must be done after adding children
236 | }
237 | }
238 | },
239 | onItemClick:function(item){
240 | if(item == null || this.ignoreChanges) return;
241 | var data = item.itemData;
242 | data.selected = !data.selected;
243 | item.selected = data.selected;
244 | item.image = File(pack.directory+"/icons/checkbox_"+(data.selected?"":"un")+"selected.png");
245 | this.checkSelection();
246 |
247 | this.elementTree.selection = null;
248 | },
249 | selectByLevel:function(select, level){
250 | var rootItems = this.itemsByLevel[0];
251 | this.ignoreChanges = true;
252 | for(var i=0; i.",
14 | DEFAULT_LAYER_PATTERN:"_.",
15 | DEFAULT_ELEMENT_PATTERN:"_.",
16 | DEFAULT_SYMBOL_PATTERN:".",
17 |
18 | type:ExportSettings,
19 |
20 | selectedTab:0,
21 | directory:"",
22 | formats:[],
23 |
24 | artboardAll:false,
25 | artboardInd:[],
26 |
27 | layerAll:false,
28 | layerInd:[],
29 | artboardAll_layers:true,
30 | artboardInd_layers:[],
31 |
32 | symbolAll:false,
33 | symbolNames:[],
34 |
35 | elementPaths:[], // e.g. ["layerInd : rootElemInd : childElemInd", "layerInd : rootElemInd : childElemInd"]
36 | elementOpenPaths:[], // e.g. ["layerInd : rootElemInd : childElemInd", "layerInd : rootElemInd : childElemInd"]
37 | artboardAll_elements:true,
38 | artboardInd_elements:[],
39 |
40 | //exportArtboards:false,
41 | ignoreWarnings:false,
42 | fontHandling:"none",
43 |
44 | ignoreOutOfBounds_layers:true,
45 | ignoreOutOfBounds_elements:true,
46 |
47 |
48 | toXML:function(includePatterns, includeGeneralSettings, includeFormatSettings, includeArtboards, includeLayers, includeElements, includeSymbols){
49 | if(includeGeneralSettings===undefined)includeGeneralSettings = true;
50 | if(includeFormatSettings===undefined)includeFormatSettings = true;
51 | if(includeArtboards===undefined)includeArtboards = true;
52 | if(includeLayers===undefined)includeLayers = true;
53 | if(includeElements===undefined)includeElements = true;
54 | if(includeSymbols===undefined)includeSymbols = true;
55 |
56 | var ret = new XML( '' );
57 |
58 | /*if(includePatterns){
59 | ret.appendChild( new XML(''+this.xmlEncode(this.artboardPattern)+'') );
60 | ret.appendChild( new XML(''+this.xmlEncode(this.layerPattern)+'') );
61 | }*/
62 | if(includeGeneralSettings){
63 | ret.appendChild( new XML(''+this.selectedTab+'') );
64 | ret.appendChild( new XML(''+this.directory+'') );
65 | ret.appendChild( new XML(''+this.ignoreWarnings+'') );
66 | ret.appendChild( new XML(''+this.ignoreOutOfBounds_layers+'') );
67 | ret.appendChild( new XML(''+this.ignoreOutOfBounds_elements+'') );
68 | }
69 |
70 | if(includeFormatSettings){
71 | var formats = new XML('');
72 | for(var i=0; i'+this.artboardInd+'') );
81 | else ret.appendChild( new XML(''+this.artboardAll+'') );
82 | }
83 |
84 | if(includeLayers){
85 | if(!this.layerAll && this.layerInd.length) ret.appendChild( new XML(''+this.layerInd+'') );
86 | else ret.appendChild( new XML(''+this.layerAll+'') );
87 | if(!this.artboardAll_layers && this.artboardInd_layers.length) ret.appendChild( new XML(''+this.artboardInd_layers+'') );
88 | else ret.appendChild( new XML(''+this.artboardAll_layers+'') );
89 | }
90 |
91 | if(includeElements){
92 | if(this.elementPaths.length){
93 | ret.appendChild( new XML(''+this.elementPaths.join(",")+'') );
94 | }
95 | if(this.elementOpenPaths.length){
96 | ret.appendChild( new XML(''+this.elementOpenPaths.join(",")+'') );
97 | }
98 | if(!this.artboardAll_elements && this.artboardInd_elements.length) ret.appendChild( new XML(''+this.artboardInd_elements+'') );
99 | else ret.appendChild( new XML(''+this.artboardAll_elements+'') );
100 | }
101 |
102 | if(includeSymbols){
103 | if(!this.symbolAll && this.symbolNames.length)ret.appendChild( new XML(''+this.symbolNames+'') );
104 | else ret.appendChild( new XML(''+this.symbolAll+'') );
105 | }
106 |
107 | return ret;
108 | },
109 |
110 | addNewFormat:function(formatSettings){
111 | this.formats.push(formatSettings);
112 |
113 | var defaultPatterns = {};
114 | var scaling;
115 | for(var i=this.formats.length-1; i>=0; --i){
116 | var format = this.formats[i];
117 | if(format.scaling)scaling = format.scaling;
118 | if(format==formatSettings)continue;
119 | for(var j in format.patterns){
120 | if(!defaultPatterns[j])defaultPatterns[j] = format.patterns[j];
121 | }
122 | }
123 | if(formatSettings.hasProp("scaling")){
124 | formatSettings.scaling = scaling || 100;
125 | }else{
126 | formatSettings.scaling = null;
127 | }
128 | if(!defaultPatterns.artboard) defaultPatterns.artboard = this.DEFAULT_ARTBOARD_PATTERN;
129 | if(!defaultPatterns.layer) defaultPatterns.layer = this.DEFAULT_LAYER_PATTERN;
130 | if(!defaultPatterns.element) defaultPatterns.element = this.DEFAULT_ELEMENT_PATTERN;
131 | if(!defaultPatterns.symbol) defaultPatterns.symbol = this.DEFAULT_SYMBOL_PATTERN;
132 |
133 | for(var j in defaultPatterns){
134 | if(!formatSettings.patterns[j]) formatSettings.patterns[j] = defaultPatterns[j];
135 | }
136 | },
137 |
138 | populateWithXML:function(xml){
139 | this.migrateXML(xml);
140 |
141 | //if(xml.artboardPattern.length())this.artboardPattern = xml.artboardPattern.toString() || this.DEFAULT_ARTBOARD_PATTERN;
142 | //if(xml.layerPattern.length())this.layerPattern = xml.layerPattern.toString() || this.DEFAULT_LAYER_PATTERN;
143 | if(xml.selectedTab.length())this.selectedTab = parseInt(xml.selectedTab.toString());
144 | if(xml.directory.length())this.directory = xml.directory.toString();
145 | if(xml.scaling.length())this.scaling = parseFloat( xml.scaling.toString().replace( /\% /, '' ));
146 |
147 | var defaultPatterns = {artboard:this.DEFAULT_ARTBOARD_PATTERN, layer:this.DEFAULT_LAYER_PATTERN, element:this.DEFAULT_ELEMENT_PATTERN, symbol:this.DEFAULT_SYMBOL_PATTERN};
148 | var formatNodes = xml.formats.format;
149 | if(formatNodes.length()){
150 | this.formats = [];
151 | for(var i=0; i"+node.suffix+".";
299 | node.layerPattern = node.prefix+"_"+node.suffix+".";
300 | delete node.prefix;
301 | delete node.suffix;
302 | }
303 | var base_path = node.base_path;
304 | if(base_path.length()){
305 | node.directory = base_path.toString();
306 | delete node.base_path;
307 | }
308 | var artboards = node.artboards;
309 | if(artboards.length()){
310 | var artboards = artboards.toString();
311 | if(artboards=="all"){
312 | node.artboardAll = "true";
313 | }else if(parseInt(artboards).toString()==artboards){
314 | node.artboardInd = artboards;
315 | }
316 | delete node.artboards;
317 | }
318 | var layers = node.layers;
319 | if(layers.length()){
320 | var layers = layers.toString();
321 | if(layers=="all"){
322 | node.layerAll = "true";
323 | }else if(parseInt(layers).toString()==layers){
324 | node.layerInd = layers;
325 | }
326 | delete node.layers;
327 | }
328 | if(node.elementPaths == null){
329 | node.elementPaths = [];
330 | }
331 | if(node.elementOpenPaths == null){
332 | node.elementOpenPaths = [];
333 | }
334 | var format = node.format;
335 | if(format.length()){
336 |
337 | var formats = new XML('');
338 | var formatNode = new XML('');
339 |
340 | formatNode.format = node.format;
341 | formatNode.transparency = node.transparency;
342 | formatNode.embedImage = node.embedImage;
343 | formatNode.fontHandling = (node.embedFont?"embed":"none");
344 | formatNode.trimEdges = node.trimEdges;
345 | formatNode.innerPadding = node.innerPadding;
346 |
347 | formats.appendChild(formatNode);
348 | node.appendChild(formats);
349 |
350 | delete node.format;
351 | delete node.transparency;
352 | delete node.embedImage;
353 | delete node.embedFont;
354 | delete node.trimEdges;
355 | delete node.innerPadding;
356 | }
357 | var formats = node.formats.format;
358 | if(formats.length()){
359 | for(var i=0; i"));
363 | }
364 | if(node.artboardPattern.length() && formatNode.patterns.artboard.length()==0){
365 | formatNode.patterns.artboard = node.artboardPattern.toString();
366 | }
367 | if(node.layerPattern.length() && formatNode.patterns.layer.length()==0){
368 | formatNode.patterns.layer = node.layerPattern.toString();
369 | }
370 | if(node.scaling && formatNode.scaling.length()==0){
371 | formatNode.scaling = node.scaling.toString();
372 | }
373 | if(formatNode.trimEdges && formatNode.trimEdges.length()!=0){
374 | var trim = formatNode.trimEdges.toString() == 'true';
375 | if(formatNode.boundsMode.length() == 0){
376 | formatNode.boundsMode = trim ? pack.BoundsMode.ARTBOARD_AND_ARTWORK : pack.BoundsMode.ARTBOARD;
377 | }
378 | delete formatNode.trimEdges;
379 | }
380 | }
381 | delete node.artboardPattern;
382 | delete node.layerPattern;
383 | delete node.scaling;
384 | }
385 | }/*,
386 | xmlEncode:function(str){
387 | str = str.split("&").join("&");
388 | str = str.split("<").join("<");
389 | str = str.split(">").join(">");
390 | str = str.split('"').join(""");
391 | str = str.split("'").join("'");
392 | return str;
393 | }*/
394 | };
395 | pack.ExportSettings = ExportSettings;
396 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/LayerBundler.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | LayerBundler = {};
3 |
4 | LayerBundler.NO_COPY = "noCopy";
5 |
6 |
7 | LayerBundler.addElements = function(docRef, bundles, exportSettings, patternName, hasBoundErrorRef, elemVis){
8 |
9 | LayerBundler.hasBoundErrorRef = hasBoundErrorRef;
10 |
11 |
12 | var artboardInd = exportSettings.artboardInd_elements;
13 | var elementPaths = exportSettings.elementPaths;
14 |
15 | var hasExports = false;
16 |
17 | if(!elementPaths.length)return;
18 |
19 | for (var i = 0; i < artboardInd.length; i++ ) {
20 | var artI = artboardInd[i];
21 | if(artI >= docRef.artboards.length)continue;
22 | var artboard = docRef.artboards[artI];
23 |
24 | for ( var j=0; j < elementPaths.length; j++ ) {
25 | var path = elementPaths[j];
26 | var pathParts = path.split(":");
27 | var layI = parseInt(pathParts[0]) - 1;
28 | if(layI >= docRef.layers.length)continue;
29 |
30 | var layer = docRef.layers[layI];
31 |
32 | var layerPath = (layI + 1) + "";
33 |
34 | var element;
35 | var searchPath;
36 | if(layerPath == path){
37 | element = layer;
38 | }else{
39 | searchPath = path;
40 | element = LayerBundler.findElement(layerPath, layer.pageItems, path);
41 | if(element == null) continue;
42 | }
43 |
44 | var bundleMap = {};
45 |
46 | for (var x = 0; x < exportSettings.formats.length; x++ ) {
47 | var formatSettings = exportSettings.formats[x];
48 | var filePattern = formatSettings.patterns[patternName];
49 | if(!formatSettings.active || filePattern == "" || filePattern == null) continue;
50 |
51 | var format = formatSettings.formatRef;
52 |
53 |
54 | var bundle = this.getBundle(bundleMap, artI, layI, formatSettings.innerPadding, formatSettings.scaling, formatSettings.boundsMode, format.copyBehaviour, formatSettings.fontHandling=="outline", exportSettings.ignoreOutOfBounds_elements, formatSettings.ungroup, j==0, j==elementPaths.length-1, elemVis, formatSettings.colorSpace, formatSettings.rasterResolution, searchPath);
55 | var elemName = (element.name || path);
56 | var name = LayerBundler.makeElemFileName(filePattern, docRef.fullName.name, formatSettings.formatRef.ext, artI, artboard.name, layI, layer.name, path, elemName);
57 | var item = new pack.ExportItem(formatSettings, name);
58 | item.names = ["Artboard "+(artI+1), "Element "+path];
59 | bundle.items.push(item);
60 |
61 | hasExports = true;
62 | }
63 |
64 | for(var k in bundleMap){
65 | bundle = bundleMap[k];
66 | if(bundle.items.length){
67 | bundles.push(bundle);
68 | }
69 | }
70 | }
71 | }
72 | return hasExports;
73 | }
74 | LayerBundler.addLayers = function(docRef, bundles, exportSettings, patternName, hasBoundErrorRef, elemVis){
75 |
76 | LayerBundler.hasBoundErrorRef = hasBoundErrorRef;
77 |
78 | var artboardInd = exportSettings.artboardInd_layers;
79 | var layerInd = exportSettings.layerInd;
80 |
81 | var hasExports = false;
82 |
83 | if(!layerInd.length)return;
84 |
85 | for (var i = 0; i < artboardInd.length; i++ ) {
86 | var artI = artboardInd[i];
87 | if(artI >= docRef.artboards.length)continue;
88 | var artboard = docRef.artboards[artI];
89 |
90 | for ( var j=0; j < layerInd.length; j++ ) {
91 | var layI = layerInd[j];
92 | if(layI >= docRef.layers.length)continue;
93 |
94 | var layer = docRef.layers[layI];
95 |
96 | var bundleMap = {};
97 |
98 | for (var x = 0; x < exportSettings.formats.length; x++ ) {
99 | var formatSettings = exportSettings.formats[x];
100 | var filePattern = formatSettings.patterns[patternName];
101 | if(!formatSettings.active || filePattern == '' || filePattern == null) continue;
102 |
103 | var format = formatSettings.formatRef;
104 |
105 |
106 | var bundle = this.getBundle(bundleMap, artI, layI, formatSettings.innerPadding, formatSettings.scaling, formatSettings.boundsMode, format.copyBehaviour, formatSettings.fontHandling=="outline", exportSettings.ignoreOutOfBounds_layers, formatSettings.ungroup, j==0, j==layerInd.length-1, elemVis, formatSettings.colorSpace, formatSettings.rasterResolution);
107 | var item = new pack.ExportItem(formatSettings, LayerBundler.makeFileName(filePattern, docRef.fullName.name, formatSettings.formatRef.ext, artI, artboard.name, layI, layer.name));
108 | item.names = ["Artboard "+(artI+1), "Layer "+(layI+1)];
109 | bundle.items.push(item);
110 |
111 | hasExports = true;
112 | }
113 |
114 | for(var k in bundleMap){
115 | bundle = bundleMap[k];
116 | if(bundle.items.length){
117 | bundles.push(bundle);
118 | }
119 | }
120 | }
121 | }
122 | return hasExports;
123 | }
124 | LayerBundler.getBundle = function(bundleMap, artI, layI, padding, scaling, boundsMode, forceCopy, doOutline, ignoreOutOfBounds, ungroup, isFirst, isLast, elemVis, colorSpace, rasterResolution, elemPath){
125 | // TODO: Remove 'elemPath' from this check after testing it using show/hide & reused doc methods
126 | var trim = boundsMode != pack.BoundsMode.ARTBOARD;
127 | if(trim || doOutline || padding || colorSpace) forceCopy = true;
128 |
129 | var key;
130 | if(!forceCopy){
131 | key = this.NO_COPY;
132 | }else{
133 | key = boundsMode+"_"+(doOutline?"outline":"nooutline")+"_"+(padding?"pad":"nopad")+(ungroup?"_ungroup":"") + (colorSpace==null ? "" : "_"+colorSpace) + (rasterResolution==null ? "" : "_"+rasterResolution) + (elemPath==null ? "" : "_"+elemPath);
134 | }
135 | var bundle = bundleMap[key];
136 | if(bundle){
137 | return bundle;
138 |
139 | }else if(!forceCopy){
140 | // export types which don't require a new document to be created just show/hide layers to complete export. (No pad, no trim, raster exports)
141 | bundle = new pack.ExportBundle();
142 | bundle.prepareHandler = isFirst ? closure(LayerBundler, LayerBundler.prepareShowLayerFirst, [artI, layI, elemPath], true) : closure(LayerBundler, LayerBundler.prepareShowLayer, [artI, layI, elemPath], true);
143 | bundle.cleanupHandler = isLast ? closure(LayerBundler, LayerBundler.cleanupShowLayerLast, [elemVis, layI], true) : closure(LayerBundler, LayerBundler.cleanupShowLayer, [elemVis, artI, layI, elemPath], true);
144 |
145 | }else if(!trim){
146 | // non-trimmed export types can simply create a new document once for each artboard. (no trim, vector exports)
147 | bundle = new pack.ExportBundle();
148 | bundle.prepareHandler = isFirst ? closure(LayerBundler, LayerBundler.prepareCopyDoc, [artI, layI, padding, doOutline, ignoreOutOfBounds, ungroup, elemVis, colorSpace, rasterResolution, elemPath, boundsMode], true) : closure(LayerBundler, LayerBundler.prepareCopyLayer, [artI, layI, padding, doOutline, ignoreOutOfBounds, ungroup, false, elemVis, null, colorSpace, rasterResolution, elemPath, boundsMode], true);
149 | bundle.cleanupHandler = isLast ? LayerBundler.cleanupCopyDoc : LayerBundler.cleanupCopyLayer;
150 |
151 | }else{
152 | // trimmed export types must create a new document for each artboard/layer/elem pair. (No pad, trim, vector exports)
153 | bundle = new pack.ExportBundle();
154 | bundle.prepareHandler = closure(LayerBundler, LayerBundler.prepareCopyLayer, [artI, layI, padding, doOutline, ignoreOutOfBounds, ungroup, true, elemVis, null, colorSpace, rasterResolution, elemPath, boundsMode], true);
155 | bundle.cleanupHandler = LayerBundler.cleanupCopyDoc;
156 |
157 | }
158 | bundleMap[key] = bundle;
159 | return bundle;
160 | }
161 |
162 | LayerBundler.prepareCopyDoc = function(docRef, exportSettings, exportBundle, artI, layI, padding, doOutline, ignoreOutOfBounds, ungroup, elemVis, colorSpace, rasterResolution, elemPath, boundsMode){
163 | var artboard = docRef.artboards[artI];
164 | docRef.artboards.setActiveArtboardIndex(artI);
165 |
166 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
167 | var rect = artboard.artboardRect;
168 | var artW = rect[2]-rect[0];
169 | var artH = rect[1]-rect[3];
170 |
171 | //var offset = {x:0, y:0};
172 | LayerBundler.layerDepths = [];
173 | LayerBundler.copyDoc = pack.DocUtils.copyDocument(docRef, artboard, rect, artW, artH, padding, pack.DocUtils.isAdditionalLayer, LayerBundler.layerDepths, doOutline, ungroup, elemVis, exportSettings.ignoreWarnings, LayerBundler.hasBoundErrorRef, null, colorSpace, rasterResolution);
174 | LayerBundler.hasAdditLayers = LayerBundler.copyDoc.layers.length > 0 && (LayerBundler.copyDoc.layers.length!=1 || LayerBundler.copyDoc.layers[0].pageItems.length || LayerBundler.copyDoc.layers[0].layers.length);
175 | return this.prepareCopyLayer(docRef, exportSettings, exportBundle, artI, layI, padding, doOutline, ignoreOutOfBounds, ungroup, false, elemVis, rect, colorSpace, rasterResolution, elemPath, boundsMode);
176 | }
177 | LayerBundler.prepareCopyLayer = function(docRef, exportSettings, exportBundle, artI, layI, padding, doOutline, ignoreOutOfBounds, ungroup, createDoc, elemVis, rect, colorSpace, rasterResolution, elemPath, boundsMode){
178 | //docRef.artboards.setActiveArtboardIndex(artI); // throws an error if new doc has already been created (can't change artboard when doc isn't in focus)
179 | var doc = LayerBundler.copyDoc || docRef;
180 |
181 | if(LayerBundler.copyDoc) app.activeDocument = docRef; // can't access artboard props when owner doc isn't in focus
182 | var layer = docRef.layers[layI];
183 | var artboard = docRef.artboards[artI];
184 | if(!rect){
185 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
186 | rect = artboard.artboardRect;
187 | }
188 | var artboardName = artboard.name;
189 |
190 | if(LayerBundler.copyDoc)app.activeDocument = doc;
191 |
192 | var elemFilter = (elemPath == null ? null : closure(LayerBundler, LayerBundler.filterElements, [elemPath], true));
193 | if(elemFilter == null && boundsMode == pack.BoundsMode.ARTWORK) elemFilter = closure(LayerBundler, ungroup ? LayerBundler.filterByVisibleUngroup : LayerBundler.filterByVisible, [], true);
194 |
195 | // only process layer if it has bounds (i.e. not guide layer) and falls within current artboard bounds
196 | var layerRect = pack.DocUtils.getLayerBounds(docRef, layer, null, elemFilter);
197 | if (layerRect) {
198 | var isVis = boundsMode == pack.BoundsMode.ARTWORK || (!ignoreOutOfBounds || pack.DocUtils.intersects(rect, layerRect));
199 | if((createDoc || !LayerBundler.hasAdditLayers) && !isVis){
200 | // skip layers where nothing is visible
201 | return "skipped";
202 | }
203 | if(createDoc){
204 |
205 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
206 |
207 | var layerOffsetX = 0;
208 | var layerOffsetY = 0;
209 |
210 | // crop to artboard
211 | if(boundsMode == pack.BoundsMode.ARTBOARD_AND_ARTWORK){
212 | if(layerRect[0]rect[1]){
216 | layerRect[1] = rect[1];
217 | }
218 | if(layerRect[2]>rect[2]){
219 | layerRect[2] = rect[2];
220 | }
221 | if(layerRect[3] 0 && (doc.layers.length!=1 || doc.layers[0].pageItems.length || doc.layers[0].layers.length);
238 | }else{
239 | layOffset = null;
240 | }
241 | if(isVis){
242 | // only copy layer if it is visible (if not only visible '+' layers will be output)
243 | var artb = doc.artboards[0];
244 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
245 | var new_layer = pack.DocUtils.copyLayer(docRef, LayerBundler.copyDoc, artb, LayerBundler.copyDoc.artboards[0], rect, layer, doc.layers.add(), padding, doOutline, ungroup, docRef.rulerOrigin, exportSettings.ignoreWarnings, LayerBundler.hasBoundErrorRef, layOffset, elemFilter);
246 | new_layer.visible = true;
247 | var depth = LayerBundler.layerDepths[layI];
248 | pack.DocUtils.setLayerDepth(new_layer, depth);
249 | exportBundle.copyLayer = new_layer;
250 | }
251 | return doc;
252 | }
253 |
254 | return null;
255 | }
256 | LayerBundler.filterElements = function(element, path, matchPath){
257 | if(matchPath == path){
258 | return true;
259 | }else if(matchPath.indexOf(path) == 0){
260 | return 'explore';
261 | }
262 | return false;
263 | }
264 | LayerBundler.filterByVisibleUngroup = function(element, path){
265 | if(element.hidden){
266 | return false;
267 | }else{
268 | return 'explore';
269 | }
270 | }
271 | LayerBundler.filterByVisible = function(element, path){
272 | if(element.hidden){
273 | return false;
274 | }else{
275 | return true;
276 | }
277 | }
278 | LayerBundler.prepareShowLayerFirst = function(docRef, exportSettings, exportBundle, artI, layI, elemPath){
279 | pack.DocUtils.hideAllLayers(docRef);
280 |
281 | exportBundle.hasOrigAdditLayers = false;
282 | for(var i=0; i 1){
193 | this.tabPanel = new pack.MainTabbedPanel( this.toolPanel, 160, 480 );
194 | this.tabPanel.onChange = function(byUser){
195 | if(byUser){
196 | exSettings.selectedTab = scopedThis.tabPanel.selection;
197 | }
198 | }
199 | }
200 |
201 | if(showParts.layers){
202 | var tab = this.tabPanel ? this.tabPanel.add("Layers") : this.toolPanel.add("panel");
203 | tab.orientation = "row";
204 |
205 | this.artboardPanel_layers = new pack.ArtboardPanel(tab, exSettings.artboardAll_layers, exSettings.artboardInd_layers, true);
206 | this.artboardPanel_layers.onSelectedChanged = function() {
207 | exSettings.artboardAll_layers = scopedThis.artboardPanel_layers.selectAll;
208 | exSettings.artboardInd_layers = scopedThis.artboardPanel_layers.selectedIndices;
209 | scopedThis.updatePreviewList();
210 | };
211 | this.artboardPanel_layers.onSelectedChanged();
212 |
213 | this.layerPanel = new pack.LayerPanel(tab, exSettings.layerAll, exSettings.layerInd, pack.IGNORE_LAYERS, exSettings.ignoreOutOfBounds_layers);
214 | this.layerPanel.onSelectedChanged = function() {
215 | exSettings.layerAll = scopedThis.layerPanel.selectAll;
216 | exSettings.layerInd = scopedThis.layerPanel.selectedIndices;
217 | scopedThis.updatePreviewList();
218 | };
219 | this.layerPanel.onIgnoreOutOfBoundsChanged = function() {
220 | exSettings.ignoreOutOfBounds_layers = scopedThis.layerPanel.ignoreOutOfBounds;
221 | };
222 | }
223 |
224 | if(showParts.artboards){
225 | var tab = this.tabPanel ? this.tabPanel.add("Artboards") : this.toolPanel.add("panel");
226 | tab.orientation = "row";
227 |
228 | this.artboardPanel = new pack.ArtboardPanel(tab, exSettings.artboardAll, exSettings.artboardInd);
229 | this.artboardPanel.onSelectedChanged = function() {
230 | exSettings.artboardAll = scopedThis.artboardPanel.selectAll;
231 | exSettings.artboardInd = scopedThis.artboardPanel.selectedIndices;
232 | scopedThis.updatePreviewList();
233 | };
234 | this.artboardPanel.onSelectedChanged();
235 | }
236 |
237 | if(showParts.elements){
238 | var tab = this.tabPanel ? this.tabPanel.add("Elements") : this.toolPanel.add("panel");
239 | tab.orientation = "row";
240 |
241 | this.artboardPanel_elements = new pack.ArtboardPanel(tab, exSettings.artboardAll_elements, exSettings.artboardInd_elements, true);
242 | this.artboardPanel_elements.onSelectedChanged = function() {
243 | exSettings.artboardAll_elements = scopedThis.artboardPanel_elements.selectAll;
244 | exSettings.artboardInd_elements = scopedThis.artboardPanel_elements.selectedIndices;
245 | scopedThis.updatePreviewList();
246 | };
247 | this.artboardPanel_elements.onSelectedChanged();
248 |
249 | this.elementPanel = new pack.ElementPanel(tab, exSettings.elementPaths, exSettings.elementOpenPaths, pack.IGNORE_LAYERS, exSettings.ignoreOutOfBounds_elements);
250 | this.elementPanel.onSelectedChanged = function() {
251 | exSettings.elementPaths = scopedThis.elementPanel.selectedPaths;
252 | exSettings.elementOpenPaths = scopedThis.elementPanel.openPaths;
253 | scopedThis.updatePreviewList();
254 | };
255 | this.elementPanel.onOpenedChanged = function() {
256 | exSettings.elementOpenPaths = scopedThis.elementPanel.openPaths;
257 | };
258 | this.elementPanel.onIgnoreOutOfBoundsChanged = function() {
259 | exSettings.ignoreOutOfBounds_elements = scopedThis.elementPanel.ignoreOutOfBounds;
260 | };
261 |
262 | if(this.tabPanel) this.tabPanel.setTransHandlers(this.tabPanel.panels.length - 1, closure(this.elementPanel, this.elementPanel.show));
263 | else this.elementPanel.show();
264 | }
265 |
266 | if(showParts.symbols){
267 | var tab = this.tabPanel ? this.tabPanel.add("Symbols") : this.toolPanel.add("panel");
268 | tab.orientation = "row";
269 |
270 | this.symbolPanel = new pack.SymbolPanel(tab, exSettings.symbolAll, exSettings.symbolNames);
271 | this.symbolPanel.onSelectedChanged = function() {
272 | exSettings.symbolAll = scopedThis.symbolPanel.selectAll;
273 | exSettings.symbolNames = scopedThis.symbolPanel.selectedNames;
274 | scopedThis.updatePreviewList();
275 | };
276 | }
277 |
278 | if(showParts.formats){
279 | var tab = this.tabPanel ? this.tabPanel.add("Export Settings", pack.Button.STYLE_MAIN_TAB_OUTPUT) : this.toolPanel.add("panel");
280 | var settingsCol = tab;
281 |
282 | var column;
283 | var row;
284 |
285 | this.settingsPanel = new pack.SettingsPanel(settingsCol, this.exportSettings);
286 | this.settingsPanel.onPatternChanged = function(){
287 | scopedThis.updatePreviewList();
288 | }
289 |
290 | this.formatPanel = new pack.FormatPanel(settingsCol, pack.formats, this.exportSettings);
291 | this.formatPanel.onFormatsChanged = function(){
292 | scopedThis.updatePreviewList();
293 | }
294 | }
295 |
296 |
297 | if(showParts.preview){
298 | var tab = this.tabPanel ? this.tabPanel.add("Output Files", pack.Button.STYLE_MAIN_TAB_OUTPUT) : this.toolPanel.add("panel");
299 | this.previewPanel = new pack.PreviewFilesPanel(tab);
300 |
301 | if(this.tabPanel){
302 | this.outputTabIndex = this.tabPanel.panels.length - 1;
303 | this.tabPanel.setTransHandlers(this.outputTabIndex, closure(this.previewPanel, this.previewPanel.show), closure(this.previewPanel, this.previewPanel.hide));
304 | }else this.previewPanel.show();
305 | }
306 |
307 | if(showParts.progress){
308 | // progress bar
309 | this.progBar = this.toolPanel.add( 'progressbar', undefined, 0, 100 );
310 | this.progBar.alignment = [ScriptUI.Alignment.RIGHT, ScriptUI.Alignment.TOP];
311 | this.progBar.size = [665,10];
312 | }
313 |
314 | if(showParts.exportButtons){
315 | this.exportPanel = new pack.ExportPanel(this.toolPanel, this.exportSettings);
316 | this.exportPanel.onCancelClicked = function() {
317 | if(scopedThis.exporter.running){
318 | scopedThis.exporter.cancel();
319 | }else{
320 | scopedThis.toolPanel.close();
321 | }
322 | };
323 | this.exportPanel.onSaveCloseClicked = function() {
324 | scopedThis.saveOptions();
325 | scopedThis.toolPanel.close()
326 | };
327 | this.exportPanel.onExportClicked = closure(this, this.beginExport);
328 | }
329 |
330 | this.exporter = new pack.Exporter(this.exportSettings,
331 | function(prog, total){scopedThis.setProgress(prog, total)},
332 | function(item){scopedThis.previewPanel.updatedExportItem(item); scopedThis.toolPanel.update();});
333 |
334 | this.exporter.onExportFinished = function(success, fail){
335 | if(success){
336 | scopedThis.toolPanel.close();
337 | }
338 | }
339 |
340 |
341 | this.elemVis = pack.DocUtils.getAllElemVisibility(this.docRef);
342 |
343 | if(this.artboardPanel) this.artboardPanel.onSelectedChanged();
344 | if(this.layerPanel) this.layerPanel.onSelectedChanged();
345 | if(this.elementPanel) this.elementPanel.onSelectedChanged();
346 | if(this.symbolPanel) this.symbolPanel.onSelectedChanged();
347 |
348 | if(this.tabPanel) this.tabPanel.setSelection(exSettings.selectedTab);
349 |
350 | this.finishedBuilding = true;
351 | this.updatePreviewList();
352 |
353 | if(this.autoExport){
354 | this.toolPanel.onActivate = function(e){
355 | scopedThis.toolPanel.onActivate = null;
356 | scopedThis.beginExport(false);
357 | }
358 | }
359 |
360 | this.toolPanel.show();
361 | },
362 |
363 | beginExport:function(save) {
364 | if(save == null) save = true;
365 | try{
366 | this.hasBoundErrorRef.broken = 0;
367 | if(save) this.saveOptions(); // save options before export in case of errors
368 |
369 | var dir = this.exportSettings.directory || "";
370 | if($.os.toLowerCase().indexOf("mac")!=-1){
371 | if(dir.charAt(0)!="/"){
372 | dir = this.docRef.path + "/" + dir;
373 | }
374 | }else{
375 | if(dir.indexOf(":")==-1){
376 | dir = this.docRef.path + "\\" + dir;
377 | }
378 | }
379 | var ran = this.exporter.checkValid(this.bundleList, this.exportSettings, dir);
380 | if(ran){
381 | if(this.tabPanel) this.tabPanel.setSelection(this.outputTabIndex);
382 | this.exporter.doRun();
383 | if(this.hasBoundErrorRef.broken){
384 | var layerName = ( this.hasBoundErrorRef.broken==1 ? "A layer" : this.hasBoundErrorRef.broken+" layers");
385 | alert(layerName+" couldn't be positioned correctly due to an Illustrator bug, if there are alignment problems in the exported files please export again with warnings turned on.\n\nYou'll have to click through warnings but the exports should be aligned properly.");
386 | }
387 | }
388 | }catch(e){
389 | alert("Error running export: "+e);
390 | }
391 | },
392 |
393 | setProgress:function(prog, total){
394 | if(!this.progBar) return;
395 | this.progBar.value = prog / total * 100;
396 | },
397 |
398 | updatePreviewList:function(){
399 | if(!this.finishedBuilding) return;
400 | try{
401 | this.bundleList = [];
402 | this.hasBoundErrorRef = {};
403 |
404 | var hasExports = pack.ArtboardBundler.add(this.docRef, this.bundleList, this.exportSettings, "artboard", this.hasBoundErrorRef);
405 | if(this.formatPanel) this.formatPanel.setPatternActive("artboard", hasExports);
406 |
407 | var hasExports = pack.LayerBundler.addLayers(this.docRef, this.bundleList, this.exportSettings, "layer", this.hasBoundErrorRef, this.elemVis);
408 | if(this.formatPanel) this.formatPanel.setPatternActive("layer", hasExports);
409 |
410 | var hasExports = pack.LayerBundler.addElements(this.docRef, this.bundleList, this.exportSettings, "element", this.hasBoundErrorRef, this.elemVis);
411 | if(this.formatPanel) this.formatPanel.setPatternActive("element", hasExports);
412 |
413 | var hasExports = pack.SymbolBundler.add(this.docRef, this.bundleList, this.exportSettings, "symbol");
414 | if(this.formatPanel) this.formatPanel.setPatternActive("symbol", hasExports);
415 |
416 | var windowsFS = (Folder.fs=="Windows");
417 | if(windowsFS){
418 | for(var i=0; i").join("-");
429 | path = path.split('"').join("'");
430 | path = path.split(':').join(";");
431 | item.fileName = path;
432 | }
433 | }
434 | }else{
435 | for(var i=0; i=selectList.length){
475 | return index-selectList.length;
476 | }else{
477 | return selectList[index].code;
478 | }
479 | },
480 |
481 | saveOptions:function(){
482 | var exSettings = this.exportSettings;
483 |
484 | this.smartExportPrefs.textFrames[0].contents = exSettings.toXML().toXMLString();
485 | this.smartExportPrefs.name = this.prefsLayerName;
486 | }
487 | };
488 | pack.ExportToolBuilder = ExportToolBuilder;
489 | })(smartExport)
--------------------------------------------------------------------------------
/SmartCore/DocUtils.jsx:
--------------------------------------------------------------------------------
1 | (function(pack){
2 | DocUtils = {};
3 |
4 |
5 |
6 | DocUtils.copyDocument = function(docRef, artboard, artboardRect, w, h, doInnerPadding, layerCheck, layerDepths, outlineText, ungroup, layerVis, ignoreWarnings, hasBoundErrorRef, offset, colorSpace, rasterResolution) {
7 | if(w<1)w = 1;
8 | if(h<1)h = 1;
9 | var preset = new DocumentPreset();
10 | preset.width = w;
11 | preset.height = h;
12 | preset.units = docRef.rulerUnits;
13 |
14 | if(rasterResolution == "screen"){
15 | preset.rasterResolution = DocumentRasterResolution.ScreenResolution;
16 | }else if(rasterResolution == "medium"){
17 | preset.rasterResolution = DocumentRasterResolution.MediumResolution;
18 | }else{
19 | preset.rasterResolution = DocumentRasterResolution.HighResolution;
20 | }
21 |
22 | if(colorSpace == "cmyk"){
23 | preset.colorMode = DocumentColorSpace.CMYK;
24 | }else if(colorSpace == "rgb"){
25 | preset.colorMode = DocumentColorSpace.RGB;
26 | }else{
27 | preset.colorMode = docRef.documentColorSpace;
28 | }
29 |
30 | var copyDoc = app.documents.addDocument(preset.colorMode, preset);
31 | copyDoc.artboards.setActiveArtboardIndex(0);
32 | var copyArtboard = copyDoc.artboards[0];
33 | copyArtboard.shift = null; // Illustrator seems to reuse instances behind the scenes
34 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
35 | copyDoc.isNew = true;
36 | try{
37 | //app.activeDocument = docRef; // this allows us to do the selection trick when copying layers
38 |
39 | // for some mystical reason, setting these can mess up the artboard dimensions
40 | //copyDoc.pageOrigin = docRef.pageOrigin;
41 | //copyDoc.rulerOrigin = docRef.rulerOrigin;
42 |
43 | var count = 1; // indices are 1 based!
44 | var n = docRef.layers.length;
45 | for ( var j=docRef.layers.length-1; j >= 0; j-- ) {
46 | layer = docRef.layers[j];
47 |
48 | var vis = (layerVis ? layerVis[j] : layer.visible );
49 | if (layerCheck==null || layerCheck(layer, vis)) {
50 | //var layerBounds = this.getLayerBounds(docRef, layer);
51 | //if(layerBounds && this.intersects(artboardRect, layerBounds)){
52 | var newLayer = this.copyLayer(docRef, copyDoc, artboard, copyArtboard, artboardRect, layer, copyDoc.layers.add(), doInnerPadding, outlineText, ungroup, docRef.rulerOrigin, ignoreWarnings, hasBoundErrorRef, offset);
53 | this.setLayerDepth(newLayer, count);
54 | if(!newLayer.pageItems.length && !newLayer.layers.length){
55 | newLayer.remove();
56 | }else{
57 | ++count;
58 | }
59 | //}
60 | }else if(layerDepths){
61 | layerDepths[j] = count;
62 | }
63 | }
64 |
65 | return copyDoc;
66 | }catch(e){
67 | alert("DocUtils.copyDocument failed:\n"+e);
68 | copyDoc.close(SaveOptions.DONOTSAVECHANGES);
69 | }
70 | }
71 | DocUtils.rectEqual = function(rect1, rect2) {
72 | return rect1[0]==rect2[0] && rect1[1]==rect2[1] && rect1[2]==rect2[2] && rect1[3]==rect2[3] ;
73 | }
74 |
75 | DocUtils.getArtboardShift = function(artboardRect, toArtboard) {
76 | var toRect = toArtboard.artboardRect;
77 | return {x:toRect[0] - artboardRect[0], y:toRect[3] - artboardRect[3]};
78 | }
79 |
80 | DocUtils.getLayerIndex = function(layers, layer){
81 | for(var i=0; i=0; --j){
157 | var child = children[j];
158 | child.move(item, ElementPlacement.PLACEAFTER);
159 | this.doUngroupItem(child);
160 | }
161 | item.remove();
162 | }
163 | }
164 | DocUtils.getLayerBounds = function(doc, layer, artboardRect, elemFilter, parentPath) {
165 | var rect;
166 | var items = DocUtils.getAllPageItems(doc, layer, true);
167 |
168 | if(parentPath == null) parentPath = (DocUtils.getLayerIndex(doc.layers, layer) + 1) + "";
169 | parentPath += ":";
170 |
171 | var childFilter = elemFilter;
172 | for(var i=0; iitemBounds[0]){
204 | rect[0] = itemBounds[0];
205 | }
206 | if(rect[1]itemBounds[3]){
213 | rect[3] = itemBounds[3];
214 | }
215 | }
216 | }
217 |
218 | if(rect && rect[0]rect[3]){
219 | return rect;
220 | }else{
221 | return null;
222 | }
223 | }
224 |
225 | DocUtils.artboardIntersects = function(docRef, artI, rect){
226 | var artboard = docRef.artboards[artI];
227 | app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
228 | var artRect = artboard.artboardRect;
229 | return this.intersects(artRect, rect);
230 | }
231 |
232 | DocUtils.copyIntoLayer = function(doc, fromLayer, toLayer, ignoreWarnings, artboardRect, parentPath, elemFilter) {
233 | var items = this.getAllPageItems(doc, fromLayer, ignoreWarnings);
234 | try{
235 | this.copyItems(doc, items, toLayer, ignoreWarnings, artboardRect, parentPath, elemFilter);
236 | }catch(e){
237 | alert("Copy items failed: "+e);
238 | }
239 | }
240 |
241 | DocUtils.copyItems = function(doc, fromList, toLayer, ignoreWarnings, artboardRect, parentPath, elemFilter) {
242 | parentPath += ":";
243 | var visWas = toLayer.visible;
244 | toLayer.visible = true;
245 | for(var i=0; idepth){
324 | layer.zOrder(ZOrderMethod.SENDBACKWARD);
325 | }
326 | }
327 |
328 | DocUtils.intersects = function(rect1, rect2) {
329 | return !( rect2[0] > rect1[2] ||
330 | rect2[1] < rect1[3] ||
331 | rect2[2] < rect1[0] ||
332 | rect2[3] > rect1[1]);
333 | }
334 |
335 | var setGetVisiblity = function(visState, doc, elems, path, ignoreWarnings, isSetting){
336 | if(path == null) path = "";
337 | else path += ":";
338 |
339 | for(var i=0; i=0; --i){
464 | this.shiftLayer(layer.layers[i], shiftX, shiftY)
465 | }
466 | }
467 |
468 | DocUtils.doOutlineLayer = function(layer) {
469 | this.doOutlineItems(layer.pageItems);
470 | for(var i=0; ivisBounds[0]){
522 | rect[0] = visBounds[0];
523 | }
524 | if(rect[1]visBounds[3]){
531 | rect[3] = visBounds[3];
532 | }
533 | }
534 | }
535 | if(maskRect && rect){
536 | if(rect[0]maskRect[1]){
540 | rect[1] = maskRect[1];
541 | }
542 | if(rect[2]>maskRect[2]){
543 | rect[2] = maskRect[2];
544 | }
545 | if(rect[3]