diff --git a/elements/app.js b/elements/app.js index ed72a102..844a986b 100644 --- a/elements/app.js +++ b/elements/app.js @@ -25,6 +25,7 @@ class App extends LitElement { --highlight-text: white; --selected-background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAAAAABX3VL4AAAADklEQVQIHWP4f4DhwH8ACoADf16N/DIAAAAASUVORK5CYII='); --z-index-menu: 10; + --z-index-dialog: 20; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', diff --git a/elements/index.js b/elements/index.js index b094682f..8cbbb457 100644 --- a/elements/index.js +++ b/elements/index.js @@ -1,3 +1,4 @@ +import './window/window.js'; import './app.js'; import './canvas.js'; import './color-box.js'; diff --git a/elements/window/window.js b/elements/window/window.js new file mode 100644 index 00000000..c6aedd4d --- /dev/null +++ b/elements/window/window.js @@ -0,0 +1,122 @@ +import { css, html, LitElement } from '../../web_modules/lit-element.js'; + +export class Window extends LitElement { + static get properties() { + return { + caption: { type: String }, + }; + } + + static get styles() { + return css` + :host { + border: 1px solid var(--button-face); + border-right-color: var(--button-text); + border-bottom-color: var(--button-text); + background-color: var(--button-face); + display: flex; + position: absolute; + z-index: var(--z-index-dialog); + } + + .wrapper { + border: 1px solid var(--highlight-text); + border-right-color: var(--canvas); + border-bottom-color: var(--canvas); + padding: 1px; + flex: 1; + display: flex; + flex-direction: column; + } + + div.title-bar { + background-color: var(--highlight); + color: var(--highlight-text); + height: 18px; + display: flex; + font-weight: bold; + align-items: center; + box-sizing: border-box; + padding: 1px 2px; + margin-bottom: 1px; + } + + div.title-bar span.title { + flex: 1; + } + + paint-window-title-bar-button:last-of-type { + margin-left: 2px; + } + `; + } + + constructor() { + super(); + + this.pointerMoveListener = this.onPointerMove.bind(this); + this.pointerUpListener = this.onPointerUp.bind(this); + document.addEventListener('pointermove', this.pointerMoveListener); + document.addEventListener('pointerup', this.pointerUpListener); + + this.position = { x: 100, y: 50 }; + this.moveWindow(); + } + + render() { + return html` +
+
+ ${this.caption} + + +
+
+ +
+
+ `; + } + + disconnectedCallback() { + super.disconnectedCallback(); + + document.removeEventListener('pointermove', this.pointerMoveListener); + document.removeEventListener('pointerup', this.pointerUpListener); + } + + onPointerDown({ clientX, clientY }) { + this.mousePosition = { clientX, clientY }; + } + + onPointerMove({ clientX, clientY }) { + // TODO: Disallow moving out of bounds + if (this.mousePosition) { + const deltaX = clientX - this.mousePosition.clientX; + const deltaY = clientY - this.mousePosition.clientY; + this.position.x = this.position.x + deltaX; + this.position.y = this.position.y + deltaY; + this.mousePosition = { clientX, clientY }; + this.moveWindow(); + } + } + + onPointerUp() { + this.mousePosition = null; + } + + moveWindow() { + this.style.transform = `translate(${this.position.x}px, ${this.position.y}px)`; + } + + onClose() { + this.dispatchEvent( + new CustomEvent('close', { bubbles: true, composed: true }), + ); + } +} + +customElements.define('paint-window', Window);