Files
slava.home/main_plugin/dgrm/shapes/shape-settings.js

122 lines
4.3 KiB
JavaScript
Executable File

import { copyAndPast } from '../diagram/group-select-applay.js';
import { copySvg, delSvg } from '../infrastructure/assets.js';
import { clickForAll, listen, classSingleAdd, evtTargetAttr } from '../infrastructure/util.js';
import { modalChangeTop, modalCreate } from './modal-create.js';
import { ShapeSmbl } from './shape-smbl.js';
/**
* @param {import('../infrastructure/canvas-smbl').CanvasElement} canvas
* @param {import('./shape-smbl').ShapeElement} shapeElement
* @param {number} bottomX positon of the bottom left corner of the panel
* @param {number} bottomY positon of the bottom left corner of the panel
*/
export function settingsPnlCreate(canvas, shapeElement, bottomX, bottomY) {
const shapeSettings = new ShapeEdit();
listen(shapeSettings, 'cmd', /** @param {CustomEvent<{cmd:string, arg:string}>} evt */ evt => {
switch (evt.detail.cmd) {
case 'style': classSingleAdd(shapeElement, shapeElement[ShapeSmbl].data, 'cl-', evt.detail.arg); break;
case 'del': shapeElement[ShapeSmbl].del(); break;
case 'copy': copyAndPast(canvas, [shapeElement]); break;
}
});
return modalCreate(bottomX, bottomY, shapeSettings);
}
class ShapeEdit extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'closed' });
shadow.innerHTML =
`<style>
.ln { display: flex; }
.ln > * {
height: 24px;
padding: 10px;
cursor: pointer;
}
#prop { padding-bottom: 10px; }
.crcl { width: 25px; height: 25px; border-radius: 50%; }
</style>
<div id="pnl">
<div id="clr" style="display: none;">
<div class="ln">
<div data-cmd="style" data-cmd-arg="cl-red">
<div class="crcl" style="background: #E74C3C"></div>
</div>
<div data-cmd="style" data-cmd-arg="cl-orange">
<div class="crcl" style="background: #ff6600"></div>
</div>
<div data-cmd="style" data-cmd-arg="cl-green">
<div class="crcl" style="background: #19bc9b"></div>
</div>
</div>
<div class="ln">
<div data-cmd="style" data-cmd-arg="cl-blue">
<div class="crcl" style="background: #1aaee5"></div>
</div>
<div data-cmd="style" data-cmd-arg="cl-dblue">
<div class="crcl" style="background: #1D809F"></div>
</div>
<div data-cmd="style" data-cmd-arg="cl-dgray">
<div class="crcl" style="background: #495057"></div>
</div>
</div>
</div>
<div id="prop" style="display: none;"><slot id="slot"></slot></div>
</div>
<div class="ln">
<svg data-toggle="clr" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M19.228 18.732l1.768-1.768 1.767 1.768a2.5 2.5 0 1 1-3.535 0zM8.878 1.08l11.314 11.313a1 1 0 0 1 0 1.415l-8.485 8.485a1 1 0 0 1-1.414 0l-8.485-8.485a1 1 0 0 1 0-1.415l7.778-7.778-2.122-2.121L8.88 1.08zM11 6.03L3.929 13.1 11 20.173l7.071-7.071L11 6.029z" fill="rgb(52,71,103)"/></svg>
<svg data-toggle="prop" ${this.getAttribute('edit-btn') ? '' : 'style="display: none;"'} viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12.9 6.858l4.242 4.243L7.242 21H3v-4.243l9.9-9.9zm1.414-1.414l2.121-2.122a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414l-2.122 2.121-4.242-4.242z" fill="rgb(52,71,103)"/></svg>
${copySvg}
${delSvg}
</div>`;
//
// tabs
{
const pnl = shadow.getElementById('pnl');
/** @param {1|-1} coef */
function modalSetTop(coef) {
modalChangeTop(window.scrollY + coef * pnl.getBoundingClientRect().height); // window.scrollY fix IPhone keyboard
}
/** @type {HTMLElement} */
let currentTab;
clickForAll(shadow, '[data-toggle]', evt => {
if (currentTab) {
modalSetTop(1);
display(currentTab, false);
}
const tab = shadow.getElementById(evtTargetAttr(evt, 'data-toggle'));
if (currentTab !== tab) {
display(tab, true);
modalSetTop(-1);
currentTab = tab;
} else {
currentTab = null;
}
});
}
//
// commands
clickForAll(shadow, '[data-cmd]', evt => {
this.dispatchEvent(new CustomEvent('cmd', {
detail: {
cmd: evtTargetAttr(evt, 'data-cmd'),
arg: evtTargetAttr(evt, 'data-cmd-arg')
}
}));
});
}
}
customElements.define('ap-shape-edit', ShapeEdit);
/** @param {ElementCSSInlineStyle} el, @param {boolean} isDisp */
function display(el, isDisp) { el.style.display = isDisp ? 'unset' : 'none'; }