├── .debug ├── CSXS └── manifest.xml ├── LICENSE ├── README.md ├── client ├── FullPad.svg ├── bodymovin.js ├── data.json ├── dead.js ├── iconFonts.css ├── index.html ├── main.js ├── myTstack │ ├── CSInterface.js │ ├── ReqLibs.js │ ├── adobeStyle.css │ ├── eventManager.js │ ├── magicMirror.js │ ├── menu_Context.js │ ├── menu_Flyout.js │ ├── mightyFiles.js │ ├── mightyFunctions.js │ └── reset.css └── style.css ├── host ├── AEFT.jsx ├── ILST.jsx ├── PHXS.jsx ├── align.jsx ├── smartAlign.jsx └── universal │ ├── Console.jsx │ └── json2.jsx ├── icons ├── iconLight.png └── iconLightRollover.png ├── log └── scribe.js └── resources ├── Icons.ai ├── Smart-Align32 ├── Read Me.txt ├── demo-files │ ├── demo.css │ └── demo.js ├── demo.html ├── fonts │ ├── Smart-Align32.svg │ ├── Smart-Align32.ttf │ └── Smart-Align32.woff ├── selection.json └── style.css ├── SmartAlign1.1.ai ├── SmartAlign1.1.svg ├── ToolbarFonts.ai ├── artB.svg ├── fonts ├── Smart-Align32.svg ├── Smart-Align32.ttf └── Smart-Align32.woff ├── old ├── FullPad.aep ├── FullPad.svg ├── FullPad2.svg ├── PanelIcons.ai ├── Proto1Pad.svg ├── Smart-Align32.zip ├── SmartAlign.aia ├── SmartAlign1.0.ai └── SmartAlign1.1.svg └── svg ├── Center.svg ├── E.svg ├── N.svg ├── NE.svg ├── NW.svg ├── S.svg ├── SE.svg ├── SW.svg ├── W.svg ├── alignE.svg ├── alignN.svg ├── alignNE.svg ├── alignNW.svg ├── alignS.svg ├── alignSE.svg ├── alignSW.svg ├── alignW.svg ├── alignX.svg ├── alignY.svg ├── artboard.svg ├── distE.svg ├── distN.svg ├── distNE.svg ├── distNW.svg ├── distS.svg ├── distSE.svg ├── distSW.svg ├── distW.svg ├── distX.svg ├── distY.svg ├── framed ├── Center.svg ├── E.svg ├── N.svg ├── NE.svg ├── NW.svg ├── S.svg ├── SE.svg ├── SW.svg └── W.svg └── selection.svg /.debug: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CSXS/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./client/index.html 27 | 28 | 29 | 30 | 31 | 32 | true 33 | 34 | 35 | Panel 36 | 37 | Smart Align 38 | 39 | 40 | 41 | 160 42 | 150 43 | 44 | 45 | 200 46 | 150 47 | 48 | 49 | 160 50 | 62 51 | 52 | 53 | 54 | ./icons/iconLight.png 55 | ./icons/iconLightRollover.png 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tom Scharstein 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Smart Align 2 | 3 | Collaboration with @nimbling for a dynamic alignment panel: 4 | 5 | ![Smart Align panel](https://thumbs.gfycat.com/HatefulSimplisticHawk-size_restricted.gif) 6 | 7 | ![New UI](https://thumbs.gfycat.com/LimpChubbyAtlanticbluetang-size_restricted.gif) 8 | 9 | When only one object (or group) is selected, align to the artboard: 10 | 11 | ![Solo](https://thumbs.gfycat.com/DearAfraidFulmar-size_restricted.gif) 12 | 13 | With multiple objects selected, align to selection: 14 | 15 | ![Solo](https://thumbs.gfycat.com/PiercingBogusHare-size_restricted.gif) 16 | 17 | Holding the Shift key will override align to artboard: 18 | 19 | ![Solo](https://thumbs.gfycat.com/SpectacularDigitalHapuka-size_restricted.gif) 20 | 21 | To-do: 22 | 23 | * Align to Key object 24 | 25 | * Clipping masks 26 | -------------------------------------------------------------------------------- /client/FullPad.svg: -------------------------------------------------------------------------------- 1 | 2 | FullPad 3 | 4 | 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /client/dead.js: -------------------------------------------------------------------------------- 1 | // html 2 | 3 | // 18 | // 19 | // 20 | // 23 | 24 | 25 | 26 | 27 | loadUniversalJSXLibraries(); 28 | console.log(`Loading for ${appName}`); 29 | // loadJSX(`align.jsx`); 30 | // loadJSX(`${appName}.jsx`); 31 | console.log(appUI); 32 | scanningToggle(true) 33 | // var toggle = { 34 | // alignTo: "selection", 35 | // direction: "align" 36 | // }; 37 | 38 | 39 | 40 | // frameD.style.opacity = 0; 41 | var scanRes; 42 | 43 | // function scanningToggle(state) { 44 | // var res, here; 45 | // var parm = ["x", "y", "w", "h"]; 46 | // if (state) { 47 | // timer = setInterval(function(){csInterface.evalScript('selectScanner();', function(a){ 48 | // if (a == scanRes) return; 49 | // console.log(a); 50 | // if (a > 0) { 51 | // // (a > 1) ? toggle.alignTo = "selection" : toggle.alignTo = "artboard"; 52 | // // (a > 1) ? a = 1 : a = a; 53 | // frameNodes.style.opacity = 1; 54 | // // if (a > 1) { 55 | // // frameD.style.opacity = 1; 56 | // console.log(a + " objects selected"); 57 | // // } else { 58 | // frameS.style.opacity = 1; 59 | // // console.log("Something is selected"); 60 | // // } 61 | // } else { 62 | // frameNodes.style.opacity = 0; 63 | // frameS.style.opacity = 0; 64 | // frameD.style.opacity = 0; 65 | // console.log("Nothing is selected"); 66 | // } 67 | // scanRes = a; 68 | // })}, 50); 69 | // console.log("Scanning on"); 70 | // } else { 71 | // clearInterval(timer); 72 | // console.log("Scanning off"); 73 | // } 74 | // } 75 | 76 | // alignBtn.addEventListener("click", function(e){ 77 | // if (e.target.classList.contains('adobe-btn-switch-on')) { 78 | // return; 79 | // } else { 80 | // toggle.direction = "align"; 81 | // } 82 | // console.log(toggle.direction); 83 | // }, false) 84 | // 85 | // distBtn.addEventListener("click", function(e){ 86 | // if (e.target.classList.contains('adobe-btn-switch-on')) { 87 | // return; 88 | // } else { 89 | // toggle.direction = "dist"; 90 | // } 91 | // console.log(toggle.direction); 92 | // }, false) 93 | 94 | 95 | 96 | // var SAbtn = [].slice.call(document.getElementsByClassName('SAbtn')); 97 | // SAbtn.forEach(function(v,i,a) { 98 | // v.addEventListener("click", function(e){ 99 | // // var classN, target; 100 | // // if (e.target.classList.contains('adobe')) { 101 | // // classN = e.target.classList; 102 | // // target = e.target; 103 | // // } else { 104 | // // classN = e.target.parentNode.classList; 105 | // // target = e.target.parentNode; 106 | // // } 107 | // action = toggle.direction + v.id; 108 | // csInterface.evalScript(`app.doScript('${action}', 'SmartAlign');`) 109 | // console.log(`Action to trigger: ${action}`); 110 | // }, false) 111 | // }); 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | // var controls = { 125 | // NW:null, 126 | // N:null, 127 | // NE:null, 128 | // W:null, 129 | // center:null, 130 | // E:null, 131 | // SW:null, 132 | // S:null, 133 | // SE:null, 134 | // } 135 | // 136 | // var bBox = { 137 | // frameDash: null, 138 | // frameSolid: null, 139 | // frameNodes: null, 140 | // }; 141 | // 142 | // for (var d in controls) { 143 | // controls[d] = this[d]; 144 | // controls[d].addEventListener("mouseover", function(e){ 145 | // // console.log(e.target); 146 | // // console.log(this.style); 147 | // // this.style.fill = "#ff0000"; 148 | // }, false) 149 | // } 150 | // 151 | // for (var b in bBox) { 152 | // bBox[b] = this[b]; 153 | // bBox[b].addEventListener("mouseover", function(e){ 154 | // console.log(e.target); 155 | // }, false) 156 | // } 157 | 158 | 159 | // // Vanilla 160 | // var httpRequest = new XMLHttpRequest() 161 | // httpRequest.onreadystatechange = function (data) { 162 | // var svg = $(xmlDoc).find("svg"); 163 | // container.append(svg); 164 | // // code 165 | // } 166 | // httpRequest.open('GET', url) 167 | // httpRequest.send() 168 | // 169 | // 170 | // $.get(svgUrl) 171 | // .then(injectSvg) 172 | // // .always(startAnimation); 173 | // 174 | // function injectSvg(xmlDoc) { 175 | // 176 | // var svg = $(xmlDoc).find("svg"); 177 | // container.append(svg); 178 | // } 179 | 180 | 181 | // console.log(controls); 182 | // console.log(bBox.style); 183 | 184 | 185 | // function svgloaded() { 186 | // console.log("test"); 187 | // var svgEmbed = document.querySelector("#svgembed"); 188 | // var svg = svgEmbed.getSVGDocument(); 189 | // // for (var d in controls) { 190 | // // controls[d] = svg.getElementById(controls[d]); 191 | // // } 192 | // var testNode = svg.getElementById('N'); 193 | // testNode.style.fill = "red"; 194 | // console.log(controls); 195 | // } 196 | // 197 | // document.addEventListener("DOMContentLoaded", function(){ 198 | // var svgEmbed = document.querySelector("#svgembed"); 199 | // svgEmbed.addEventListener("load", svgloaded); 200 | // },false); 201 | 202 | // var ajax = new XMLHttpRequest(); 203 | // ajax.open("GET", "FullPad.svg", true); 204 | // ajax.send(); 205 | // ajax.onload = function(e) { 206 | // var pad = document.getElementById('placeHolder'); 207 | // pad.innerHTML = ajax.responseText; 208 | // } 209 | 210 | 211 | // buildBodyMovin(); 212 | // function buildBodyMovin() { 213 | // var bMovin = document.getElementById('bMovin'); 214 | // var animData = { 215 | // wrapper: bMovin, 216 | // animType: 'svg', 217 | // loop: false, 218 | // prerender: true, 219 | // autoplay: true, 220 | // path: './data.json' 221 | // }; 222 | // var anim = bodymovin.loadAnimation(animData); 223 | // } 224 | // 225 | // var nCenter = document.getElementById('center'); 226 | // nCenter.addEventListener("mouseover", function(e){ 227 | // console.log(e); 228 | // }, false) 229 | 230 | // document.querySelectorAll(".fillNode").forEach(function(e){ 231 | // e.style.fill = '#' + ; 232 | // e.style.stroke = '#' + ; 233 | // }); 234 | 235 | 236 | 237 | // var SAbtn = [].slice.call(document.getElementsByClassName('adobe-btn-sp')); 238 | // SAbtn.forEach(function(v,i,a) { 239 | // v.addEventListener("click", function(e){ 240 | // var classN, target; 241 | // if (e.target.classList.contains('adobe')) { 242 | // classN = e.target.classList; 243 | // target = e.target; 244 | // } else { 245 | // classN = e.target.parentNode.classList; 246 | // target = e.target.parentNode; 247 | // } 248 | // action = toggle.direction + target.id; 249 | // csInterface.evalScript(`app.doScript('${action}', 'SmartAlign');`) 250 | // console.log(`Action to trigger: ${action}`); 251 | // }, false) 252 | // }); 253 | -------------------------------------------------------------------------------- /client/iconFonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Smart-Align32'; 3 | src: 4 | url('../resources/fonts/Smart-Align32.ttf?rii5vg') format('truetype'), 5 | url('../resources/fonts/Smart-Align32.woff?rii5vg') format('woff'), 6 | url('../resources/fonts/Smart-Align32.svg?rii5vg#Smart-Align32') format('svg'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | [class^="icon-"], [class*=" icon-"] { 12 | /* use !important to prevent issues with browser extensions that change fonts */ 13 | font-family: 'Smart-Align32' !important; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | 21 | /* Better Font Rendering =========== */ 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .icon-alignE:before { 27 | content: "\e900"; 28 | color: #a1a1a1; 29 | } 30 | .icon-alignN:before { 31 | content: "\e901"; 32 | color: #a1a1a1; 33 | } 34 | .icon-alignNE:before { 35 | content: "\e902"; 36 | color: #a1a1a1; 37 | } 38 | .icon-alignNW:before { 39 | content: "\e903"; 40 | color: #a1a1a1; 41 | } 42 | .icon-alignS:before { 43 | content: "\e904"; 44 | color: #a1a1a1; 45 | } 46 | .icon-alignSE:before { 47 | content: "\e905"; 48 | color: #a1a1a1; 49 | } 50 | .icon-alignSW:before { 51 | content: "\e906"; 52 | color: #a1a1a1; 53 | } 54 | .icon-alignW:before { 55 | content: "\e907"; 56 | color: #a1a1a1; 57 | } 58 | .icon-alignX:before { 59 | content: "\e908"; 60 | color: #a1a1a1; 61 | } 62 | .icon-alignY:before { 63 | content: "\e909"; 64 | color: #a1a1a1; 65 | } 66 | .icon-artboard .path1:before { 67 | content: "\e90a"; 68 | color: rgb(161, 161, 161); 69 | opacity: 0.2; 70 | } 71 | .icon-artboard .path2:before { 72 | content: "\e90b"; 73 | margin-left: -1em; 74 | color: rgb(161, 161, 161); 75 | } 76 | .icon-artboard .path3:before { 77 | content: "\e90c"; 78 | margin-left: -1em; 79 | color: rgb(161, 161, 161); 80 | } 81 | .icon-artboard .path4:before { 82 | content: "\e90d"; 83 | margin-left: -1em; 84 | color: rgb(161, 161, 161); 85 | } 86 | .icon-Center:before { 87 | content: "\e90e"; 88 | color: #a1a1a1; 89 | } 90 | .icon-distE:before { 91 | content: "\e90f"; 92 | color: #a1a1a1; 93 | } 94 | .icon-distN:before { 95 | content: "\e910"; 96 | color: #a1a1a1; 97 | } 98 | .icon-distNE:before { 99 | content: "\e911"; 100 | color: #a1a1a1; 101 | } 102 | .icon-distNW:before { 103 | content: "\e912"; 104 | color: #a1a1a1; 105 | } 106 | .icon-distS:before { 107 | content: "\e913"; 108 | color: #a1a1a1; 109 | } 110 | .icon-distSE:before { 111 | content: "\e914"; 112 | color: #a1a1a1; 113 | } 114 | .icon-distSW:before { 115 | content: "\e915"; 116 | color: #a1a1a1; 117 | } 118 | .icon-distW:before { 119 | content: "\e916"; 120 | color: #a1a1a1; 121 | } 122 | .icon-distX:before { 123 | content: "\e917"; 124 | color: #a1a1a1; 125 | } 126 | .icon-distY:before { 127 | content: "\e918"; 128 | color: #a1a1a1; 129 | } 130 | .icon-E:before { 131 | content: "\e919"; 132 | color: #a1a1a1; 133 | } 134 | .icon-N:before { 135 | content: "\e91a"; 136 | color: #a1a1a1; 137 | } 138 | .icon-NE:before { 139 | content: "\e91b"; 140 | color: #a1a1a1; 141 | } 142 | .icon-NW:before { 143 | content: "\e91c"; 144 | color: #a1a1a1; 145 | } 146 | .icon-S:before { 147 | content: "\e91d"; 148 | color: #a1a1a1; 149 | } 150 | .icon-SE:before { 151 | content: "\e91e"; 152 | color: #a1a1a1; 153 | } 154 | .icon-selection:before { 155 | content: "\e91f"; 156 | color: #a1a1a1; 157 | } 158 | .icon-SW:before { 159 | content: "\e920"; 160 | color: #a1a1a1; 161 | } 162 | .icon-W:before { 163 | content: "\e921"; 164 | color: #a1a1a1; 165 | } 166 | -------------------------------------------------------------------------------- /client/main.js: -------------------------------------------------------------------------------- 1 | dispatchEvent('mighty.start', extFolder()) 2 | 3 | var frameS = document.getElementById('frameSolid'); 4 | var frameD = document.getElementById('frameDash') 5 | var frameNodes = document.getElementById('frameNodes'); 6 | 7 | var csInterface = new CSInterface(); 8 | var appSkin = csInterface.hostEnvironment.appSkinInfo; 9 | var sysPath = csInterface.getSystemPath(SystemPath.EXTENSION); 10 | var logPath = sysPath + "/log/"; 11 | var hostPath = sysPath + "/host/"; 12 | var appName = csInterface.hostEnvironment.appName; 13 | var alignSolo, lastNum; 14 | 15 | var coords = { 16 | rel : { 17 | x1:null, 18 | y1:null, 19 | x2:null, 20 | y2:null, 21 | w:null, 22 | h:null, 23 | }, 24 | artB : { 25 | x1:null, 26 | y1:null, 27 | x2:null, 28 | y2:null, 29 | w:null, 30 | h:null, 31 | index:null, 32 | }, 33 | abs : { 34 | x1:null, 35 | y1:null, 36 | x2:null, 37 | y2:null, 38 | w:null, 39 | h:null, 40 | }, 41 | which: "selection" 42 | }; 43 | 44 | loadUniversalJSXLibraries(); 45 | console.log(`Loading for ${appName}`); 46 | loadJSX(`smartAlign.jsx`); 47 | loadJSX(`${appName}.jsx`); 48 | console.log(appUI); 49 | var scanSel, scanAB, lastA; 50 | var isActive = false; 51 | scanningSelection(true); 52 | scanningArtboard(true); 53 | 54 | function scanningArtboard(state) { 55 | var res, here; 56 | var parm = ["x1", "y1", "x2", "y2", "w", "h", "index"]; 57 | if (state) { 58 | timerAB = setInterval(function(){csInterface.evalScript('scanCurrentArtboard();', function(a){ 59 | if (a == scanAB) return; 60 | if (a !== scanAB) { 61 | console.log('Artboard changed'); 62 | csInterface.evalScript(`updateArtboardDimensions(${a});`, function(aa){ 63 | var res = aa.split(','); 64 | for (var m = 0; m < res.length; m++) { 65 | here = parm[m]; 66 | coords.artB[here] = parseInt(res[m]); 67 | }; 68 | console.log(coords.artB); 69 | }); 70 | } 71 | scanAB = a; 72 | })}, 50); 73 | console.log("Scanning artboard on"); 74 | } else { 75 | clearInterval(timerAB); 76 | console.log("Scanning artboard off"); 77 | } 78 | } 79 | 80 | function scanningSelection(state) { 81 | if (state) { 82 | timer = setInterval(function(){csInterface.evalScript('selectScanner();', function(a){ 83 | if (a == scanSel) return; 84 | scanResults(a); 85 | scanSel = a; 86 | })}, 50); 87 | console.log("Scanning on"); 88 | } else { 89 | clearInterval(timer); 90 | console.log("Scanning off"); 91 | } 92 | } 93 | 94 | function scanResults(a) { 95 | var res, here, type; 96 | var parm = ["x1", "y1", "x2", "y2", "w", "h"]; 97 | if (a == 1) 98 | alignSolo = true; 99 | if (a > 0) { 100 | isActive = true; 101 | if (a > 1) { 102 | csInterface.evalScript(`getBounds(selection, 'geometricBounds')`, function(e){ 103 | alignSolo = false; 104 | type = e.split(";") 105 | res = type[0].split(","); 106 | for (var m = 0; m < res.length; m++) { 107 | if (res[m] == null) break; 108 | here = parm[m]; 109 | coords.rel[here] = parseInt(res[m]); 110 | }; 111 | absRes = type[1].split(","); 112 | for (var m = 0; m < absRes.length; m++) { 113 | if (res[m] == null) break; 114 | here = parm[m]; 115 | coords.abs[here] = parseInt(absRes[m]) 116 | }; 117 | }) 118 | setBoundingBox(true, 'solid', color.B); 119 | } else { 120 | setBoundingBox(true, 'dash', color.G); 121 | } 122 | } else { 123 | isActive = false; 124 | setBoundingBox(false, 'solid', 'red'); 125 | res = ["", "", "", "", "", ""]; 126 | } 127 | lastNum = a; 128 | console.log(a); 129 | } 130 | 131 | 132 | var SAbtn = [].slice.call(document.getElementsByClassName('SAbtn')); 133 | SAbtn.forEach(function(v,i,a) { 134 | v.addEventListener("click", function(e){ 135 | var yOff; 136 | if (alignSolo) { 137 | yOff = (coords.artB.index < 1) ? coords.artB.y2 * -1 : coords.artB.y2; 138 | csInterface.evalScript(`alignSingleToArtboard('${v.id}', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 139 | } else { 140 | if (e.shiftKey) { 141 | console.log(coords.artB); 142 | yOff = (coords.artB.index < 1) ? coords.artB.y2 * -1 : coords.artB.y2; 143 | switch(v.id) { 144 | case 'N': 145 | csInterface.evalScript(`alignSelection('align', 'artboard', 'verticalTop', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 146 | break; 147 | case 'W': 148 | csInterface.evalScript(`alignSelection('align', 'artboard', 'horizontalLeft', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 149 | break; 150 | case 'E': 151 | csInterface.evalScript(`alignSelection('align', 'artboard', 'horizontalRight', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 152 | break; 153 | case 'S': 154 | csInterface.evalScript(`alignSelection('align', 'artboard', 'verticalBottom', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 155 | break; 156 | case 'distributeX': 157 | csInterface.evalScript(`alignSelection('distributeEven', 'artboard', 'verticalCenter', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 158 | break; 159 | case 'distributeY': 160 | csInterface.evalScript(`alignSelection('distributeEven', 'artboard', 'horizontalCenter', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 161 | break; 162 | case 'alignX': 163 | csInterface.evalScript(`alignSelection('align', 'artboard', 'verticalCenter', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 164 | break; 165 | case 'alignY': 166 | csInterface.evalScript(`alignSelection('align', 'artboard', 'horizontalCenter', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 167 | break; 168 | default: 169 | csInterface.evalScript(`alignSelection('align', 'artboard', '${v.id}', ${coords.artB.x1}, ${coords.artB.y1}, ${coords.artB.x2}, ${yOff})`); 170 | break; 171 | } 172 | } else if (e.altKey) { 173 | yOff = (coords.abs.index < 1) ? coords.abs.y2 * -1 : coords.abs.y2; 174 | csInterface.evalScript(`alignSelection('distribute', 'selection', '${v.id}', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 175 | } else if (e.ctrlKey) { 176 | yOff = (coords.abs.index < 1) ? coords.abs.y2 * -1 : coords.abs.y2; 177 | csInterface.evalScript(`alignSelection('distributeEven', 'selection', '${v.id}', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 178 | } else { 179 | yOff = (coords.abs.index < 1) ? coords.rel.y2 : coords.abs.y2; 180 | switch(v.id) { 181 | case 'N': 182 | csInterface.evalScript(`alignSelection('align', 'selection', 'verticalTop', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 183 | break; 184 | case 'W': 185 | csInterface.evalScript(`alignSelection('align', 'selection', 'horizontalLeft', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 186 | break; 187 | case 'E': 188 | csInterface.evalScript(`alignSelection('align', 'selection', 'horizontalRight', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 189 | break; 190 | case 'S': 191 | csInterface.evalScript(`alignSelection('align', 'selection', 'verticalBottom', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 192 | break; 193 | case 'distributeX': 194 | csInterface.evalScript(`alignSelection('distributeEven', 'selection', 'horizontalCenter', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 195 | break; 196 | case 'distributeY': 197 | csInterface.evalScript(`alignSelection('distributeEven', 'selection', 'verticalCenter', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 198 | break; 199 | case 'alignX': 200 | csInterface.evalScript(`alignSelection('align', 'selection', 'verticalCenter', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 201 | break; 202 | case 'alignY': 203 | csInterface.evalScript(`alignSelection('align', 'selection', 'horizontalCenter', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 204 | break; 205 | default: 206 | csInterface.evalScript(`alignSelection('align', 'selection', '${v.id}', ${coords.abs.x1}, ${coords.abs.y1}, ${coords.abs.x2}, ${yOff})`); 207 | break; 208 | } 209 | } 210 | } 211 | }, false); 212 | 213 | v.addEventListener("mouseover", function(e){ 214 | if (e.altKey) { 215 | setUILayout("scrunch"); 216 | } else if (e.shiftKey) { 217 | if (isActive) 218 | setBoundingBox(true, 'dash', color.G); 219 | } else { 220 | if (isActive) { 221 | if (alignSolo) 222 | setBoundingBox(true, 'dash', color.G); 223 | else 224 | setBoundingBox(true, 'solid', color.B); 225 | } 226 | setUILayout("default"); 227 | } 228 | }, false) 229 | 230 | v.addEventListener("mouseout", function(e){ 231 | if (e.shiftKey) { 232 | if (isActive) 233 | setBoundingBox(true, 'dash', color.G); 234 | } else { 235 | if (isActive) { 236 | if (alignSolo) 237 | setBoundingBox(true, 'dash', color.G); 238 | else 239 | setBoundingBox(true, 'solid', color.B); 240 | } else { 241 | setBoundingBox(false, 'dash', color.G); 242 | } 243 | } 244 | if (e.altKey) { 245 | setUILayout("scrunch"); 246 | } else { 247 | setUILayout("default"); 248 | } 249 | }, false) 250 | 251 | }) 252 | 253 | 254 | function setBoundingBox(on, type, color) { 255 | if (on) { 256 | setUILayout(type); 257 | document.documentElement.style.setProperty('--colorBBox', color); 258 | if (type == 'solid') { 259 | document.documentElement.style.setProperty('--frameSolid', 1); 260 | document.documentElement.style.setProperty('--frameDash', 0); 261 | } else { 262 | document.documentElement.style.setProperty('--frameSolid', 0) 263 | document.documentElement.style.setProperty('--frameDash', 1); 264 | } 265 | document.documentElement.style.setProperty('--frameNodes', 1); 266 | } else { 267 | document.documentElement.style.setProperty('--frameSolid', 0); 268 | document.documentElement.style.setProperty('--frameDash', 0); 269 | document.documentElement.style.setProperty('--frameNodes', 0); 270 | } 271 | } 272 | 273 | var color = { 274 | R: '#9e2c26', 275 | G: '#319608', 276 | B: '#086baf', 277 | }; 278 | 279 | function setUILayout(which){ 280 | if (which == 'default') { 281 | document.documentElement.style.setProperty('--icoScrunchOpacity', 0); 282 | document.documentElement.style.setProperty('--icoDefOpacity', 1); 283 | } else if (which == 'scrunch') { 284 | document.documentElement.style.setProperty('--icoDefOpacity', 0); 285 | document.documentElement.style.setProperty('--icoScrunchOpacity', 1); 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /client/myTstack/ReqLibs.js: -------------------------------------------------------------------------------- 1 | // https://www.davidebarranca.com/2014/01/html-panels-tips-2-including-multiple-jsx/ 2 | function loadJSX(fileName) { 3 | var csInterface = new CSInterface(); 4 | var extensionRoot = csInterface.getSystemPath(SystemPath.EXTENSION) + "/host/"; 5 | csInterface.evalScript('$.evalFile("' + extensionRoot + fileName + '")'); 6 | console.log("loading " + extensionRoot + fileName); 7 | } 8 | 9 | function loadUniversalJSXLibraries() { 10 | var libs = ["json2.jsx", "Console.jsx"]; 11 | var csInterface = new CSInterface(); 12 | var extensionRoot = csInterface.getSystemPath(SystemPath.EXTENSION) + "/host/universal/"; 13 | for (var i = 0; i < libs.length; i++) { 14 | csInterface.evalScript('$.evalFile("' + extensionRoot + libs[i] + '")'); 15 | console.log("loading " + extensionRoot + libs[i]); 16 | } 17 | } 18 | 19 | // https://stackoverflow.com/a/6211660 20 | function isEven(n) { 21 | return n % 2 == 0; 22 | } 23 | function isOdd(n) { 24 | return Math.abs(n % 2) == 1; 25 | } 26 | 27 | /** 28 | * Premiere Pro Panel 29 | */ 30 | function toHex(color, delta) { 31 | function computeValue(value, delta) { 32 | var computedValue = !isNaN(delta) ? value + delta : value; 33 | if (computedValue < 0) { 34 | computedValue = 0; 35 | } else if (computedValue > 255) { 36 | computedValue = 255; 37 | } 38 | 39 | computedValue = Math.round(computedValue).toString(16); 40 | return computedValue.length == 1 ? "0" + computedValue : computedValue; 41 | } 42 | 43 | var hex = ""; 44 | if (color) { 45 | with (color) { 46 | hex = computeValue(red, delta) + computeValue(green, delta) + computeValue(blue, delta); 47 | }; 48 | } 49 | return "#" + hex; 50 | } 51 | 52 | function toHexDigits(color, delta) { 53 | function computeValue(value, delta) { 54 | var computedValue = !isNaN(delta) ? value + delta : value; 55 | if (computedValue < 0) { 56 | computedValue = 0; 57 | } else if (computedValue > 255) { 58 | computedValue = 255; 59 | } 60 | 61 | computedValue = Math.round(computedValue).toString(16); 62 | return computedValue.length == 1 ? "0" + computedValue : computedValue; 63 | } 64 | 65 | var hex = ""; 66 | if (color) { 67 | with (color) { 68 | hex = computeValue(red, delta) + computeValue(green, delta) + computeValue(blue, delta); 69 | }; 70 | } 71 | return hex; 72 | } 73 | 74 | // https://stackoverflow.com/a/8027444 75 | function isHexColor(param) { 76 | var isOk = /^[0-9A-F]{6}$/i.test(param); 77 | return isOk; 78 | } 79 | 80 | // https://stackoverflow.com/a/25352300 81 | function isAlphaNumeric(str) { 82 | var code, i, len; 83 | for (i = 0, len = str.length; i < len; i++) { 84 | code = str.charCodeAt(i); 85 | if (!(code > 47 && code < 58) && // numeric (0-9) 86 | !(code > 64 && code < 91) && // upper alpha (A-Z) 87 | !(code > 96 && code < 123)) { // lower alpha (a-z) 88 | return false; 89 | } 90 | } 91 | return true; 92 | }; 93 | 94 | 95 | // https://stackoverflow.com/a/11923973 96 | function rgbToHsl(c) { 97 | var r = c[0]/255, g = c[1]/255, b = c[2]/255; 98 | var max = Math.max(r, g, b), min = Math.min(r, g, b); 99 | var h, s, l = (max + min) / 2; 100 | 101 | if(max == min) { 102 | h = s = 0; // achromatic 103 | } else { 104 | var d = max - min; 105 | s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 106 | switch(max){ 107 | case r: h = (g - b) / d + (g < b ? 6 : 0); break; 108 | case g: h = (b - r) / d + 2; break; 109 | case b: h = (r - g) / d + 4; break; 110 | } 111 | h /= 6; 112 | } 113 | // return new Array(h, s, l); 114 | return new Array(h * 360, s * 100, l * 100); 115 | } 116 | 117 | // https://stackoverflow.com/a/44134328 118 | function hslToHex(h, s, l) { 119 | h /= 360; 120 | s /= 100; 121 | l /= 100; 122 | let r, g, b; 123 | if (s === 0) { 124 | r = g = b = l; // achromatic 125 | } else { 126 | const hue2rgb = (p, q, t) => { 127 | if (t < 0) t += 1; 128 | if (t > 1) t -= 1; 129 | if (t < 1 / 6) return p + (q - p) * 6 * t; 130 | if (t < 1 / 2) return q; 131 | if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; 132 | return p; 133 | }; 134 | const q = l < 0.5 ? l * (1 + s) : l + s - l * s; 135 | const p = 2 * l - q; 136 | r = hue2rgb(p, q, h + 1 / 3); 137 | g = hue2rgb(p, q, h); 138 | b = hue2rgb(p, q, h - 1 / 3); 139 | } 140 | const toHex = x => { 141 | const hex = Math.round(x * 255).toString(16); 142 | return hex.length === 1 ? '0' + hex : hex; 143 | }; 144 | return `${toHex(r)}${toHex(g)}${toHex(b)}`; 145 | } 146 | 147 | 148 | 149 | /// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb 150 | 151 | function componentToHex(c) { 152 | var hex = c.toString(16); 153 | return hex.length == 1 ? "0" + hex : hex; 154 | } 155 | 156 | function rgbToHex(r, g, b) { 157 | return componentToHex(r) + componentToHex(g) + componentToHex(b); 158 | } 159 | 160 | function hexToRgb(hex) { 161 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 162 | return result ? { 163 | r: parseInt(result[1], 16), 164 | g: parseInt(result[2], 16), 165 | b: parseInt(result[3], 16) 166 | } : null; 167 | } 168 | -------------------------------------------------------------------------------- /client/myTstack/adobeStyle.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 12px; 3 | } 4 | 5 | :root { 6 | --globalBorderWidth: 1.5px; 7 | --borderRadius: 3px; 8 | --borderWidth: 1.5px; 9 | 10 | --colorPanelBG: #323232; 11 | --border: 1.5px solid transparent; 12 | --btnBorder: 1.5px solid transparent; 13 | 14 | --inputPadding: 0rem .5rem; 15 | --inputHeight: 1.5rem; 16 | --inputWidthMD: 3rem; 17 | --inputWidthLG: 4rem; 18 | --inputWidth1X: 100%; 19 | 20 | /* --btnPadding: .0625rem 1vw; */ 21 | --btnPadding: 0rem 0rem; 22 | --btnMargin: auto .035rem; 23 | --btnHeight: 1.75rem; 24 | --btnHeightMax: 25.17px; 25 | --btnWidth: 28%; 26 | 27 | --fontSize: 10px; 28 | --fontFamily: "Adobe Clean", sans-serif; 29 | 30 | --colorInputIdle: #262626; 31 | --colorInputActive: #fcfcfc; 32 | 33 | --colorDisabled: #393939; 34 | --colorFontDisabled: #525252; 35 | --colorFontActive: #000000; 36 | --colorFont: #b7b7b7; 37 | 38 | --colorBorder: #3e3e3e; 39 | --colorHover: #292929; 40 | --colorActive: #1f1f1f; 41 | --colorFocus: #46a0f5; 42 | --colorIcon: #b4b4b4; 43 | --colorSelect: #086baf; 44 | 45 | } 46 | 47 | body { 48 | margin: 0px 5%; 49 | overflow: hidden; 50 | background-color: var(--colorPanelBG); 51 | color: var(--colorIcon); 52 | } 53 | 54 | .adobe-toolbar-divider { 55 | margin: .125rem; 56 | border-top: solid 1.33px var(--colorHover); 57 | opacity: 0.6; 58 | width: 94%; 59 | } 60 | 61 | .adobe { 62 | display: flex; 63 | justify-content: center; 64 | align-items: center; 65 | border-radius: var(--borderRadius); 66 | border: var(--border); 67 | } 68 | 69 | 70 | 71 | .adobe-btn, .adobe-btn-switch, .adobe-btn-switch-off, .adobe-btn-switch-on, .adobe-btn-hover, .adobe-btn-active { 72 | padding: var(--btnPadding); 73 | max-width: var(--btnWidth); 74 | /* width: 25%; */ 75 | height: var(--btnHeight); 76 | max-height: var(--btnHeightMax); 77 | border-width: var(--globalBorderWidth); 78 | border-style: solid; 79 | margin: var(--btnMargin); 80 | user-select: none; 81 | cursor: pointer; 82 | font-size: 1.8rem; 83 | } 84 | 85 | .adobe-btn-trans { 86 | padding: var(--btnPadding); 87 | max-width: var(--btnWidth); 88 | height: var(--btnHeight); 89 | max-height: var(--btnHeightMax); 90 | border-width: var(--globalBorderWidth); 91 | border-style: solid; 92 | margin: var(--btnMargin); 93 | user-select: none; 94 | cursor: default; 95 | font-size: 1.8rem; 96 | } 97 | 98 | 99 | 100 | 101 | .adobe-btn:hover, .adobe-btn-switch-off:hover, .adobe-btn-switch:hover, .adobe-btn-sp:hover { 102 | border-color: var(--colorBorder); 103 | background-color: var(--colorHover); 104 | } 105 | 106 | .adobe-btn:active, .adobe-btn-switch-off:active, .adobe-btn-switch:active, .adobe-btn-sp:active { 107 | border-color: var(--colorBorder); 108 | background-color: var(--colorActive); 109 | } 110 | 111 | .adobe-btn-hover { 112 | /* border-width: var(--borderWidth); */ 113 | border-color: var(--colorBorder); 114 | background-color: var(--colorHover); 115 | } 116 | 117 | .adobe-btn-active { 118 | border-color: var(--colorBorder); 119 | background-color: var(--colorActive); 120 | } 121 | 122 | 123 | .adobe-btn-switch-on { 124 | border-color: var(--colorBorder); 125 | background-color: var(--colorActive); 126 | } 127 | 128 | .adobe-btn-switch-on { 129 | border-color: var(--colorBorder); 130 | background-color: var(--colorActive); 131 | } 132 | 133 | .adobe-inputGroup { 134 | /* border: 2px solid red; */ 135 | display: inline-block; 136 | max-height: var(--inputHeight); 137 | } 138 | 139 | .adobe-inputGroup-suffix { 140 | position: relative; 141 | /* float: right; */ 142 | top: -1.4rem; 143 | margin-left: 50%; 144 | } 145 | 146 | .adobe-input { 147 | justify-content: flex-start; 148 | border-style: solid; 149 | background-color: var(--colorInputIdle); 150 | font-size: 10px; 151 | color: var(--colorFont); 152 | border-width: var(--borderWidth); 153 | border-color: var(--colorBorder); 154 | border-radius: var(--borderRadius); 155 | padding: var(--inputPadding); 156 | height: var(--inputHeight); 157 | } 158 | 159 | .adobe-input-md { 160 | width: 2rem; 161 | } 162 | 163 | .adobe-input:focus { 164 | outline-offset: 0px; 165 | background-color: var(--colorInputActive); 166 | /* border-color: var(--colorActive); */ 167 | color: var(--colorFontActive); 168 | } 169 | 170 | :focus { 171 | outline-width: 0px; 172 | } 173 | 174 | input[type=number]::-webkit-inner-spin-button, 175 | input[type=number]::-webkit-outer-spin-button { 176 | -webkit-appearance: none; 177 | margin: 0; 178 | } 179 | 180 | 181 | 182 | 183 | .adobe-toolbar { 184 | display: flex; 185 | justify-content: center; 186 | flex-wrap: wrap; 187 | margin: .5rem 0px; 188 | align-items: center; 189 | } 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | /* .adobe-toolbar-sm { 198 | display: flex; 199 | justify-content: center; 200 | flex-wrap: wrap; 201 | margin: 0px; 202 | align-items: center; 203 | } 204 | 205 | .adobe-footer { 206 | display: none; 207 | justify-content: space-between; 208 | flex-wrap: wrap; 209 | margin: .325rem 0px; 210 | align-items: center; 211 | } 212 | 213 | .adobe-btn-corner { 214 | position: relative; 215 | top: .70rem; 216 | left: .275rem; 217 | border-style: solid; 218 | border-color: red; 219 | width: 0px; 220 | height: 0px; 221 | border-right-color: transparent; 222 | border-left-color: transparent; 223 | border-left-width: 4.5px; 224 | border-bottom-width: 4.5px; 225 | border-top-width: 0px; 226 | border-right-width: 0px; 227 | } 228 | 229 | .adobe-btn-toggle { 230 | padding-left: .5rem; 231 | padding-right: .5rem; 232 | display: flex; 233 | justify-content: center; 234 | align-items: center; 235 | border-radius: var(--borderRadius); 236 | width: auto; 237 | height: var(--btnHeight); 238 | border: var(--border); 239 | margin: auto .035rem; 240 | user-select: none; 241 | cursor: pointer; 242 | } 243 | 244 | .adobe-btn-select { 245 | padding-left: .5rem; 246 | padding-right: .5rem; 247 | display: flex; 248 | justify-content: center; 249 | align-items: center; 250 | border-radius: var(--borderRadius); 251 | width: auto; 252 | height: var(--btnHeight); 253 | border: var(--border); 254 | margin-left: .5rem; 255 | user-select: none; 256 | cursor: pointer; 257 | } */ 258 | 259 | 260 | /* .adobe-upDown { 261 | padding-left: .25rem; 262 | padding-right: .25rem; 263 | margin-right: .5rem; 264 | margin-left: 0px; 265 | width: auto; 266 | height: 1.75rem; 267 | border-color: transparent; 268 | border-style: solid; 269 | border-width: 1.5px; 270 | border-left-width: 0px; 271 | border-radius: 0px 2px 2px 0px; 272 | } 273 | 274 | .adobe-upDown-Up, .adobe-upDown-Down { 275 | height: 8px; 276 | display: flex; 277 | flex-direction: column; 278 | justify-content: space-between; 279 | } 280 | 281 | .adobe-upDown-Up { 282 | margin-top: -2px; 283 | margin-bottom: 1px; 284 | } 285 | 286 | .adobe-upDown-Down { 287 | margin-bottom: 0px; 288 | margin-top: 4px; 289 | } 290 | 291 | 292 | 293 | .adobe-input-md { 294 | width: 2.5rem; 295 | margin: 0px .25rem; 296 | } 297 | 298 | .adobe-input-lg { 299 | width: 6.75rem; 300 | margin: 0px .25rem; 301 | } 302 | 303 | .adobe-input-2x { 304 | width: 60%; 305 | margin: 0px 0px; 306 | } 307 | 308 | .adobe-console { 309 | display: flex; 310 | justify-content: space-between; 311 | flex-wrap: wrap; 312 | margin: .5rem 0px .5rem 0px; 313 | border-style: solid; 314 | border-width: 1.5px; 315 | border-radius: var(--borderRadius); 316 | padding: .25rem 1rem .25rem .5rem; 317 | height: 1.75rem; 318 | width: 100%; 319 | user-select: none; 320 | cursor: default; 321 | overflow: hidden; 322 | } 323 | 324 | .no-input { 325 | user-select: none; 326 | cursor: default; 327 | } 328 | 329 | .adobe-input-num { 330 | margin-right: 0px; 331 | width: 3.25rem; 332 | height: 1.75rem; 333 | border-style: solid; 334 | border-width: 1.5px; 335 | border-radius: 2px 0px 0px 2px; 336 | padding: .25rem .5rem; 337 | } 338 | 339 | .adobe-input-full { 340 | width: 100%; 341 | } 342 | 343 | .adobe-swatch { 344 | display: flex; 345 | justify-content: center; 346 | align-items: center; 347 | background-color: red; 348 | border-radius: .25rem; 349 | width: .5rem; 350 | height: 1.5rem; 351 | border: var(--border); 352 | margin: auto .25rem; 353 | cursor: pointer; 354 | } 355 | 356 | .adobe-swatchStrip { 357 | display: flex; 358 | flex-wrap: wrap; 359 | justify-content: flex-start; 360 | width: auto; 361 | } */ 362 | -------------------------------------------------------------------------------- /client/myTstack/eventManager.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var csInterface = new CSInterface(); 5 | 6 | csInterface.addEventListener('com.init', function(evt) { 7 | console.log("Initializing console"); 8 | }); 9 | 10 | dispatchEvent("com.plug", "Plugged In") 11 | 12 | function dispatchEvent(name, data) { 13 | var event = new CSEvent(name, 'APPLICATION'); 14 | event.data = data; 15 | csInterface.dispatchEvent(event); 16 | } 17 | 18 | csInterface.addEventListener("com.adobe.csxs.events.flyoutMenuClicked", log); 19 | function log(event){ 20 | console.log(event); 21 | } 22 | 23 | csInterface.addEventListener("com.adobe.csxs.events", log); 24 | function log(event){ 25 | console.log(event); 26 | console.log(" triggered "); 27 | } 28 | 29 | csInterface.addEventListener('mighty.rollcall', function(evt) { 30 | dispatchEvent('mighty.rollanswer', extFolder()) 31 | }); 32 | 33 | // btn.addEventListener("click", function(evt){ 34 | // dispatchEvent(name, data) 35 | // }, false); 36 | 37 | 38 | }()); 39 | -------------------------------------------------------------------------------- /client/myTstack/magicMirror.js: -------------------------------------------------------------------------------- 1 | var cs = new CSInterface(); 2 | var docExist; 3 | 4 | window.onload = init; 5 | // window.onload = logSkin; 6 | 7 | function init(){ 8 | var appSkin = cs.hostEnvironment.appSkinInfo; 9 | logSkin(appSkin); 10 | loadBorderWidth(); 11 | callDoc(); 12 | cs.addEventListener(CSInterface.THEME_COLOR_CHANGED_EVENT, onAppThemeColorChanged); 13 | // cs.addEventListener('documentAfterActivate', reset); 14 | cs.addEventListener('applicationActive', callDoc); 15 | appUI.data.name = cs.hostEnvironment.appName; 16 | if (navigator.platform.indexOf('Win') > -1) { 17 | appUI.data.os = 'Win'; 18 | } else if (navigator.platform.indexOf('Mac') > -1) { 19 | appUI.data.os = 'Mac'; 20 | } 21 | 22 | buildUI(); 23 | } 24 | 25 | function reset(){ 26 | // console.log("reload!"); 27 | location.reload(); 28 | } 29 | 30 | function callDoc() { 31 | if (cs.hostEnvironment.appName === 'ILST') { 32 | cs.evalScript('app.documents[0].name', function(e){ 33 | appUI.data.doc = e; 34 | cs.evalScript('app.documents[0].path', function(i){ 35 | appUI.data.docPath = i; 36 | }) 37 | }) 38 | } 39 | // console.log(appUI.data); 40 | } 41 | 42 | function updateThemeWithAppSkinInfo() { 43 | reColorUI(); 44 | } 45 | 46 | const appUI = { 47 | global : { 48 | BorderWidth: "1.35px", 49 | }, 50 | color : { 51 | PanelBG: "#323232", 52 | Border: "#3e3e3e", 53 | Icon: "#b4b4b4", 54 | Font: "#b7b7b7", 55 | Hover: "#292929", 56 | Active: "#1f1f1f", 57 | Focus: "#46a0f5", 58 | Disabled: "#393939", 59 | FontDisabled: "#525252", 60 | FontActive: "#000000", 61 | InputIdle: "#262626", 62 | InputActive: "#fcfcfc", 63 | }, 64 | btn : { 65 | Padding: ".0625rem .5rem", 66 | Margin: "auto .035rem", 67 | Height: "1.75rem", 68 | Width: "1.25rem", 69 | Border: "1.5px solid transparent", 70 | }, 71 | input : { 72 | Height: "1.5rem", 73 | WidthMD : "2rem", 74 | WidthLG : "4rem", 75 | Width1X : "100%" 76 | }, 77 | font: { 78 | Family: "Adobe Clean", 79 | Size: "10px" 80 | }, 81 | data : { 82 | name: cs.hostEnvironment.appName, 83 | doc: "none", 84 | docPath: "none", 85 | theme: "none", 86 | extPath: cs.getSystemPath(SystemPath.EXTENSION), 87 | panelWidth: window.innerWidth, 88 | panelHeight: window.innerHeight, 89 | system: cs.getOSInformation('--user-agent'), 90 | version: cs.hostEnvironment.appVersion, 91 | os: "none" 92 | } 93 | }; 94 | 95 | 96 | function reColorUI(){ 97 | for (let [key, value] of Object.entries(appUI)) { 98 | if (key === 'data') continue; 99 | for (let [index, data] of Object.entries(appUI[key])) { 100 | document.documentElement.style.setProperty('--' + key + index, data); 101 | } 102 | } 103 | } 104 | 105 | 106 | function buildUI(){ 107 | var btnToggles = ['switch', 'switch-on', 'switch-off']; 108 | for (var i = 0; i < btnToggles.length; i++) { 109 | var toggleBtn = [].slice.call(document.getElementsByClassName('adobe-btn-' + btnToggles[i])); 110 | toggleBtn.forEach(function(v,i,a) { 111 | v.addEventListener("click", function(e){ 112 | var classN, target; 113 | if (e.target.classList.contains('adobe')) { 114 | classN = e.target.classList; 115 | target = e.target; 116 | } else { 117 | classN = e.target.parentNode.classList; 118 | target = e.target.parentNode; 119 | } 120 | if (classN.contains('adobe-btn-switch-on')) { 121 | classN.remove('adobe-btn-switch-on'); 122 | classN.add('adobe-btn-switch-off') 123 | } else { 124 | classN.remove('adobe-btn-switch-off', 'adobe-btn-switch'); 125 | classN.add('adobe-btn-switch-on'); 126 | } 127 | toolbarToggle(target); 128 | }, false); 129 | }); 130 | } 131 | var inputGroup = [].slice.call(document.getElementsByClassName('adobe-inputGroup')); 132 | inputGroup.forEach(function(v,i,a) { 133 | var target = "none"; 134 | for (var u = 0; u < v.children.length; u++) { 135 | if (v.children[u].classList.contains('adobe-inputNumber')){ 136 | target = v.children[u]; 137 | } 138 | } 139 | if (target !== "none") {addWheelScrollTo(v, target);} 140 | }); 141 | } 142 | 143 | function addWheelScrollTo(v, target) { 144 | v.addEventListener("mouseover", function(evtTier){ 145 | console.log(evtTier); 146 | }); 147 | v.addEventListener("wheel", function(evt){ 148 | var newNum = target.textContent; 149 | if (evt.deltaY < 0) { 150 | newNum++; 151 | } else { 152 | newNum--; 153 | } 154 | console.log(evt); 155 | target.textContent = newNum; 156 | }, false) 157 | } 158 | 159 | // var scrollCount = 1; 160 | // window.addEventListener('mousewheel', function(e){ 161 | // 162 | // if(e.wheelDelta<0 && scrollCount<5){ 163 | // scrollCount++; 164 | // } 165 | // 166 | // else if(e.wheelDelta>0 && scrollCount>1){ 167 | // scrollCount--; 168 | // } 169 | // document.querySelector('.number').innerHTML = scrollCount; 170 | // }) 171 | 172 | 173 | function toolbarToggle(elt) { 174 | var btnToggles = ['switch', 'switch-on', 'switch-off']; 175 | var toolbar = [].slice.call(document.getElementsByClassName('adobe-toolbar')); 176 | toolbar.forEach(function(v,i,a) { 177 | var child = v.children; 178 | for (var ee = 0; ee < v.children.length; ee++) { 179 | for (var u = 0; u < btnToggles.length; u++) { 180 | if (child[ee].classList.contains('adobe-btn-' + btnToggles[u])) { 181 | if (child[ee] !== elt) { 182 | child[ee].classList.remove('adobe-btn-switch-off', 'adobe-btn-switch', 'adobe-btn-switch-on'); 183 | child[ee].classList.add('adobe-btn-switch-off'); 184 | } 185 | } 186 | } 187 | } 188 | }) 189 | } 190 | 191 | function loadBorderWidth() { 192 | if (appUI.data.name === 'PHXS') { 193 | appUI.borderWidth = "1.25px"; 194 | } else { 195 | appUI.data.borderWidth = "1.25px"; 196 | } 197 | } 198 | 199 | 200 | function logSkin(params) { 201 | var csInterface = new CSInterface(); 202 | var appSkin = params; 203 | appUI.data.system = csInterface.getOSInformation('--user-agent'); 204 | appUI.data.name = csInterface.hostEnvironment.appName; 205 | appUI.data.version = csInterface.hostEnvironment.appVersion; 206 | // appUI.color.PanelBG = toHex(appSkin.panelBackgroundColor.color); 207 | var baseColor = appSkin.panelBackgroundColor.color; 208 | // appUI.color.Font = appSkin.baseFontFamily; 209 | appUI.font.Size = appSkin.baseFontSize; 210 | 211 | if (appSkin.panelBackgroundColor.color.red > 220) { 212 | appUI.data.theme = 'Lightest'; 213 | switch(appUI.data.name) { 214 | case 'PHXS': 215 | appUI.color.Disabled = toHex(baseColor, -10); 216 | appUI.color.FontDisabled = toHex(baseColor, -72); 217 | appUI.color.Focus = '#0f64d2'; 218 | appUI.color.Font = toHex(baseColor, -168); 219 | appUI.color.BorderDisabled = toHex(baseColor, -18); 220 | appUI.color.BorderActive = toHex(baseColor, -72); 221 | appUI.color.Border = toHex(baseColor, -36); 222 | appUI.color.Icon = toHex(baseColor, -190); 223 | appUI.color.Hover = toHex(baseColor, 12); 224 | appUI.color.Active = toHex(baseColor, -49); 225 | appUI.color.InputIdle = toHex(baseColor, 15); 226 | appUI.color.InputActive = toHex(baseColor, 15); 227 | appUI.color.FontActive = appUI.color.Font; 228 | break; 229 | case 'ILST': 230 | appUI.color.Disabled = toHex(baseColor, -10); 231 | appUI.color.FontDisabled = toHex(baseColor, -42); 232 | appUI.color.Focus = '#0f64d2'; 233 | appUI.color.Font = toHex(baseColor, -168); 234 | appUI.color.Border = toHex(baseColor, -20); 235 | appUI.color.Icon = toHex(baseColor, -153); 236 | appUI.color.Hover = toHex(baseColor, 9); 237 | appUI.color.Active = toHex(baseColor, -51); 238 | appUI.color.InputIdle = toHex(baseColor, 15); 239 | appUI.color.InputActive = toHex(baseColor, 15); 240 | appUI.color.FontActive = appUI.color.Font; 241 | break; 242 | default: 243 | 244 | appUI.color.Focus = toHex(appSkin.systemHighlightColor); 245 | break; 246 | } 247 | } else if (appSkin.panelBackgroundColor.color.red > 150) { 248 | appUI.data.theme = 'Light'; 249 | switch(appUI.data.name) { 250 | case 'PHXS': 251 | 252 | appUI.color.Disabled = toHex(baseColor, 5); 253 | appUI.color.FontDisabled = toHex(baseColor, -74); 254 | appUI.color.Focus = '#0f64d2'; 255 | appUI.color.Font = toHex(baseColor, -128); 256 | appUI.color.BorderDisabled = toHex(baseColor, -11); 257 | appUI.color.BorderActive = toHex(baseColor, -72); 258 | appUI.color.Border = toHex(baseColor, -36); 259 | appUI.color.Icon = toHex(baseColor, -158); 260 | appUI.color.Hover = toHex(baseColor, 25); 261 | appUI.color.Active = toHex(baseColor, -56); 262 | appUI.color.InputIdle = toHex(baseColor, 25); 263 | appUI.color.InputActive = toHex(baseColor, 25); 264 | appUI.color.FontActive = appUI.color.Font; 265 | break; 266 | case 'ILST': 267 | appUI.color.Disabled = toHex(baseColor, -8); 268 | appUI.color.FontDisabled = toHex(baseColor, -32); 269 | appUI.color.Focus = '#0f64d2'; 270 | appUI.color.Font = toHex(baseColor, -168); 271 | appUI.color.Border = toHex(baseColor, -16); 272 | appUI.color.Icon = toHex(baseColor, -107); 273 | appUI.color.Hover = toHex(baseColor, 36); 274 | appUI.color.Active = toHex(baseColor, -34); 275 | appUI.color.InputIdle = toHex(baseColor, 43); 276 | appUI.color.InputActive = toHex(baseColor, 43); 277 | appUI.color.FontActive = appUI.color.Font; 278 | break; 279 | default: 280 | appUI.color.Focus = toHex(appSkin.systemHighlightColor); 281 | break; 282 | } 283 | } else if (appSkin.panelBackgroundColor.color.red > 100) { 284 | appUI.data.theme = 'Dark'; 285 | appUI.color.Disabled = toHex(baseColor, 6); 286 | switch(appUI.data.name) { 287 | case 'PHXS': 288 | appUI.color.FontDisabled = toHex(baseColor, 69); 289 | appUI.color.Focus = '#0f64d2'; 290 | appUI.color.Font = toHex(baseColor, 133); 291 | appUI.color.Border = toHex(baseColor, 19); 292 | appUI.color.Icon = toHex(baseColor, 135); 293 | appUI.color.Hover = toHex(baseColor, -14); 294 | appUI.color.Active = toHex(baseColor, -27); 295 | appUI.color.InputIdle = toHex(baseColor, -14); 296 | appUI.color.InputActive = toHex(baseColor, -14); 297 | appUI.color.FontActive = appUI.color.Font; 298 | break; 299 | case 'ILST': 300 | appUI.color.FontDisabled = toHex(baseColor, 30); 301 | appUI.color.Focus = '#46a0f5'; 302 | appUI.color.Font = toHex(baseColor, 133); 303 | appUI.color.Border = toHex(baseColor, 12); 304 | appUI.color.Active = toHex(baseColor, -35); 305 | appUI.color.Hover = toHex(baseColor, -22); 306 | appUI.color.Icon = toHex(baseColor, 104); 307 | appUI.color.InputIdle = toHex(baseColor, -14); 308 | appUI.color.InputActive = toHex(baseColor, 202); 309 | appUI.color.FontActive = toHex(baseColor, -255); 310 | break; 311 | default: 312 | appUI.color.Focus = toHex(appSkin.systemHighlightColor); 313 | break; 314 | } 315 | } else { 316 | appUI.data.theme = 'Darkest'; 317 | appUI.color.FontDisabled = toHex(baseColor, 32); 318 | appUI.color.Hover = toHex(baseColor, -9); 319 | appUI.color.Disabled = toHex(baseColor, 7); 320 | appUI.color.Active = toHex(baseColor, -19); 321 | switch(appUI.data.name) { 322 | case 'PHXS': 323 | appUI.color.Focus = '#0f64d2'; 324 | appUI.color.Font = toHex(baseColor, 162); 325 | appUI.color.Border = toHex(baseColor, 21); 326 | appUI.color.Icon = toHex(baseColor, 162); 327 | appUI.color.InputIdle = toHex(baseColor, -9); 328 | appUI.color.InputActive = appUI.color.InputIdle; 329 | appUI.color.FontActive = appUI.color.Font; 330 | break; 331 | case 'ILST': 332 | appUI.color.Focus = '#46a0f5'; 333 | appUI.color.Font = toHex(baseColor, 133); 334 | appUI.color.Border = toHex(baseColor, 12); 335 | appUI.color.Icon = toHex(baseColor, 130); 336 | appUI.color.InputIdle = toHex(baseColor, -12); 337 | appUI.color.InputActive = toHex(baseColor, 202); 338 | appUI.color.FontActive = toHex(baseColor, -255); 339 | break; 340 | default: 341 | appUI.color.Focus = toHex(appSkin.systemHighlightColor); 342 | // appUI.color.Focus = '#46a0f5'; 343 | appUI.color.Font = toHex(baseColor, 133); 344 | appUI.color.Border = toHex(baseColor, 12); 345 | appUI.color.Icon = toHex(baseColor, 130); 346 | appUI.color.InputIdle = toHex(baseColor, -12); 347 | appUI.color.InputActive = toHex(baseColor, 202); 348 | appUI.color.FontActive = toHex(baseColor, -255); 349 | break; 350 | } 351 | } 352 | updateThemeWithAppSkinInfo(); 353 | } 354 | 355 | 356 | 357 | /** 358 | * Convert the Color object to string in hexadecimal format; 359 | */ 360 | function toHex(color, delta) { 361 | function computeValue(value, delta) { 362 | var computedValue = !isNaN(delta) ? value + delta : value; 363 | if (computedValue < 0) { 364 | computedValue = 0; 365 | } else if (computedValue > 255) { 366 | computedValue = 255; 367 | } 368 | 369 | computedValue = Math.round(computedValue).toString(16); 370 | return computedValue.length == 1 ? "0" + computedValue : computedValue; 371 | } 372 | 373 | var hex = ""; 374 | if (color) { 375 | with (color) { 376 | hex = computeValue(red, delta) + computeValue(green, delta) + computeValue(blue, delta); 377 | }; 378 | } 379 | return "#" + hex; 380 | } 381 | 382 | function onAppThemeColorChanged(event) { 383 | var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo; 384 | logSkin(skinInfo); 385 | console.log(`Theme changed to ${appUI.data.theme}`); 386 | } 387 | 388 | 389 | 390 | // for (value in appUI.color) { 391 | // console.log('--color' + value, appUI.color); 392 | // } 393 | 394 | // $$$ // document.documentElement.style.setProperty('--color' + value, 'red'); 395 | 396 | // var sheets = [].slice.call(document.styleSheets); 397 | // sheets.forEach(function(e){ 398 | // if (e.href.includes('adobeStyle.css')) { 399 | // var style = e.cssRules.style; 400 | // e.cssRules[1].style.setProperty('--colorPanelBG', 'red'); 401 | // // console.log(e.cssRules[1].style); 402 | // // console.log(e.cssRules.style[0]); 403 | // 404 | // // e.cssRules[1].style.setProperty('--colorPanelBG', '#ff0000') 405 | // } 406 | // 407 | // }) 408 | 409 | // var jsSheet = document.styleSheets[7]; 410 | // var jsRules = jsSheet.cssRules; 411 | // console.log(sheet); 412 | // for (var i = 0; i < document.styleSheets.length; i++){ 413 | // 414 | // } 415 | // } 416 | -------------------------------------------------------------------------------- /client/myTstack/menu_Context.js: -------------------------------------------------------------------------------- 1 | var csInterface = new CSInterface(); 2 | var menu_ContextFlip = false; 3 | 4 | var menu_ContextXML = ' \ 5 | \ 6 | \ 7 | \ 8 | \ 9 | \ 10 | \ 11 | '; 12 | 13 | csInterface.setContextMenu(menu_ContextXML, setContextMenuCallback); 14 | 15 | function setContextMenuCallback(event) { 16 | if (event == "refresh") { 17 | location.reload(); 18 | } else if (event === 'check') { 19 | menu_ContextFlip = !menu_ContextFlip; 20 | console.log(`${event} is ${menu_ContextFlip}`); 21 | } else { 22 | console.log(event); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/myTstack/menu_Flyout.js: -------------------------------------------------------------------------------- 1 | var csInterface = new CSInterface(); 2 | var isFlipped = false; 3 | 4 | var menu_FlyoutXML = ' \ 5 | \ 6 | \ 7 | \ 8 | '; 9 | // \ 10 | // \ 11 | // \ 12 | 13 | csInterface.setPanelFlyoutMenu(menu_FlyoutXML); 14 | csInterface.addEventListener("com.adobe.csxs.events.flyoutMenuClicked", setPanelCallback); 15 | 16 | 17 | function setPanelCallback(event) { 18 | if (event.data.menuId == "refresh") { 19 | location.reload(); 20 | } else if (event.data.menuId == "message") { 21 | // csInterface.evalScript(`sendMsg()`); 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/myTstack/mightyFiles.js: -------------------------------------------------------------------------------- 1 | var csInterface = new CSInterface(); 2 | var sysPath = csInterface.getSystemPath(SystemPath.EXTENSION); 3 | var logPath = sysPath + "/log/"; 4 | 5 | // To see adobe i/o functions: 6 | // console.log(window.cep.fs); 7 | 8 | function clearTests() { 9 | fileArray = ['test1.js', 'test2.js', 'test3.js', 'test4.js', 'test5.js', 'test6.json']; 10 | myT.deleteFiles('./log', fileArray); 11 | } 12 | 13 | function howToWriteFile(){ 14 | var variablePath = logPath + 'test3.js'; 15 | myT.writeFile('.log/', 'test1.js', `I'm test 1!`); 16 | myT.writeFile('./log/test2.js', `I'm test 2!`); 17 | myT.writeFile(variablePath, `I'm test 3!`); 18 | myT.writeFile(logPath, 'test4.js', `I have (directory, name, content) parameters`); 19 | myT.writeFile(logPath + 'test5.js', 'Or (fullPath, content) parameters'); 20 | myT.writeFile(logPath, 'test6', `With 3 arguments I'll default to .json if name has no extension`); 21 | } 22 | 23 | 24 | function correctPathErrors(str) { 25 | str = (inString(str, '//') ? strReplace(str, '//', '/') : str ); 26 | str = ( !hasFileExtension(str) ? ((str[str.length - 1] !== '/') ? str + '/' : str ) : str) 27 | str = (/^.[a-z]/.test(str.substr(0,3)) ? str.replace('.', './') : str); 28 | return str; 29 | } 30 | 31 | function smartPath(path) { 32 | path = correctPathErrors(path); 33 | return (isLocalFile(path) ? sysPath + path : path); 34 | } 35 | 36 | function isLocalFile(file){ 37 | var str = csInterface.getSystemPath(SystemPath.EXTENSION); 38 | var parent = str.substring(str.lastIndexOf('/') + 1, str.length); 39 | if (!inString(file, parent)) { 40 | return true; 41 | } else { 42 | return false; 43 | } 44 | } 45 | 46 | 47 | var smartReg = { 48 | backwardSlash : /\\/g, 49 | multiSlash : /\/*\//g, 50 | hasFileExt : /\.([a-zA-Z])*[^\W]/g, 51 | local : /(\.){1,2}(\/)/, 52 | }; 53 | 54 | 55 | // console.log(hasParentRegEx(logPath, extFolder())); 56 | function hasParentRegEx(str, arg){ 57 | var value = false; 58 | var regEx = `(/)` + arg; 59 | var reg = new RegExp(regEx, "g"); 60 | return reg.test(str) 61 | } 62 | 63 | 64 | // DIRECTORY 65 | // 66 | 67 | const myT = { 68 | makeDir : function(path){ 69 | path = myT.isDirectory(smartPath(path)); 70 | var result = window.cep.fs.makedir(path); 71 | if (0 == result.err) 72 | return result.data; 73 | else 74 | return false; 75 | }, 76 | readDir : function(path){ 77 | path = myT.isDirectory(smartPath(path)); 78 | var result = window.cep.fs.readdir(path); 79 | if (0 == result.err) 80 | return result.data; 81 | else 82 | return false; 83 | }, 84 | readAllFiles : function(path){ 85 | path = myT.isDirectory(smartPath(path)); 86 | var collection = []; 87 | var children = myT.readDir(path); 88 | children.forEach(function(v,i,a){ 89 | collection.push(myT.readFile(path + '/' + v)); 90 | }); 91 | return collection; 92 | }, 93 | deleteDir : function(path){ 94 | path = myT.isDirectory(smartPath(path)); 95 | try { 96 | var children = myT.readDir(path); 97 | myT.deleteFiles(path, children); 98 | csInterface.evalScript(`deleteFolder('${path}')`, function(e){ 99 | return true; 100 | }) 101 | } catch(e){return false;} 102 | }, 103 | isDirectory : function(path){ 104 | var lastChar = path.substring(path.length - 1, path.length); 105 | if (lastChar == '/') { 106 | path = trimR(path, 1); 107 | } 108 | return path; 109 | }, 110 | readFile : function(args){ 111 | var result; 112 | let path = smartPath(arguments[0]); 113 | if (arguments.length > 1) { 114 | result = window.cep.fs.readFile(path + arguments[1]); 115 | } else { 116 | result = window.cep.fs.readFile(path); 117 | } 118 | if (0 == result.err) { 119 | return result.data; 120 | } 121 | }, 122 | readFiles : function(path, ...args){ 123 | path = smartPath(path); 124 | var mirror = []; 125 | for (var i = 0; i < args.length; i++) { 126 | if (hasArray(args[i])) { 127 | var children = args[i]; 128 | for (var e = 0; e < children.length; e++){ 129 | mirror.push(myT.readFile(path, children[e])); 130 | } 131 | } else { 132 | mirror.push(myT.readFile(path, args[i])); 133 | } 134 | } 135 | return mirror; 136 | }, 137 | writeFile : function(args) { 138 | var directory = smartPath(arguments[0]); 139 | var result; 140 | if (arguments.length > 2) { 141 | res = directory + arguments[1]; 142 | res = (hasFileExtension(res) ? res : res += '.json'); 143 | result = window.cep.fs.writeFile(res, arguments[2]); 144 | } else if (arguments.length > 1) { 145 | directory = (hasFileExtension(directory) ? directory : directory += '.json'); 146 | result = window.cep.fs.writeFile(directory, arguments[1]) 147 | } else { 148 | console.log("Need more parameters for myT.writeFile(name, data)"); 149 | return false; 150 | } 151 | if (0 == result.err) { 152 | return true; 153 | } else { 154 | return false; 155 | } 156 | }, 157 | writeFiles : function(path, paths=[], contents=[]){ 158 | path = smartPath(path); 159 | var errors = []; 160 | paths.forEach(function(v,i,a){ 161 | var rewrite = myT.writeFile(path, v, contents[i]); 162 | if (!rewrite) 163 | errors.push(i); 164 | }); 165 | if (!errors) 166 | return true; 167 | else 168 | return false; 169 | }, 170 | deleteFile : function(path, name){ 171 | path = smartPath(path); 172 | var result = window.cep.fs.deleteFile(path + name); 173 | return result; 174 | }, 175 | deleteFiles: function(path, ...args){ 176 | path = smartPath(path); 177 | var mirror = []; 178 | for (var i = 0; i < args.length; i++) { 179 | if (hasArray(args[i])) { 180 | var children = args[i]; 181 | for (var e = 0; e < children.length; e++){ 182 | mirror.push(myT.deleteFile(path, children[e])); 183 | } 184 | } else { 185 | mirror.push(myT.deleteFile(path, args[i])); 186 | } 187 | } 188 | return mirror; 189 | }, 190 | copyFile : function(path, ...args){ 191 | path = smartPath(path); 192 | var original, newName; 193 | if (args.length > 2) { 194 | original = args[0]; 195 | newName = args[2]; 196 | path2 = smartPath(args[1]); 197 | } else if (args.length > 1) { 198 | original = args[0]; 199 | newName = args[1]; 200 | path2 = path; 201 | } else { 202 | original = args[0]; 203 | newName = insertAliasBeforeExt(original); 204 | path2 = path; 205 | } 206 | var result = myT.writeFile(path2, newName, myT.readFile(path, original)); 207 | return result; 208 | } 209 | } 210 | 211 | 212 | function insertAliasBeforeExt(...args){ 213 | if (args.length > 1) { 214 | return args[0].insert(args[0].lastIndexOf('.'), args[1]); 215 | } else { 216 | return args[0].insert(args[0].lastIndexOf('.'), 'copy'); 217 | } 218 | } 219 | 220 | 221 | 222 | function extFolder(){ 223 | var str = csInterface.getSystemPath(SystemPath.EXTENSION); 224 | var parent = str.substring(str.lastIndexOf('/') + 1, str.length); 225 | return parent; 226 | } 227 | 228 | 229 | function hasFileExtension(str){ 230 | var errs = []; 231 | var ext = ['.js', '.jsx', '.html', '.css', '.json', '.svg', '.txt', '.md']; 232 | for (var i = 0; i < ext.length; i++){ 233 | if (inString(str, ext[i])) { 234 | errs.push(ext[i]); 235 | } 236 | } 237 | if (errs.length > 0) { 238 | return true; 239 | } else { 240 | return false; 241 | } 242 | } 243 | 244 | 245 | function findBetween(str, first, second){ 246 | var string = str.match(new RegExp(first + "(.*)" + second)); 247 | if (string !== null) { 248 | return string[1]; 249 | } else { 250 | return false; 251 | } 252 | } 253 | 254 | function hasArray(...args){ 255 | var err = false; 256 | for (var i = 0; i < args.length; i++){ 257 | if (args[i].constructor == Array) 258 | err = args[i]; 259 | } 260 | return err; 261 | } 262 | 263 | 264 | // function parseClassesFromLayerNames(str){ 265 | // var classes = (findBetween('id=\"hello .class\" ', 'id=\"', '\"')) ? true : false; 266 | // } 267 | 268 | // console.log(findBetween('id=\"hello .class\" ', 'id=\"', '\"')); 269 | // console.log(findBetween('id=\"what now\"', 'id', 'hello')); 270 | 271 | // console.log(hasArray('said', 'the', 'mouse', ['to', 'the', 'cur'])); 272 | // console.log(myT.readFile('./log/test1.js')); 273 | // console.log(myT.readFile(logPath, 'test2.js')); 274 | // console.log(myT.readFile('./log', 'test3.js')); 275 | 276 | // var thisDir =myT.readDir('./log'); 277 | // console.log(readDir('./log')); 278 | // console.log(readDir(logPath)) 279 | // console.log(thisDir[0]); 280 | // console.log(readDir('./log')); 281 | // myT.copyFile('./log', 'test1.js') 282 | // console.log(copyFile('./log', 'item.svg', './log/test', 'newItem.svg')); 283 | // console.log(copyFile('./log', 'test7.json')); 284 | // console.log(copyFile('.log', 'test7.json')); 285 | // myT.copyFile('./log', 'test1.js', './log/temp', 'test9.js') 286 | 287 | // myT.readFiles('./log', 'test1.js', 'test2.js', 'test3.js') 288 | // myT.readFiles('./log', ['test1.js', 'test2.js', 'test3.js']) 289 | 290 | // console.log(correctPathErrors('.//log//')); 291 | // console.log(correctPathErrors('./data//temp')); 292 | // console.log(correctPathErrors('.temp/')); 293 | // console.log(correctPathErrors('.log/data.json')); 294 | 295 | // console.log(strReplace('.said./the./mouse./to./the./cur', './', '/', 2)); 296 | // console.log(strReplace('./such./a./trial./dear./sir', './', '/', 1)); 297 | // console.log(strReplace('no no yes yes no no', 'no', 'yes')); 298 | // console.log(strReplace('no no yes yes no no', 'no')); 299 | // console.log(smartPath(logPath)); 300 | // console.log(smartPath('.log/test.js')); 301 | // console.log(smartPath('.//log/')); 302 | -------------------------------------------------------------------------------- /client/myTstack/mightyFunctions.js: -------------------------------------------------------------------------------- 1 | var csInterface = new CSInterface(); 2 | 3 | function dispatchEvent(name, data) { 4 | var event = new CSEvent(name, 'APPLICATION'); 5 | event.data = data; 6 | csInterface.dispatchEvent(event); 7 | } 8 | 9 | function chainEvent(data, name) { 10 | csInterface.evalScript(`JSXEvent('${data}', '${name}')`) 11 | } 12 | 13 | function changeCSSVar(prop, data){ 14 | document.documentElement.style.setProperty('--' + prop, data); 15 | } 16 | 17 | function deleteChildren(parent){ 18 | while(parent.firstChild){ 19 | parent.removeChild(parent.firstChild); 20 | } 21 | } 22 | 23 | function trimL(str, num) { 24 | return str.substr(num) 25 | } 26 | 27 | function trimR(str, num) { 28 | return str.slice(0, (num * -1)); 29 | } 30 | 31 | 32 | // trimEdges(string, both); 33 | // trimEdges(string, L, R); 34 | function trimEdges(str, ...num) { 35 | if (num.length > 1) { 36 | return str.substr(num[0]).slice(0, (num[1] * -1)); 37 | } else { 38 | return str.substr(num[0]).slice(0, (num[0] * -1)); 39 | } 40 | } 41 | 42 | 43 | // strReplace('a b c d', 'd'); 44 | // strReplace('a b c d', 'd', '1 2 3'); 45 | // strReplace('.said./the./mouse./to./the./cur', './', '/', 2) 46 | // strReplace('./such./a./trial./dear./sir', './', '/', 1) 47 | function strReplace(s, ...args){ 48 | if (args.length > 2) { 49 | var d = s.split(args[0]); 50 | var fixer = []; 51 | for (var i = 0; i < d.length; i++) { 52 | if (i < args[2]) { 53 | fixer.push(d[i] + args[1]) 54 | } else { 55 | fixer.push(d[i] + args[0]) 56 | }; 57 | }; 58 | return fixer.join(''); 59 | } else if (args.length > 1) { 60 | return s.split(args[0]).join(args[1]); 61 | } else { 62 | return s.split(args[0]).join(''); 63 | } 64 | } 65 | 66 | function inString(haystack, needle){ 67 | if (haystack.includes(needle)) { 68 | return true; 69 | } else { 70 | return false; 71 | } 72 | } 73 | 74 | 75 | function switchClass(elt, class1, class2) { 76 | if (elt.classList.contains(class1)) { 77 | elt.classList.remove(class1); 78 | elt.classList.add(class2); 79 | } 80 | } 81 | 82 | function hasClass(elt, ...targets) { 83 | var match = false; 84 | var classes = elt.classList.toString(); 85 | for (var i = 0; i < targets.length; i++) { 86 | if (inString(classes, targets[i])) { 87 | match = true; 88 | } 89 | } 90 | return match; 91 | } 92 | 93 | function containsMultiple(haystack, needle){ 94 | if (haystack.split(needle).length > 2) { 95 | return true; 96 | } else { 97 | return false; 98 | } 99 | } 100 | 101 | // function hasFileExtension(str){ 102 | // console.log(str.lastIndexOf('.')); 103 | // if (str.lastIndexOf('.') > 4) { 104 | // return false; 105 | // } else { 106 | // return true; 107 | // } 108 | // 109 | // } 110 | 111 | 112 | function isBetween(a, b, c) { 113 | if ((a > b) && (a < c)) { 114 | return true; 115 | } else { 116 | return false; 117 | } 118 | } 119 | 120 | 121 | var contains = function (haystack, needle) { 122 | return !!~haystack.indexOf(needle); 123 | }; 124 | 125 | String.prototype.insert = function (index, string) { 126 | if (index > 0) 127 | return this.substring(0, index) + string + this.substring(index, this.length); 128 | else 129 | return string + this; 130 | }; 131 | 132 | // // can be used like so now: 133 | // if (contains(items, 3452)) { 134 | // // do something else... 135 | // } 136 | 137 | 138 | // 1 param: automatic div tag, param is either id or classes (no solo class) 139 | // createChild(preview, ['adobe adobe-btn']); 140 | 141 | // 3 params: tag, id/classes, class 142 | // createChild(preview, ['div', 'hello', 'fa fa-lg fa-magic']); 143 | function createChild(parent, child) { 144 | var id = false; 145 | var classes = false; 146 | var tag = false; 147 | if (child.length < 2) { 148 | tag = 'div'; 149 | } else { 150 | tag = child[0]; 151 | } 152 | var container = parent.appendChild(document.createElement(tag)) 153 | if (child.length > 1) { 154 | if (theseAreClasses(child[1])) { 155 | classes = child[1]; 156 | } else { 157 | id = child[1]; 158 | } 159 | } 160 | if (child.length > 3) { 161 | if (tag == 'input') { 162 | container.type = "text"; 163 | container.name = id; 164 | container.value = child[3]; 165 | } else if (tag == 'span') { 166 | container.textContent = child[3]; 167 | } 168 | classes = child[2]; 169 | } else if (child.length > 2) { 170 | id = child[1]; 171 | classes = child[2]; 172 | } else if (child.length > 1) { 173 | // console.log('Two params'); 174 | } else if (child.length > 0) { 175 | if (theseAreClasses(child[0])) { 176 | classes = child[0]; 177 | } else { 178 | id = child[0]; 179 | } 180 | } 181 | if (classes) { 182 | container.setAttribute("class", classes); 183 | } 184 | if (id) { 185 | container.id = id; 186 | } 187 | } 188 | 189 | function theseAreClasses(target){ 190 | if (inString(target, ' ')) { 191 | return true; 192 | } else { 193 | return false; 194 | } 195 | } 196 | 197 | function loadJavaScript(filename){ 198 | var fileref=document.createElement('script') 199 | fileref.setAttribute("type","text/javascript") 200 | fileref.setAttribute("src", "../log/" + filename + ".js") 201 | if (typeof fileref!="undefined") 202 | document.getElementsByTagName("head")[0].appendChild(fileref) 203 | } 204 | -------------------------------------------------------------------------------- /client/myTstack/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } 49 | -------------------------------------------------------------------------------- /client/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --quart: cubic-bezier(0.76, 0.00, 0.24, 1.00); 3 | --colorBBox: #086baf; 4 | --colorSAFocus: #086baf; 5 | --icoDefOpacity: 1; 6 | --icoScrunchOpacity: 0; 7 | --frameNodes: 0; 8 | --frameDash: 0; 9 | --frameSolid: 0; 10 | } 11 | 12 | #TopToolbar { 13 | display: none; 14 | } 15 | 16 | @media only screen and (max-width: 110px) { 17 | body { 18 | margin: 0px 0px; 19 | } 20 | 21 | #TopToolbar { 22 | display: flex; 23 | } 24 | #padComponents { 25 | display: none; 26 | } 27 | } 28 | 29 | #content { 30 | margin: 1rem 0px; 31 | } 32 | 33 | svg { 34 | width: 100%; 35 | } 36 | 37 | .icoDef { 38 | opacity: var(--icoDefOpacity); 39 | } 40 | 41 | .icoScrunch { 42 | opacity: var(--icoScrunchOpacity); 43 | } 44 | 45 | .icoFill { 46 | fill: var(--colorIcon); 47 | transition: opacity 100ms var(--quart) 0ms; 48 | cursor: pointer; 49 | } 50 | 51 | .bound { 52 | fill: rgba(0,0,0,0.2); 53 | transition: fill 100ms var(--quart) 20ms; 54 | cursor: pointer; 55 | } 56 | 57 | 58 | g:hover > .bound { 59 | fill: var(--colorBorder); 60 | /* -webkit-filter: drop-shadow(2rem 2rem 1rem rgba(0,0,0,0.5)); */ 61 | } 62 | 63 | g:active > .icoFill { 64 | fill: var(--colorPanelBG); 65 | } 66 | 67 | g:active > .icoStr { 68 | stroke: var(--colorPanelBG); 69 | } 70 | 71 | g:active > .bound { 72 | fill: var(--colorSAFocus); 73 | } 74 | 75 | .frameDashLine { 76 | /* opacity: var(--BBoxDashes); */ 77 | fill: none; 78 | stroke: var(--colorBBox); 79 | stroke-miterlimit: 10; 80 | stroke-dasharray: 7.664572715759277,7.664572715759277; 81 | transition: stroke 100ms var(--quart) 20ms; 82 | } 83 | 84 | .icoStr { 85 | fill: none; 86 | stroke: var(--colorIcon); 87 | stroke-linecap: round; 88 | stroke-linejoin: round; 89 | } 90 | 91 | .frameNode { 92 | fill: #fff; 93 | stroke: var(--colorBBox); 94 | stroke-miterlimit: 10; 95 | transition: stroke 100ms var(--quart) 20ms, 96 | fill 100ms var(--quart) 20ms; 97 | } 98 | 99 | 100 | #frameNodes { 101 | opacity: var(--frameNodes); 102 | transition: opacity 180ms var(--quart) 20ms; 103 | } 104 | 105 | #frameSolid { 106 | opacity: var(--frameSolid); 107 | transition: opacity 180ms var(--quart) 20ms; 108 | } 109 | 110 | #frameDash { 111 | opacity: var(--frameDash); 112 | transition: opacity 180ms var(--quart) 20ms; 113 | } 114 | 115 | #frameS { 116 | stroke: var(--colorBBox); 117 | fill: none; 118 | } 119 | 120 | #bMovin { 121 | /* position:relative; */ 122 | /* border: 2px solid red; */ 123 | height: auto; 124 | } 125 | 126 | 127 | 128 | /* #fillButton { 129 | fill: #007bff; 130 | } */ 131 | 132 | .adobe-btn { 133 | font-size: 1.5rem; 134 | } 135 | 136 | .adobe-btn-sp { 137 | margin: 0px; 138 | } 139 | 140 | .adobe-toolbar-sp { 141 | display: flex; 142 | justify-content: center; 143 | flex-wrap: wrap; 144 | margin: 0px; 145 | align-items: center; 146 | } 147 | 148 | .adobe-btn-sp { 149 | max-width: 28%; 150 | font-size: 2rem; 151 | font-size: 28vw; 152 | /* display: inline-block; */ 153 | display: flex; 154 | padding: 0px; 155 | margin: 0px; 156 | /* border-width: var(--globalBorderWidth); */ 157 | border-style: solid; 158 | user-select: none; 159 | cursor: pointer; 160 | color: var(--colorFont); 161 | } 162 | -------------------------------------------------------------------------------- /host/AEFT.jsx: -------------------------------------------------------------------------------- 1 | var compCheck = app.project.item.length; 2 | var exist = app.project.item.length > 0; 3 | var thisComp; 4 | var isSelected; 5 | var selectedLength; 6 | var count; 7 | var selectedLayer; 8 | 9 | // alert(app.project.activeItem) 10 | 11 | function activeProject() { 12 | if (compCheck > 0) { 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | } 18 | 19 | if (compCheck > 0) { 20 | thisComp = app.project.activeItem; 21 | isSelected = app.project.activeItem.selectedLayers.length > 0; 22 | selectedLength = app.project.activeItem.selectedLayers.length; 23 | count = 0; 24 | selectedLayer = app.project.activeItem.selectedLayers[0]; 25 | } 26 | 27 | function textFromClipboard(clipboard) { 28 | if (app.project.activeItem.selectedLayers.length > 0) { 29 | for (var a = 0; a < app.project.activeItem.selectedLayers.length; a++) { 30 | var textLayer = thisComp.selectedLayers[a]; 31 | textLayer.sourceText.setValue(clipboard); 32 | } 33 | } else { 34 | alert("No text layer selected.") 35 | } 36 | } 37 | 38 | function docName() { 39 | var data = { 40 | name: "none", 41 | color: "none" 42 | }; 43 | if (exist) { 44 | data.comp = app.project.activeItem.name; 45 | // data.doc = app.project.file; 46 | return JSON.stringify(data); 47 | } 48 | } 49 | 50 | // main("color", "0000ff", "ff0000") 51 | // thanks Horshack @https://forums.adobe.com/thread/2317720 52 | function dumpPropTree(rootObj, nestingLevel, selected, type, find, replace) { 53 | var countProps = rootObj.numProperties; 54 | for (var propIndex=1; propIndex <= countProps; propIndex++) { 55 | var prop = rootObj.property(propIndex); 56 | // thanks Dan Ebberts 57 | switch(prop.propertyValueType) { 58 | case PropertyValueType.COLOR: 59 | if ((type === 'color') && (isVisibleColorPropery(prop))) { 60 | var newColor = rgbToHex(prop.value[0] * 255, prop.value[1] * 255, prop.value[2] * 255); 61 | if (newColor === find) { 62 | var replaceColor = hexToRgb(replace); 63 | prop.setValue([replaceColor.r/255, replaceColor.g/255, replaceColor.b/255]) 64 | } 65 | } 66 | break; 67 | default: 68 | break; 69 | } 70 | if (prop.name === find) { 71 | if (type === "name") { 72 | prop.name = replace; 73 | } else if (type === "select") { 74 | prop.selected = true; 75 | } 76 | } 77 | if ((type === 'expression') && (prop.canSetExpression)) { 78 | if (prop.expression) { 79 | var oldExp = prop.expression; 80 | var re = new RegExp(find); 81 | var newExp = oldExp.replace(re, replace); 82 | prop.expression = newExp; 83 | } 84 | } 85 | if (prop.numProperties > 0) 86 | dumpPropTree(prop, nestingLevel+1, selected, type, find, replace); 87 | } 88 | } 89 | 90 | function main(selected, type, find, replace) { 91 | var activeComp = app.project.activeItem; 92 | var countSelectedLayers = activeComp.layers.length; 93 | for (selectedLayerIndex = 1; selectedLayerIndex <= countSelectedLayers; selectedLayerIndex++) { 94 | var layer = activeComp.layers[selectedLayerIndex]; 95 | dumpPropTree(layer, 0, selected, type, find, replace); 96 | } 97 | } 98 | 99 | // thanks Tomas Sinkunas 100 | function isVisibleColorPropery(property) { 101 | return property.propertyValueType === PropertyValueType.COLOR && !isHidden(property); 102 | } 103 | 104 | function isHidden(property) { 105 | var oldExpression = property.expression; 106 | try { 107 | // try to add some dummy expression; 108 | // If it errors out - this means property is hidden 109 | // overwise property can be modified 110 | property.expression = "value"; 111 | } catch (e) { 112 | return true; 113 | } 114 | // Set expression to it's old value; 115 | property.expression = oldExpression; 116 | return false; 117 | } 118 | 119 | 120 | 121 | /// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb 122 | 123 | function componentToHex(c) { 124 | var hex = c.toString(16); 125 | return hex.length == 1 ? "0" + hex : hex; 126 | } 127 | 128 | function rgbToHex(r, g, b) { 129 | return componentToHex(r) + componentToHex(g) + componentToHex(b); 130 | } 131 | 132 | function hexToRgb(hex) { 133 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 134 | return result ? { 135 | r: parseInt(result[1], 16), 136 | g: parseInt(result[2], 16), 137 | b: parseInt(result[3], 16) 138 | } : null; 139 | } 140 | -------------------------------------------------------------------------------- /host/ILST.jsx: -------------------------------------------------------------------------------- 1 | // var doc; 2 | // var exist = app.documents.length > 0; 3 | // 4 | // // function colorPicker(){ 5 | // // return $.colorPicker(-1); 6 | // // } 7 | // 8 | // 9 | // function docName() { 10 | // var data = { 11 | // name: "none", 12 | // path: "none" 13 | // }; 14 | // var newData = []; 15 | // if (exist) { 16 | // doc = app.activeDocument; 17 | // newData.push(doc.name); 18 | // newData.push(doc.path); 19 | // return newData; 20 | // } 21 | // } 22 | // 23 | // function doesExist() { 24 | // if (app.documents.length > 0) { 25 | // doc = app.activeDocument; 26 | // return true; 27 | // } else { 28 | // return false; 29 | // } 30 | // } 31 | // 32 | // function colorFromApp() { 33 | // if (app.isFillActive()) { 34 | // defaultColor = fillColorFromAI(); 35 | // } else { 36 | // defaultColor = strokeColorFromAI(); 37 | // } 38 | // return defaultColor; 39 | // } 40 | // 41 | // function fillColorFromAI() { 42 | // if (exist) { 43 | // var convertColor = rgbToHex(doc.defaultFillColor.red, doc.defaultFillColor.green, doc.defaultFillColor.blue); 44 | // return convertColor; 45 | // } else { 46 | // return "ffffff"; 47 | // } 48 | // } 49 | // function strokeColorFromAI() { 50 | // if (exist) { 51 | // var convertColor = rgbToHex(doc.defaultStrokeColor.red, doc.defaultStrokeColor.green, doc.defaultStrokeColor.blue); 52 | // return convertColor; 53 | // } else { 54 | // return "231f20"; 55 | // } 56 | // } 57 | -------------------------------------------------------------------------------- /host/PHXS.jsx: -------------------------------------------------------------------------------- 1 | var doc; 2 | var exist = app.documents.length > 0; 3 | 4 | function docName() { 5 | var data = { 6 | name: "none", 7 | path: "none" 8 | }; 9 | var newData = []; 10 | if (exist) { 11 | doc = app.activeDocument; 12 | // data.name = doc.name; 13 | // data.path = doc.path; 14 | newData.push(doc.name); 15 | newData.push(doc.path); 16 | // alert(data.path); 17 | // alert(data.name + " " + data.path) 18 | return newData; 19 | // return JSON.stringify(data); 20 | } 21 | } 22 | 23 | function doesExist() { 24 | if (app.documents.length > 0) { 25 | doc = app.activeDocument; 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | } 31 | 32 | function runScript(path) { 33 | $.evalFile(path) 34 | } 35 | -------------------------------------------------------------------------------- /host/align.jsx: -------------------------------------------------------------------------------- 1 | // ArtboardCenterAroundSelectedPaths.jsx 2 | // works with CS5 3 | // http://forums.adobe.com/thread/1336506?tstart=0 4 | // (title: script to align selected objects to artboard) 5 | // quick & dirty, all selected items will be centered at the active artboard 6 | // (include clipping paths !visible result can be different) 7 | 8 | // regards pixxxelschubser 19.Nov. 2013 9 | 10 | 11 | /** @pixxxelschubser **/ 12 | function alignArtboardToSelection(){ 13 | var aDoc = app.activeDocument; 14 | var Sel = aDoc.selection; 15 | 16 | if (Sel.length > 0) { 17 | var abIdx = aDoc.artboards.getActiveArtboardIndex(); 18 | var actAbBds = aDoc.artboards[abIdx].artboardRect; 19 | 20 | var vBounds = Sel[0].visibleBounds; 21 | vBounds_Li = vBounds[0]; 22 | vBounds_Ob = vBounds[1]; 23 | vBounds_Re = vBounds[2]; 24 | vBounds_Un = vBounds[3]; 25 | 26 | if (Sel.length > 1) { 27 | for (var i = 1; i < Sel.length; i++) { 28 | vBdsI = Sel[i].visibleBounds; 29 | if( vBounds_Li > vBdsI[0] ) {vBounds_Li = vBdsI[0]}; 30 | if( vBounds_Ob < vBdsI[1] ) {vBounds_Ob = vBdsI[1]}; 31 | if( vBounds_Re < vBdsI[2] ) {vBounds_Re = vBdsI[2]}; 32 | if( vBounds_Un > vBdsI[3] ) {vBounds_Un = vBdsI[3]}; 33 | } 34 | 35 | aDoc.artboards[abIdx].artboardRect = [vBounds_Li +((vBounds_Re - vBounds_Li)/2-(actAbBds[2]-actAbBds[0])/2), vBounds_Ob -((vBounds_Ob - vBounds_Un)/2+(actAbBds[3]-actAbBds[1])/2), vBounds_Li +((vBounds_Re - vBounds_Li)/2-(actAbBds[2]-actAbBds[0])/2)+(actAbBds[2]-actAbBds[0]), vBounds_Ob -((vBounds_Ob - vBounds_Un)/2+(actAbBds[3]-actAbBds[1])/2)+(actAbBds[3]-actAbBds[1])]; 36 | } 37 | } else { 38 | alert ("No selection"); 39 | } 40 | } 41 | 42 | // alignSelection(); 43 | 44 | /** @TenA 45 | https://forums.adobe.com/thread/2111711 **/ 46 | function alignSelection(){ 47 | var refBnds = app.activeDocument.selection[0].geometricBounds; 48 | for (var i = 0; i < app.selection.length; i++) { 49 | var target = app.selection[i]; 50 | var ct = refBnds[0] + (refBnds[2] - refBnds[0]) / 2; 51 | var md = refBnds[1] + (refBnds[3] - refBnds[1]) / 2; 52 | var wd = target.width; 53 | var ht = target.height; 54 | target.position = [ct - wd / 2, md + ht / 2]; 55 | } 56 | } 57 | 58 | // alert(getBBox()); 59 | 60 | getBoundingBox(); 61 | 62 | function getTrueSizes(){ 63 | var x, y, w, h; 64 | var group = []; 65 | for (var i = 0; i < app.selection.length; i++) { 66 | var trueRect = []; 67 | var rect = [] 68 | var target = app.selection[i]; 69 | var bounds = target.geometricBounds; 70 | for (var a = 0; a < bounds.length; a++) { 71 | if (bounds[a] < 0) 72 | bounds[a] = bounds[a]*(-1); 73 | rect.push(bounds[a]) 74 | } 75 | x = rect[0]; 76 | y = rect[1]; 77 | w = ((rect[0] - rect[2]) < 0) ? ((rect[0] - rect[2])*(-1)) : (rect[0] - rect[2]) 78 | h = ((rect[1] - rect[3]) < 0) ? ((rect[1] - rect[3])*(-1)) : (rect[1] - rect[3]) 79 | trueRect.push(x, y, w, h) 80 | group.push(trueRect); 81 | } 82 | return group; 83 | } 84 | 85 | // alert(getBoundingBox()) 86 | 87 | function getBoundingBox() { 88 | var grp = getTrueSizes(); 89 | var width, height; 90 | // iterate through objects to find numbers based on value and not selection order 91 | width = (grp[0][0] - (grp[1][0] + grp[1][2])); 92 | height = (grp[0][1] - (grp[1][1] + grp[1][3])); 93 | width = (width < 0) ? width * (-1) : width; 94 | height = (height < 0) ? height * (-1) : height; 95 | return rect = [ grp[0][0], grp[0][1], width, height ]; 96 | // alert("w: " + width + ", h:" + height) 97 | } 98 | 99 | 100 | // alert(getBounds(selection, 'geometricBounds')) 101 | 102 | /** @Alexander Ladygin 103 | https://forums.adobe.com/thread/2109761 **/ 104 | function getBounds(arr, bounds) { 105 | var x = [], y = [], w = [], h = [], 106 | bounds = bounds || 'geometricBounds'; 107 | 108 | for ( var i = 0; i < arr.length; i++ ) { 109 | x.push(arr[i][bounds][0]); 110 | y.push(arr[i][bounds][1]); 111 | w.push(arr[i][bounds][2]); 112 | h.push(arr[i][bounds][3]); 113 | } 114 | 115 | x = Math.min.apply(null, x); 116 | y = Math.max.apply(null, y); 117 | w = Math.max.apply(null, w); 118 | h = Math.min.apply(null, h); 119 | return rect = [ x, y, w, h ]; 120 | }; 121 | 122 | // var selectionXY = [ app.activeDocument.selection.bounds[0].as('px'), 123 | // app.activeDocument.selection.bounds[1].as('px') ]; 124 | 125 | // alert(selectionXY) 126 | -------------------------------------------------------------------------------- /host/smartAlign.jsx: -------------------------------------------------------------------------------- 1 | var thisDoc = app.documents[0]; 2 | var activeAB = thisDoc.artboards.getActiveArtboardIndex(); 3 | var lastAB = 0; 4 | var lastABOffset, isOrigin, thisAB, absAB, relAB; 5 | 6 | function selectScanner() { 7 | if (app.selection.length > 0) { 8 | return app.selection.length; 9 | } else { 10 | return 0; 11 | } 12 | } 13 | 14 | function scanCurrentArtboard(){ 15 | activeAB = thisDoc.artboards.getActiveArtboardIndex(); 16 | if (activeAB !== lastAB) 17 | return activeAB 18 | else 19 | return lastAB; 20 | lastAB = activeAB; 21 | } 22 | 23 | function updateArtboardDimensions(index){ 24 | var w, h; 25 | thisAB = thisDoc.artboards.getActiveArtboardIndex(); 26 | absAB = thisDoc.artboards[index].artboardRect; 27 | absAB[1] = (absAB[1] * (-1)); 28 | relAB = []; 29 | for (var inv = 0; inv < 4; inv++) { 30 | res = (absAB[inv] < 0) ? (absAB[inv] * (-1)) : absAB[inv]; 31 | relAB.push(roundTo(res, 4)); 32 | } 33 | if (absAB[0] < 0) 34 | w = (absAB[0] - relAB[2]); 35 | else 36 | w = (relAB[0] - relAB[2]); 37 | if (absAB[1] < 0) 38 | h = (absAB[1] - absAB[3]); 39 | else 40 | h = (relAB[1] - relAB[3]); 41 | w = (w < 0) ? (w*(-1)) : w; 42 | h = (h < 0) ? (h*(-1)) : h; 43 | lastABOffset = [ parseInt((absAB[0] * -1)), parseInt(absAB[1]), thisAB ] 44 | absAB[1] = (absAB[1] * (-1)); 45 | return rect = [ absAB[0], absAB[1], absAB[2], absAB[3], w, h, thisAB ]; 46 | // return rect = [ absAB[0], absAB[1], w, h ]; 47 | } 48 | 49 | 50 | 51 | /** modified from Alexander Ladygin: 52 | https://forums.adobe.com/thread/2109761 **/ 53 | function getBounds(arr, bounds) { 54 | thisAB = thisDoc.artboards.getActiveArtboardIndex(); 55 | var absX1, absY1, absX2, absY2; 56 | var x1 = [], y1 = [], x2 = [], y2 = [], 57 | bounds = bounds || 'geometricBounds'; 58 | 59 | // relative selection bounding box 60 | for (var i = 0; i < arr.length; i++) { 61 | x1.push(lastABOffset[0] + arr[i][bounds][0]); 62 | x2.push(lastABOffset[0] + arr[i][bounds][2]); 63 | y1.push((arr[i][bounds][1] + lastABOffset[1]) * -1); 64 | y2.push((arr[i][bounds][3] + lastABOffset[1]) * -1); 65 | } 66 | 67 | // find XY min/max, get width and height 68 | x1 = Math.min.apply(null, x1); 69 | y1 = Math.min.apply(null, y1); 70 | x2 = Math.max.apply(null, x2); 71 | y2 = Math.max.apply(null, y2); 72 | w = x2 - x1; 73 | h = y2 - y1; 74 | 75 | // reverse and store for absolute position of selection 76 | if (thisAB > 0) { 77 | absX1 = (lastABOffset[0] * -1) + x1; 78 | absX2 = (lastABOffset[0] * -1) + x2; 79 | absY1 = (lastABOffset[1] * -1) - y1; 80 | absY2 = (lastABOffset[1] * -1) - y2; 81 | } else { 82 | absX1 = x1; 83 | absY1 = y1; 84 | absX2 = x2; 85 | absY2 = y2; 86 | } 87 | 88 | // send two arrays with ; delimiter 89 | return rect = [ x1, y1, x2, y2, w, h ] + ";" + [ absX1, absY1, absX2, absY2, w, h ]; 90 | }; 91 | 92 | // alert(app.documents[0].artboards[0].artboardRect) 93 | // alignSingleToArtboard('NE'); 94 | // alignSelection('selection', 'Center', 20, 25, 100, 100) 95 | 96 | function alignSingleToArtboard(alignCompass, x1, y1, x2, y2) { 97 | // var currAB = app.documents[0].activeArtboard; 98 | var inverted = false; 99 | var indexAB = app.documents[0].artboards.getActiveArtboardIndex(); 100 | var boundsAB = app.documents[0].artboards[indexAB].artboardRect; 101 | if (indexAB < 1) 102 | inverted = true; 103 | var minX = x1; 104 | var maxX = x2; 105 | var minY = y1; 106 | var maxY = y2; 107 | var midX = (minX + (maxX - minX) / 2); 108 | var midY = (minY + (maxY - minY) / 2); 109 | 110 | var target = app.selection[0]; 111 | var wd = target.width; 112 | var ht = target.height; 113 | switch(alignCompass){ 114 | case 'NW': 115 | if (inverted) 116 | target.position = [minX, minY * -1]; 117 | else 118 | target.position = [minX, minY]; 119 | break; 120 | case 'N': 121 | if (inverted) 122 | target.position = [midX - wd / 2, minY * -1]; 123 | else 124 | target.position = [midX - wd / 2, minY]; 125 | break; 126 | case 'NE': 127 | if (inverted) 128 | target.position = [maxX - wd, minY * -1]; 129 | else 130 | target.position = [maxX - wd, minY]; 131 | break; 132 | case 'W': 133 | if (inverted) 134 | target.position = [minX, (midY - ht / 2) * -1]; 135 | else 136 | target.position = [minX, midY + ht / 2]; 137 | break; 138 | case 'Center': 139 | if (inverted) 140 | target.position = [midX - wd / 2, (midY - ht / 2) * -1]; 141 | else 142 | target.position = [midX - wd / 2, midY + ht / 2]; 143 | break; 144 | case 'E': 145 | if (inverted) 146 | target.position = [maxX - wd, (midY - ht / 2) * -1]; 147 | else 148 | target.position = [maxX - wd, midY + ht / 2]; 149 | break; 150 | case 'SW': 151 | if (inverted) 152 | target.position = [minX, (maxY - ht) * -1]; 153 | else 154 | target.position = [minX, maxY + ht]; 155 | break; 156 | case 'S': 157 | if (inverted) 158 | target.position = [midX - wd / 2, (maxY - ht) * -1]; 159 | else 160 | target.position = [midX - wd / 2, maxY + ht]; 161 | break; 162 | case 'SE': 163 | if (inverted) 164 | target.position = [maxX - wd, (maxY - ht) * -1]; 165 | else 166 | target.position = [maxX - wd, maxY + ht]; 167 | break; 168 | case 'alignY': 169 | if (inverted) 170 | target.position = [bounds[0], (midY - ht) * -1]; 171 | else 172 | target.position = [bounds[0], maxY - ht]; 173 | break; 174 | case 'alignX': 175 | if (inverted) 176 | target.position = [midX - wd / 2, bounds[1]]; 177 | else 178 | target.position = [midX - wd / 2, bounds[1]]; 179 | break; 180 | default: 181 | // alert(alignCompass); 182 | break; 183 | } 184 | } 185 | 186 | 187 | /** based on @TenA's response from 188 | https://forums.adobe.com/thread/2111711 **/ 189 | function alignSelection(alignType, alignTarget, alignCompass, x1, y1, x2, y2) { 190 | var refBnds; 191 | var inverted = false; 192 | if (alignTarget === 'selectionKey') { 193 | refBnds = app.activeDocument.selection[0].geometricBounds; 194 | } else { 195 | refBnds = [ x1, y1, x2, y2 ] 196 | } 197 | if (thisDoc.artboards.getActiveArtboardIndex() < 1) 198 | inverted = true; 199 | 200 | var minX = refBnds[0]; 201 | var minY = refBnds[1]; 202 | var maxX = refBnds[2]; 203 | var maxY = refBnds[3]; 204 | var midX = (minX + (maxX - minX) / 2); 205 | var midY = (minY + (maxY - minY) / 2); 206 | var boxW = maxX - minX; 207 | var boxH = maxY - minY; 208 | boxW = (boxW < 0) ? boxW * -1 : boxW; 209 | boxH = (boxH < 0) ? boxH * -1 : boxH; 210 | 211 | // calculate for Distributes 212 | var first = 0; 213 | var last = app.selection.length - 1; 214 | var startX = app.selection[0].width + minX; 215 | var endX = maxX - app.selection[last].width; 216 | var startY = app.selection[0].height + minY; 217 | var endY = maxY - app.selection[last].height; 218 | // var blendRect = [startX, startY, endX, endY]; 219 | // var blendW = blendRect[2] - blendRect[0]; 220 | // var blendH = blendRect[3] - blendRect[1]; 221 | var childrenW = app.selection[first].width + app.selection[last].width; 222 | var childrenH = app.selection[first].height + app.selection[last].height; 223 | for (var ii = 1; ii < last; ii++) { 224 | childrenW = childrenW + app.selection[ii].width; 225 | childrenH = childrenH + app.selection[ii].height; 226 | } 227 | var remainderW = boxW - childrenW; 228 | var remainderH = boxH - childrenH; 229 | var evenX = remainderW / (app.selection.length - 1); 230 | var evenY = remainderH / (app.selection.length - 1); 231 | 232 | // alert(boxH + " - " + childrenH + " = " + remainderH + " / " + last + " = " + evenY) 233 | // alert("totalW: " + boxW + ", childW: " + childrenW + ", remainder: " + remainderW + "\rtotalH: " + boxH + "childH: " + childrenH + ", remainder: " + remainderH); 234 | 235 | for (var i = 0; i < app.selection.length; i++) { 236 | var target = app.selection[i]; 237 | var wd = target.width; 238 | var ht = target.height; 239 | var bounds = target.geometricBounds; 240 | if (alignType === 'align') { 241 | switch(alignCompass){ 242 | case 'NW': 243 | if (inverted) 244 | target.position = [minX, minY * -1]; 245 | else 246 | target.position = [minX, minY]; 247 | break; 248 | case 'N': 249 | if (inverted) 250 | target.position = [midX - wd / 2, minY * -1]; 251 | else 252 | target.position = [midX - wd / 2, minY]; 253 | break; 254 | case 'NE': 255 | if (inverted) 256 | target.position = [maxX - wd, minY * -1]; 257 | else 258 | target.position = [maxX - wd, minY]; 259 | break; 260 | case 'W': 261 | if (inverted) 262 | target.position = [minX, (midY - ht / 2) * -1]; 263 | else 264 | target.position = [minX, midY + ht / 2]; 265 | break; 266 | case 'Center': 267 | if (inverted) 268 | target.position = [midX - wd / 2, (midY - ht / 2) * -1]; 269 | else 270 | target.position = [midX - wd / 2, midY + ht / 2]; 271 | break; 272 | case 'E': 273 | if (inverted) 274 | target.position = [maxX - wd, (midY - ht / 2) * -1]; 275 | else 276 | target.position = [maxX - wd, midY + ht / 2]; 277 | break; 278 | case 'SW': 279 | if (inverted) 280 | target.position = [minX, (maxY - ht) * -1]; 281 | else 282 | target.position = [minX, maxY + ht]; 283 | break; 284 | case 'S': 285 | if (inverted) 286 | target.position = [midX - wd / 2, (maxY - ht) * -1]; 287 | else 288 | target.position = [midX - wd / 2, maxY + ht]; 289 | break; 290 | case 'SE': 291 | if (inverted) 292 | target.position = [maxX - wd, (maxY - ht) * -1]; 293 | else 294 | target.position = [maxX - wd, maxY + ht]; 295 | break; 296 | case 'verticalCenter': 297 | if (inverted) 298 | target.position = [bounds[0], (midY - ht / 2) * -1]; 299 | else 300 | target.position = [bounds[0], midY + ht / 2]; 301 | break; 302 | case 'verticalTop': 303 | if (inverted) 304 | target.position = [bounds[0], minY * -1]; 305 | else 306 | target.position = [bounds[0], minY]; 307 | break; 308 | case 'verticalBottom': 309 | if (inverted) 310 | target.position = [bounds[0], (maxY - ht) * -1]; 311 | else 312 | target.position = [bounds[0], maxY + ht]; 313 | break; 314 | case 'horizontalCenter': 315 | if (inverted) 316 | target.position = [midX - wd / 2, bounds[1]]; 317 | else 318 | target.position = [midX - wd / 2, bounds[1]]; 319 | break; 320 | case 'horizontalLeft': 321 | if (inverted) 322 | target.position = [minX, bounds[1]]; 323 | else 324 | target.position = [minX, bounds[1]]; 325 | break; 326 | case 'horizontalRight': 327 | if (inverted) 328 | target.position = [maxX - wd, bounds[1]]; 329 | else 330 | target.position = [maxX - wd, bounds[1]]; 331 | break; 332 | default: 333 | // alert(alignCompass); 334 | break; 335 | } 336 | } else if (alignType === 'distribute') { 337 | var offsetWNum = boxW / (app.selection.length - 1); 338 | var offsetHNum = boxH / (app.selection.length - 1); 339 | switch(alignCompass){ 340 | case 'NW': 341 | if (inverted) { 342 | if (i == first) { 343 | target.position = [minX, minY]; 344 | } else if (i == last) { 345 | target.position = [maxX - wd, (maxY * -1) + ht]; 346 | } else { 347 | target.position = [minX + (offsetWNum * i) - (wd / 2), minY + ((offsetHNum * i) - (ht / 2)) * -1]; 348 | } 349 | } else { 350 | if (i == first) { 351 | target.position = [minX, minY]; 352 | } else if (i == last) { 353 | target.position = [maxX - wd, (maxY) + ht]; 354 | } else { 355 | target.position = [minX + (offsetWNum * i) - (wd / 2), minY - ((offsetHNum * i) + (ht / 2))]; 356 | } 357 | } 358 | break; 359 | } 360 | } else if (alignType === 'distributeEven') { 361 | // var offsetWNum = boxW / (app.selection.length - 1); 362 | // var offsetHNum = boxH / (app.selection.length - 1); 363 | switch(alignCompass){ 364 | case 'verticalCenter': 365 | if (inverted) { 366 | if (i == first) { 367 | target.position = [minX, minY]; 368 | } else if (i == last) { 369 | target.position = [maxX - wd, (maxY * -1) + ht]; 370 | } else { 371 | var prevXPos = app.selection[i-1].geometricBounds[0]; 372 | var prevWidth = app.selection[i-1].width; 373 | var prevYPos = app.selection[i-1].geometricBounds[1]; 374 | var prevHeight = app.selection[i-1].height; 375 | prevYPos = (prevYPos < 0) ? prevYPos * -1 : prevYPos; 376 | target.position = [bounds[0], (prevYPos + prevHeight + evenY) * -1]; 377 | } 378 | } else { 379 | if (i == first) { 380 | target.position = [minX, minY]; 381 | } else if (i == last) { 382 | target.position = [maxX - wd, (maxY) + ht]; 383 | } else { 384 | var prevXPos = app.selection[i-1].geometricBounds[0]; 385 | var prevWidth = app.selection[i-1].width; 386 | var prevYPos = app.selection[i-1].geometricBounds[1]; 387 | var prevHeight = app.selection[i-1].height; 388 | // alert(prevYPos + " " + prevHeight + " " + evenY) 389 | target.position = [bounds[0], prevYPos - prevHeight - evenY]; 390 | // target.position = [startX + (offsetWNum * i) - ] 391 | // alt: 392 | // target.position = [startX + (offsetWNum * i) + (wd / 2), (startY + (offsetHNum * i) + (ht / 2)) * -1]; 393 | } 394 | } 395 | break; 396 | case 'horizontalCenter': 397 | if (i == first) { 398 | target.position = [minX, minY]; 399 | } else if (i == last) { 400 | target.position = [maxX - wd, (maxY * -1) + ht]; 401 | } else { 402 | var prevXPos = app.selection[i-1].geometricBounds[0]; 403 | var prevWidth = app.selection[i-1].width; 404 | var prevYPos = app.selection[i-1].geometricBounds[1]; 405 | var prevHeight = app.selection[i-1].height; 406 | prevYPos = (prevYPos < 0) ? prevYPos * -1 : prevYPos; 407 | target.position = [prevXPos + prevWidth + evenX, bounds[1]]; 408 | } 409 | break; 410 | default: 411 | break; 412 | } 413 | } 414 | } 415 | } 416 | 417 | // alert(app.selection[app.selection.length - 1].width - app.selection[0].width) 418 | // alignSelection('distributeEven', 'selection', 'verticalCenter', 0, 0, 100, 100) 419 | 420 | 421 | function roundTo(n, digits) { 422 | var negative = false; 423 | if (digits === undefined) { 424 | digits = 0; 425 | } 426 | if( n < 0) { 427 | negative = true; 428 | n = n * -1; 429 | } 430 | var multiplicator = Math.pow(10, digits); 431 | n = parseFloat((n * multiplicator).toFixed(11)); 432 | n = (Math.round(n) / multiplicator).toFixed(2); 433 | if( negative ) { 434 | n = (n * -1).toFixed(2); 435 | } 436 | return n; 437 | } 438 | -------------------------------------------------------------------------------- /host/universal/Console.jsx: -------------------------------------------------------------------------------- 1 | function sendMsg(){ 2 | alert("Hello?") 3 | } 4 | 5 | var err = { 6 | name: "none", 7 | line: "0", 8 | full: "no errors", 9 | data: "errors", 10 | ifIs: 0 11 | }; 12 | 13 | JSXEvent(err, "com.init") 14 | 15 | function runScript(path) { 16 | try { 17 | $.evalFile(path) 18 | } catch (e) { 19 | JSXEvent(e.name + "," + e.line + "," + e + "," + e.message, "com.playwrite.error") 20 | } 21 | } 22 | 23 | function console(evalObj){ 24 | try { 25 | JSXEvent(evalObj, "com.playwrite.console") 26 | 27 | } catch(e) { 28 | JSXEvent(e, "com.playwrite.error") 29 | } 30 | } 31 | 32 | 33 | function JSXEvent(payload, eventType) { 34 | try { 35 | var xLib = new ExternalObject("lib:\PlugPlugExternalObject"); 36 | } catch (e) { 37 | JSXEvent(e, "com.playwrite.error") 38 | } 39 | if (xLib) { 40 | var eventObj = new CSXSEvent(); 41 | eventObj.type = eventType; 42 | eventObj.data = payload; 43 | eventObj.dispatch(); 44 | } 45 | return; 46 | } 47 | 48 | 49 | 50 | 51 | 52 | // function triggerJSXFunction(isOn) { 53 | // if (isOn) { 54 | // // there's a returning value from JS 55 | // alert("Returning value: " + isOn); 56 | // } else { 57 | // if (Math.random() > 0.5) { 58 | // // payload is a regular string 59 | // JSXEvent(somePayload, "ConsoleEvent"); 60 | // } else { 61 | // // payload is a stringified function to be evaluated 62 | // JSXEvent(someOtherPayload, "Custom Event 2"); 63 | // } 64 | // } 65 | // } 66 | 67 | 68 | /// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb 69 | function componentToHex(c) { 70 | var hex = c.toString(16); 71 | return hex.length == 1 ? "0" + hex : hex; 72 | } 73 | 74 | function rgbToHex(r, g, b) { 75 | return componentToHex(r) + componentToHex(g) + componentToHex(b); 76 | } 77 | 78 | function hexToRgb(hex) { 79 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 80 | return result ? { 81 | r: parseInt(result[1], 16), 82 | g: parseInt(result[2], 16), 83 | b: parseInt(result[3], 16) 84 | } : null; 85 | } 86 | 87 | // var pathTo = { 88 | // sand: "none" 89 | // res: "none" 90 | // }; 91 | 92 | // var set = 'MySet'; 93 | // // Location of your saved Actions.aia file 94 | // var aia =File('~/Desktop/MySet.aia');// 95 | // // 96 | // try{ 97 | // app.unloadAction(set,''); 98 | // }catch(e){} 99 | 100 | // function bootActions(path) { 101 | // alert(path) 102 | // try { 103 | // app.loadAction(path); 104 | // } catch(e){alert(e);} 105 | // } 106 | 107 | // function logData(sandPath){ 108 | // pathTo.sand = sandPath; 109 | // // alert(pathTo.sand) 110 | // } 111 | -------------------------------------------------------------------------------- /icons/iconLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/icons/iconLight.png -------------------------------------------------------------------------------- /icons/iconLightRollover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/icons/iconLightRollover.png -------------------------------------------------------------------------------- /log/scribe.js: -------------------------------------------------------------------------------- 1 | // Testing scribe 2 | -------------------------------------------------------------------------------- /resources/Icons.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/Icons.ai -------------------------------------------------------------------------------- /resources/Smart-Align32/Read Me.txt: -------------------------------------------------------------------------------- 1 | Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures. 2 | 3 | To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/#docs/local-fonts 4 | 5 | You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects. 6 | 7 | You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection. 8 | -------------------------------------------------------------------------------- /resources/Smart-Align32/demo-files/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | font-family: sans-serif; 5 | font-size: 1em; 6 | line-height: 1.5; 7 | color: #555; 8 | background: #fff; 9 | } 10 | h1 { 11 | font-size: 1.5em; 12 | font-weight: normal; 13 | } 14 | small { 15 | font-size: .66666667em; 16 | } 17 | a { 18 | color: #e74c3c; 19 | text-decoration: none; 20 | } 21 | a:hover, a:focus { 22 | box-shadow: 0 1px #e74c3c; 23 | } 24 | .bshadow0, input { 25 | box-shadow: inset 0 -2px #e7e7e7; 26 | } 27 | input:hover { 28 | box-shadow: inset 0 -2px #ccc; 29 | } 30 | input, fieldset { 31 | font-family: sans-serif; 32 | font-size: 1em; 33 | margin: 0; 34 | padding: 0; 35 | border: 0; 36 | } 37 | input { 38 | color: inherit; 39 | line-height: 1.5; 40 | height: 1.5em; 41 | padding: .25em 0; 42 | } 43 | input:focus { 44 | outline: none; 45 | box-shadow: inset 0 -2px #449fdb; 46 | } 47 | .glyph { 48 | font-size: 16px; 49 | width: 15em; 50 | padding-bottom: 1em; 51 | margin-right: 4em; 52 | margin-bottom: 1em; 53 | float: left; 54 | overflow: hidden; 55 | } 56 | .liga { 57 | width: 80%; 58 | width: calc(100% - 2.5em); 59 | } 60 | .talign-right { 61 | text-align: right; 62 | } 63 | .talign-center { 64 | text-align: center; 65 | } 66 | .bgc1 { 67 | background: #f1f1f1; 68 | } 69 | .fgc1 { 70 | color: #999; 71 | } 72 | .fgc0 { 73 | color: #000; 74 | } 75 | p { 76 | margin-top: 1em; 77 | margin-bottom: 1em; 78 | } 79 | .mvm { 80 | margin-top: .75em; 81 | margin-bottom: .75em; 82 | } 83 | .mtn { 84 | margin-top: 0; 85 | } 86 | .mtl, .mal { 87 | margin-top: 1.5em; 88 | } 89 | .mbl, .mal { 90 | margin-bottom: 1.5em; 91 | } 92 | .mal, .mhl { 93 | margin-left: 1.5em; 94 | margin-right: 1.5em; 95 | } 96 | .mhmm { 97 | margin-left: 1em; 98 | margin-right: 1em; 99 | } 100 | .mls { 101 | margin-left: .25em; 102 | } 103 | .ptl { 104 | padding-top: 1.5em; 105 | } 106 | .pbs, .pvs { 107 | padding-bottom: .25em; 108 | } 109 | .pvs, .pts { 110 | padding-top: .25em; 111 | } 112 | .unit { 113 | float: left; 114 | } 115 | .unitRight { 116 | float: right; 117 | } 118 | .size1of2 { 119 | width: 50%; 120 | } 121 | .size1of1 { 122 | width: 100%; 123 | } 124 | .clearfix:before, .clearfix:after { 125 | content: " "; 126 | display: table; 127 | } 128 | .clearfix:after { 129 | clear: both; 130 | } 131 | .hidden-true { 132 | display: none; 133 | } 134 | .textbox0 { 135 | width: 3em; 136 | background: #f1f1f1; 137 | padding: .25em .5em; 138 | line-height: 1.5; 139 | height: 1.5em; 140 | } 141 | #testDrive { 142 | display: block; 143 | padding-top: 24px; 144 | line-height: 1.5; 145 | } 146 | .fs0 { 147 | font-size: 16px; 148 | } 149 | .fs1 { 150 | font-size: 32px; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /resources/Smart-Align32/demo-files/demo.js: -------------------------------------------------------------------------------- 1 | if (!('boxShadow' in document.body.style)) { 2 | document.body.setAttribute('class', 'noBoxShadow'); 3 | } 4 | 5 | document.body.addEventListener("click", function(e) { 6 | var target = e.target; 7 | if (target.tagName === "INPUT" && 8 | target.getAttribute('class').indexOf('liga') === -1) { 9 | target.select(); 10 | } 11 | }); 12 | 13 | (function() { 14 | var fontSize = document.getElementById('fontSize'), 15 | testDrive = document.getElementById('testDrive'), 16 | testText = document.getElementById('testText'); 17 | function updateTest() { 18 | testDrive.innerHTML = testText.value || String.fromCharCode(160); 19 | if (window.icomoonLiga) { 20 | window.icomoonLiga(testDrive); 21 | } 22 | } 23 | function updateSize() { 24 | testDrive.style.fontSize = fontSize.value + 'px'; 25 | } 26 | fontSize.addEventListener('change', updateSize, false); 27 | testText.addEventListener('input', updateTest, false); 28 | testText.addEventListener('change', updateTest, false); 29 | updateSize(); 30 | }()); 31 | -------------------------------------------------------------------------------- /resources/Smart-Align32/fonts/Smart-Align32.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /resources/Smart-Align32/fonts/Smart-Align32.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/Smart-Align32/fonts/Smart-Align32.ttf -------------------------------------------------------------------------------- /resources/Smart-Align32/fonts/Smart-Align32.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/Smart-Align32/fonts/Smart-Align32.woff -------------------------------------------------------------------------------- /resources/Smart-Align32/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Smart-Align32'; 3 | src: 4 | url('fonts/Smart-Align32.ttf?rii5vg') format('truetype'), 5 | url('fonts/Smart-Align32.woff?rii5vg') format('woff'), 6 | url('fonts/Smart-Align32.svg?rii5vg#Smart-Align32') format('svg'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | [class^="icon-"], [class*=" icon-"] { 12 | /* use !important to prevent issues with browser extensions that change fonts */ 13 | font-family: 'Smart-Align32' !important; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | 21 | /* Better Font Rendering =========== */ 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .icon-alignE:before { 27 | content: "\e900"; 28 | color: #a1a1a1; 29 | } 30 | .icon-alignN:before { 31 | content: "\e901"; 32 | color: #a1a1a1; 33 | } 34 | .icon-alignNE:before { 35 | content: "\e902"; 36 | color: #a1a1a1; 37 | } 38 | .icon-alignNW:before { 39 | content: "\e903"; 40 | color: #a1a1a1; 41 | } 42 | .icon-alignS:before { 43 | content: "\e904"; 44 | color: #a1a1a1; 45 | } 46 | .icon-alignSE:before { 47 | content: "\e905"; 48 | color: #a1a1a1; 49 | } 50 | .icon-alignSW:before { 51 | content: "\e906"; 52 | color: #a1a1a1; 53 | } 54 | .icon-alignW:before { 55 | content: "\e907"; 56 | color: #a1a1a1; 57 | } 58 | .icon-alignX:before { 59 | content: "\e908"; 60 | color: #a1a1a1; 61 | } 62 | .icon-alignY:before { 63 | content: "\e909"; 64 | color: #a1a1a1; 65 | } 66 | .icon-artboard .path1:before { 67 | content: "\e90a"; 68 | color: rgb(161, 161, 161); 69 | opacity: 0.2; 70 | } 71 | .icon-artboard .path2:before { 72 | content: "\e90b"; 73 | margin-left: -1em; 74 | color: rgb(161, 161, 161); 75 | } 76 | .icon-artboard .path3:before { 77 | content: "\e90c"; 78 | margin-left: -1em; 79 | color: rgb(161, 161, 161); 80 | } 81 | .icon-artboard .path4:before { 82 | content: "\e90d"; 83 | margin-left: -1em; 84 | color: rgb(161, 161, 161); 85 | } 86 | .icon-Center:before { 87 | content: "\e90e"; 88 | color: #a1a1a1; 89 | } 90 | .icon-distE:before { 91 | content: "\e90f"; 92 | color: #a1a1a1; 93 | } 94 | .icon-distN:before { 95 | content: "\e910"; 96 | color: #a1a1a1; 97 | } 98 | .icon-distNE:before { 99 | content: "\e911"; 100 | color: #a1a1a1; 101 | } 102 | .icon-distNW:before { 103 | content: "\e912"; 104 | color: #a1a1a1; 105 | } 106 | .icon-distS:before { 107 | content: "\e913"; 108 | color: #a1a1a1; 109 | } 110 | .icon-distSE:before { 111 | content: "\e914"; 112 | color: #a1a1a1; 113 | } 114 | .icon-distSW:before { 115 | content: "\e915"; 116 | color: #a1a1a1; 117 | } 118 | .icon-distW:before { 119 | content: "\e916"; 120 | color: #a1a1a1; 121 | } 122 | .icon-distX:before { 123 | content: "\e917"; 124 | color: #a1a1a1; 125 | } 126 | .icon-distY:before { 127 | content: "\e918"; 128 | color: #a1a1a1; 129 | } 130 | .icon-E:before { 131 | content: "\e919"; 132 | color: #a1a1a1; 133 | } 134 | .icon-N:before { 135 | content: "\e91a"; 136 | color: #a1a1a1; 137 | } 138 | .icon-NE:before { 139 | content: "\e91b"; 140 | color: #a1a1a1; 141 | } 142 | .icon-NW:before { 143 | content: "\e91c"; 144 | color: #a1a1a1; 145 | } 146 | .icon-S:before { 147 | content: "\e91d"; 148 | color: #a1a1a1; 149 | } 150 | .icon-SE:before { 151 | content: "\e91e"; 152 | color: #a1a1a1; 153 | } 154 | .icon-selection:before { 155 | content: "\e91f"; 156 | color: #a1a1a1; 157 | } 158 | .icon-SW:before { 159 | content: "\e920"; 160 | color: #a1a1a1; 161 | } 162 | .icon-W:before { 163 | content: "\e921"; 164 | color: #a1a1a1; 165 | } 166 | -------------------------------------------------------------------------------- /resources/SmartAlign1.1.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/SmartAlign1.1.ai -------------------------------------------------------------------------------- /resources/SmartAlign1.1.svg: -------------------------------------------------------------------------------- 1 | 2 | SmartAlign1.1css 3 | 4 | 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /resources/ToolbarFonts.ai: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 21 | 23 | 25 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 39 | 41 | 43 | 45 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 57 | 59 | 61 | 63 | 64 | 65 | 66 | 67 | 69 | 70 | 71 | 72 | 73 | 74 | 76 | 78 | 80 | 81 | 82 | 83 | 84 | 86 | 88 | 89 | 90 | 91 | 92 | 94 | 96 | 98 | 100 | 101 | 102 | 103 | 104 | 106 | 108 | 109 | 110 | 111 | 112 | 114 | 116 | 118 | 120 | 121 | 122 | 123 | 124 | 125 | 127 | 128 | 129 | 130 | 131 | 132 | 134 | 136 | 138 | 139 | 140 | 141 | 142 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 152 | 154 | 156 | 157 | 158 | 159 | 160 | 162 | 164 | 165 | 166 | 167 | 168 | 170 | 172 | 174 | 176 | 177 | 178 | 179 | 180 | 181 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 191 | 193 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 203 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 216 | 218 | 219 | 220 | 221 | 222 | 223 | 225 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 238 | 240 | 241 | 242 | 243 | 244 | 247 | 248 | 249 | 250 | 251 | 254 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /resources/artB.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | artB 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /resources/fonts/Smart-Align32.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /resources/fonts/Smart-Align32.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/fonts/Smart-Align32.ttf -------------------------------------------------------------------------------- /resources/fonts/Smart-Align32.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/fonts/Smart-Align32.woff -------------------------------------------------------------------------------- /resources/old/FullPad.aep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/old/FullPad.aep -------------------------------------------------------------------------------- /resources/old/FullPad.svg: -------------------------------------------------------------------------------- 1 | 2 | FullPad 3 | 4 | 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /resources/old/FullPad2.svg: -------------------------------------------------------------------------------- 1 | 2 | FullPad2 3 | 4 | 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /resources/old/PanelIcons.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/old/PanelIcons.ai -------------------------------------------------------------------------------- /resources/old/Proto1Pad.svg: -------------------------------------------------------------------------------- 1 | 2 | Proto 1 3 | 4 | 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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /resources/old/Smart-Align32.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/old/Smart-Align32.zip -------------------------------------------------------------------------------- /resources/old/SmartAlign1.0.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Inventsable/Smart-Align/dfcca7949c38968c622ef8f8e6d325ac9cbebacd/resources/old/SmartAlign1.0.ai -------------------------------------------------------------------------------- /resources/svg/Center.svg: -------------------------------------------------------------------------------- 1 | 2 | Center 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/E.svg: -------------------------------------------------------------------------------- 1 | 2 | E 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/N.svg: -------------------------------------------------------------------------------- 1 | 2 | N 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/NE.svg: -------------------------------------------------------------------------------- 1 | 2 | NE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/NW.svg: -------------------------------------------------------------------------------- 1 | 2 | NW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/S.svg: -------------------------------------------------------------------------------- 1 | 2 | S 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/SE.svg: -------------------------------------------------------------------------------- 1 | 2 | SE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/SW.svg: -------------------------------------------------------------------------------- 1 | 2 | SW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/W.svg: -------------------------------------------------------------------------------- 1 | 2 | W 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/alignE.svg: -------------------------------------------------------------------------------- 1 | 2 | alignE 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/alignN.svg: -------------------------------------------------------------------------------- 1 | 2 | alignN 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/alignNE.svg: -------------------------------------------------------------------------------- 1 | 2 | NE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/alignNW.svg: -------------------------------------------------------------------------------- 1 | 2 | NW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/alignS.svg: -------------------------------------------------------------------------------- 1 | 2 | alignS 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/alignSE.svg: -------------------------------------------------------------------------------- 1 | 2 | SE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/alignSW.svg: -------------------------------------------------------------------------------- 1 | 2 | SW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/alignW.svg: -------------------------------------------------------------------------------- 1 | 2 | alignW 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/alignX.svg: -------------------------------------------------------------------------------- 1 | 2 | alignX 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/alignY.svg: -------------------------------------------------------------------------------- 1 | 2 | alignY 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/artboard.svg: -------------------------------------------------------------------------------- 1 | 2 | artboard 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /resources/svg/distE.svg: -------------------------------------------------------------------------------- 1 | 2 | distE 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/svg/distN.svg: -------------------------------------------------------------------------------- 1 | 2 | distN 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/svg/distNE.svg: -------------------------------------------------------------------------------- 1 | 2 | NE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/distNW.svg: -------------------------------------------------------------------------------- 1 | 2 | NW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/distS.svg: -------------------------------------------------------------------------------- 1 | 2 | distS 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/svg/distSE.svg: -------------------------------------------------------------------------------- 1 | 2 | SE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/distSW.svg: -------------------------------------------------------------------------------- 1 | 2 | SW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/distW.svg: -------------------------------------------------------------------------------- 1 | 2 | distW 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/svg/distX.svg: -------------------------------------------------------------------------------- 1 | 2 | distX 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/svg/distY.svg: -------------------------------------------------------------------------------- 1 | 2 | distY 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/svg/framed/Center.svg: -------------------------------------------------------------------------------- 1 | 2 | Center 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/svg/framed/E.svg: -------------------------------------------------------------------------------- 1 | 2 | E 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/framed/N.svg: -------------------------------------------------------------------------------- 1 | 2 | N 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/framed/NE.svg: -------------------------------------------------------------------------------- 1 | 2 | NE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/framed/NW.svg: -------------------------------------------------------------------------------- 1 | 2 | NW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/framed/S.svg: -------------------------------------------------------------------------------- 1 | 2 | S 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/framed/SE.svg: -------------------------------------------------------------------------------- 1 | 2 | SE 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/framed/SW.svg: -------------------------------------------------------------------------------- 1 | 2 | SW 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/svg/framed/W.svg: -------------------------------------------------------------------------------- 1 | 2 | W 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/svg/selection.svg: -------------------------------------------------------------------------------- 1 | 2 | selection 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | --------------------------------------------------------------------------------