/** * @category MyEic * @subcategory Libraries * @extends View */ class WindozDomContent extends View { icon = null; /** * */ loadContent(name, options, data) { return this._controller.loadContent(name, options, data); } get expanded() { return this.el.hasAttribute('expanded'); } _saveWindowBox(){ const box = this.el.getBoundingClientRect() this.savedWindowBox = { width: `${box.width}px`, height: `${box.height}px`, left: `${box.x}px`, top: `${box.y}px`, } } /** * */ expand() { this._saveWindowBox() this.el.setAttribute('expanded',''); this.el.dispatchEvent(new CustomEvent('expanded')); this.el.style.left = 'auto'; this.el.style.top = 'auto'; this.el.style.height = 'auto'; this.el.style.width = 'auto'; this.DOMContentResized() } /** * */ shrink() { this.el.removeAttribute('expanded'); this.el.dispatchEvent(new CustomEvent('shrinked')); Object.assign(this.el.style, this.savedWindowBox) // this.el.style.left = this.el.getBoundingClientRect().x; // this.el.style.top = this.el.getBoundingClientRect().y; this.DOMContentResized(); } openDialog(view) { let promise = new Promise(function(resolve) { if(typeof view === 'string') { let content = view; view = new WindozDialogContent(); view.el = content; } let dialog = WindozController.createDialog(view); function commit(result) { WindozController.closeDialog(view._sparcId); resolve(result); } function abort(result) { WindozController.closeDialog(view._sparcId); resolve(result); } view.commit = commit; view.abort = abort; view.buttons.forEach(function(button) { dialog.querySelector('[eicdialog] > [eiccard] > footer').append(button.el); }); view.DOMContentFocused(); view.DOMContentResized(); }); return promise; } unload() { let button = this.el.closest('.window').querySelector('.controls .close') if(button) button.click(); } /** * */ initWindowEvents() { this.draggable(this.el); this.resizable(this.el, this.DOMContentResized.bind(this)); } draggable(element) { let mouseX, mouseY, offsetX = 0, offsetY = 0; // mouse button down over the element element.querySelector('header h1').addEventListener('mousedown', onMouseDown.bind(this)); /** * Listens to `mousedown` event. * * @param {Object} event - The event. */ function onMouseDown(event) { event.stopPropagation(); event.preventDefault(); mouseX = event.clientX; mouseY = event.clientY; offsetX = element.getBoundingClientRect().x; offsetY = element.getBoundingClientRect().y; document.addEventListener('mousemove', onMouseMove); element.addEventListener('mouseup', onMouseUp.bind(this)); } /** * Listens to `mouseup` event. * * @param {Object} event - The event. */ function onMouseUp(event) { offsetX = parseInt(element.style.left) || 0; offsetY = parseInt(element.style.top) || 0; document.removeEventListener('mousemove', onMouseMove); element.removeEventListener('mouseup', onMouseUp); if(this.windowPrefsId){ const box = element.getBoundingClientRect() app.User.setPreference(`windows.${this.windowPrefsId}`, { x: box.x, y: box.y, }); } } /** * Listens to `mousemove` event. * * @param {Object} event - The event. */ function onMouseMove(event) { if(event.buttons != 1) { document.removeEventListener('mousemove', onMouseMove); return; } let dX = event.clientX - mouseX; let dY = event.clientY - mouseY; element.style.left = offsetX + dX + 'px'; element.style.top = offsetY + dY + 'px'; } } resizable(element, onResize) { let mouseX, mouseY, offset = 0, offsetY = 0, grab = ''; element.querySelectorAll(':scope > .handle').forEach(handle => handle.addEventListener('mousedown', onMouseDown.bind(this))) element.querySelector('section').addEventListener('mousedown', onBlockMouseDown); function onBlockMouseDown(event) { event.stopPropagation(); } /** * mousedown event listener * * @param {Object} event - mouse event. */ function onMouseDown(event) { event.stopPropagation(); event.preventDefault(); if(event.currentTarget.parentElement.hasAttribute('expanded')) return false; let limits = element.getBoundingClientRect(); mouseX = event.clientX; mouseY = event.clientY; grab = event.currentTarget.dataset.side offset = element.getBoundingClientRect(); document.addEventListener('mousemove', onMouseMove); element.addEventListener('mouseup', onMouseUp.bind(this)); } /** * mouseup event listener * * @param {Object} event - The event. */ function onMouseUp(event) { document.removeEventListener('mousemove', onMouseMove); element.removeEventListener('mouseup', onMouseUp); if(this.windowPrefsId){ const box = element.getBoundingClientRect() app.User.setPreference(`windows.${this.windowPrefsId}`, { w: box.width, h: box.height, }); } } /** * Listens to `mousemove` event. * * @param {Object} event - The event. */ function onMouseMove(event) { if(event.buttons != 1) { document.removeEventListener('mousemove', onMouseMove); return; } let dx = event.clientX - mouseX; let dy = event.clientY - mouseY; mouseX = event.clientX; mouseY = event.clientY; if(grab.indexOf('n') > -1) { offset.y = offset.y + dy; offset.height = offset.height - dy; } if(grab.indexOf('s') > -1) { offset.height = offset.height + dy; } if(grab.indexOf('w') > -1) { offset.x = offset.x + dx; offset.width = offset.width - dx; } if(grab.indexOf('e') > -1) { offset.width = offset.width + dx; } element.style.left = offset.x + 'px'; element.style.top = offset.y + 'px'; element.style.height = offset.height + 'px'; element.style.width = offset.width + 'px'; onResize(); } } DOMContentResized() { let limits = [ { name: 'desktop', min: 768 }, { name: 'tablet', min: 600 }, { name: 'mobile', min: 0 } ]; let bounds = this.el.getBoundingClientRect(); let device = limits.find(item => item.min < bounds.width); this.el.setAttribute('device', device ? device.name: limits[0].name); } static boxFromPrefs(viewName, defaults){ function getPref(path) { return path.split('.').reduce( (acc, key) => acc?.[key], app.User.preferences.windows ) } let top, left, width, height const box = getPref(viewName) if(box){ left = box.x ? box.x : defaults.x top = box.y ? box.y : defaults.y width = box.w ? box.w : defaults.w height = box.h ? box.h : defaults.h } else { left = defaults.x top = defaults.y width = defaults.w height = defaults.h const ws = document.querySelector('[eicapp] .app-workspace')?.getBoundingClientRect() const areaLeft = ws?.left ?? 0 const areaTop = ws?.top ?? 0 const areaWidth = ws?.width ?? window.innerWidth const areaHeight = ws?.height ?? window.innerHeight if(left === 'center') left = Math.round(areaLeft + (areaWidth - width) / 2) if(top === 'center') top = Math.round(areaTop + (areaHeight - height) / 2) } return({ width: `${width}px`, height: `${height}px`, left: `${left}px`, top: `${top}px`, }) } } app.registerClass('WindozDomContent', WindozDomContent);