brush picker!
This commit is contained in:
parent
9b82b211b4
commit
c1612b2a94
12 changed files with 849 additions and 45 deletions
115
static/context-menu.js
Normal file
115
static/context-menu.js
Normal file
|
@ -0,0 +1,115 @@
|
|||
// - Create your context menu by instantiating ContextMenu and adding elements to it
|
||||
// - Open your menu in response to a contextmenu event by using globalContextMenuSpace.openAtCursor(event, menu)
|
||||
|
||||
import { listen } from "rkgk/framework.js";
|
||||
|
||||
export class ContextMenu extends HTMLElement {
|
||||
connectedCallback() {
|
||||
this.classList.add("rkgk-panel");
|
||||
|
||||
this.closeController = new AbortController();
|
||||
|
||||
this.hasMouse = false;
|
||||
this.addEventListener("mouseover", () => (this.hasMouse = true));
|
||||
this.addEventListener("mouseleave", () => (this.hasMouse = false));
|
||||
|
||||
window.addEventListener(
|
||||
"mousedown",
|
||||
() => {
|
||||
if (!this.hasMouse) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
{ signal: this.closeController.signal },
|
||||
);
|
||||
|
||||
window.addEventListener(
|
||||
"keydown",
|
||||
(event) => {
|
||||
if (event.key == "Escape") {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
{ signal: this.closeController.signal },
|
||||
);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.closeController.abort();
|
||||
}
|
||||
|
||||
close() {
|
||||
this.space.close(this);
|
||||
}
|
||||
|
||||
addButton(label, options) {
|
||||
let { classList, disabled, tooltip, noCloseOnClick } = options ?? {};
|
||||
classList ??= [];
|
||||
disabled ??= false;
|
||||
tooltip ??= "";
|
||||
noCloseOnClick ??= false;
|
||||
|
||||
let button = this.appendChild(document.createElement("button"));
|
||||
button.classList.add(...classList);
|
||||
button.innerText = label;
|
||||
button.disabled = disabled;
|
||||
button.title = tooltip;
|
||||
|
||||
button.addEventListener("click", () => {
|
||||
if (!noCloseOnClick) this.close();
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
addHtmlP(text, options) {
|
||||
let { classList } = options ?? {};
|
||||
classList ??= [];
|
||||
|
||||
let p = this.appendChild(document.createElement("p"));
|
||||
p.innerHTML = text;
|
||||
p.classList.add(...classList);
|
||||
return p;
|
||||
}
|
||||
|
||||
addSeparator() {
|
||||
this.appendChild(document.createElement("hr"));
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("rkgk-context-menu", ContextMenu);
|
||||
|
||||
export class ContextMenuSpace extends HTMLElement {
|
||||
open(contextMenu) {
|
||||
contextMenu.space = this;
|
||||
this.appendChild(contextMenu);
|
||||
}
|
||||
|
||||
close(contextMenu) {
|
||||
this.removeChild(contextMenu);
|
||||
}
|
||||
|
||||
openAtCursor(cursorEvent, contextMenu) {
|
||||
this.open(contextMenu);
|
||||
|
||||
// NOTE: This assumes the context menu space is positioned at (0, 0) and spans the full page.
|
||||
|
||||
let areaWidth = this.clientWidth;
|
||||
let areaHeight = this.clientHeight;
|
||||
let menuWidth = contextMenu.clientWidth;
|
||||
let menuHeight = contextMenu.clientHeight;
|
||||
|
||||
let x = cursorEvent.clientX;
|
||||
let y = cursorEvent.clientY;
|
||||
|
||||
// If the menu would reach outside the screen bounds, snap it back in.
|
||||
if (x + menuWidth > areaWidth) x -= menuWidth;
|
||||
if (y + menuHeight > areaHeight) y -= menuHeight;
|
||||
|
||||
contextMenu.style.transform = `translate(${x}px, ${y}px)`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("rkgk-context-menu-space", ContextMenuSpace);
|
||||
|
||||
export const globalContextMenuSpace = document.querySelector("rkgk-context-menu-space");
|
Loading…
Add table
Add a link
Reference in a new issue