Skip to content

Instantly share code, notes, and snippets.

@tokyosheep
Last active March 6, 2023 13:20
Show Gist options
  • Select an option

  • Save tokyosheep/9b0781aed38a2db99b9b21db2fc145e8 to your computer and use it in GitHub Desktop.

Select an option

Save tokyosheep/9b0781aed38a2db99b9b21db2fc145e8 to your computer and use it in GitHub Desktop.
/*
use as a psjs not as a js.
this script defines UI Dialog.
*/
const { createLayer } = require("./photoshopAPI.psjs");
//dialog size
const DIALOG_WIDTH = '550px';
const DIALOG_HEIGHT = '650px';
const dialogStyle = {
padding: '20px',
boxSizing:'border-box'
};
/**
* modal window class object
*/
class ModalWindow {
constructor (dialog, header, main, footer) {
this._dialog = dialog;
this._dialog.width = DIALOG_WIDTH;
this._dialog.height = DIALOG_HEIGHT;
this.header = header;
this.main = main;
this.footer = footer;
this.setStyles(dialogStyle);
}
setStyles (styleObj) {
Object.entries(styleObj).forEach(([key, value]) => {
this.dialog.style[key] = value;
})
};
/**
* unit elements under dialog window
*/
uniteElms () {
this._dialog.appendChild(this.header);
this._dialog.appendChild(this.main);
this._dialog.appendChild(this.footer);
}
get dialog () {
return this._dialog;
}
};
class HTMLDocBase {
constructor (elm, className , id = null) {
this.elm = elm;
this.elm.className = className;
this.events = new Set();
this.children = new Set();
if (id !== null) this.elm.id = id;
};
setStyles (styleObj) {
Object.entries(styleObj).forEach(([key, value]) => {
this.elm.style[key] = value;
})
};
addElements (elms) {
if (Array.isArray(elms)){
for (let i=0;i<elms.length;i++) {
this.children.add(elms[i]);
this.elm.appendChild(elms[i].elm);
}
} else {
this.children.add(elms);
this.elm.appendChild(elms.elm);
}
};
removeAllChild () {
while (this.elm.firstChild) {
this.elm.removeChild(this.elm.firstChild);
};
this.children.clear();
};
getFirstChild () {
return this.children.size === 0 ? null : [...this.children][0];
}
getThroughClass (className) {
return this.children.find(child => child.elm.className === className) ?? null;
};
getThtoughId (id) {
return this.children.find(child => child.elm.id === id) ?? null;
};
addEvent (evetName, callback) {
if (this.events.has(evetName)) {
app.showAlert('it already has the event');
return;
}
this.events.add(evetName, {
evetName,
callback
});
this.elm.addEventListener(evetName, callback);
};
removeEvent (evetName) {
const target = this.events.has(evetName);
if (target === undefined) {
app.showAlert("this element doen't have the event");
return;
}
this.elm.removeEventListener(target.eventName, target.callback);
}
};
const headerStyle = {
width: '100%',
height: '40px'
}
class HeaderArea extends HTMLDocBase {
constructor () {
super(document.createElement('header'), 'header', 'headerArea');
this.setStyles(headerStyle);
};
};
const headTitleStyle = {
fontSize: '15px',
color: '#fff'
};
class HeadTitle extends HTMLDocBase {
constructor () {
super(document.createElement('h1'), 'head', 'headTitle');
this.elm.textContent = 'sample UI';
this.setStyles(headTitleStyle);
};
};
const mainWrapperStyle = {
width: '100%',
height: '500px',
};
class MainWrapper extends HTMLDocBase {
constructor () {
super(document.createElement('div'), 'wrapper', 'mainWrapper');
this.setStyles(mainWrapperStyle);
};
};
const footerStyle = {
width: '100%',
height: '40px',
display: 'flex',
justifyContent: 'flex-start',
gap: '10px'
};
class FooterArea extends HTMLDocBase {
constructor () {
super(document.createElement('footer'), 'footer', 'footerArea');
this.setStyles(footerStyle);
};
};
class SPActionButton extends HTMLDocBase {
constructor (name, className, id) {
super(document.createElement('sp-action-button'), className, id);
this.elm.textContent = name;
};
};
const createHeaderArea = () => {
const headerArea = new HeaderArea();
const headTitle = new HeadTitle();
headerArea.addElements(headTitle);
return { headerArea };
}
const createMainArea = () => {
const mainArea = new MainWrapper();
const button = new SPActionButton('create layer button');
button.addEvent("click", createLayer);
mainArea.addElements(button);
return { mainArea };
};
const spButtonClass = 'sp-actionbutton';
const createFooterArea = () => {
const footerArea = new FooterArea();
const closeButton = new SPActionButton('close', spButtonClass, 'closebutton');
footerArea.addElements([
closeButton
]);
return {
footerArea,
closeButton
};
};
const createDialog = async (headerArea, footerArea, mainArea) => {
const modalWindow = new ModalWindow(
document.createElement("dialog"),
headerArea.elm,
mainArea.elm,
footerArea.elm
);
modalWindow.uniteElms();
return modalWindow;
};
const showModalWindow = async() => {
const { headerArea } = createHeaderArea();
const {
footerArea,
closeButton
} = createFooterArea();
const { mainArea } = createMainArea();
const modal = await createDialog(headerArea, footerArea, mainArea);
document.body.appendChild(modal.dialog).showModal();
return new Promise((resolve, reject) => {
closeButton.addEvent('click', () => {
modal.dialog.close();
resolve("dialog cancelled");
})
modal.dialog.addEventListener("close", () => {
reject("dialog closed");
});
});
};
module.exports = showModalWindow;
/*
use Photoshop later than 24.2 because it needs unrestricted relative module environment.
use as a psjs not as a js.
this is index script file. run this script. other files are used as a module.
*/
const { app } = require("photoshop");
const showModalWindow = require("./dialogUI.psjs");
try {
await showModalWindow();
} catch (e) {
await app.showAlert(e);
}
// use as a psjs not as a js
const { app } = require("photoshop");
const createLayer = async () => {
if (app.documents.length < 1) {
await app.showAlert("there's no any document");
return;
}
try {
await app.activeDocument.createLayer();
} catch (e) {
await app.showAlert(e);
}
};
module.exports = {
createLayer
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment