/* config: {
title: string,
content: string,
id: string,
width?: number = 400,
height?: number = 400,
minWidth?: number = 200,
minHeight?: number = 200,
posX?: number = null, // automatically centers window based on w/h
posY?: number = null,
postCreation?: () => void
} */
let WINDOWS = {};
let MOUSE_MOVE_PROCESSING = {};
let globalIncrement = 1;
function createWindow(config) {
if (document.getElementById(config.id)) {
WINDOWS[config.id].element.style.zIndex = globalIncrement;
globalIncrement++;
return;
}
// 1 - border
// 10 - padding
// 35 - header
let _windowPaddingX = 1*2 + 10*2;
let _windowPaddingY = 1*2 + 10*2 + 35;
config.width = config.width || 600;
config.height = config.height || 400;
config.minWidth = config.minWidth || 200;
config.minHeight = config.minHeight || 200;
let realWidth = Math.max(config.minWidth, Math.min(config.width, innerWidth - _windowPaddingX - 20));
let realHeight = Math.max(config.minHeight, Math.min(config.height, innerHeight - _windowPaddingY - 20));
let posX = config.posX || Math.round((innerWidth / 2) - ((realWidth + _windowPaddingX) / 2));
let posY = config.posY || Math.round((innerHeight / 2) - ((realHeight + _windowPaddingY) / 2));
let wO = document.createElement("div");
wO.classList.add("window-outer");
let w = document.createElement("div");
w.classList.add("window");
w.style.width = `${realWidth}px`;
w.style.height = `${realHeight}px`;
w.innerHTML = config.content;
let wH = document.createElement("div");
wH.classList.add("window-header");
wH.innerHTML = `
`;
let wC = document.createElement("div");
wC.classList.add("window-container");
wC.style.left = `${posX}px`;
wC.style.top = `${posY}px`;
wC.id = config.id;
wC.style.zIndex = globalIncrement;
wC.style.width = `${realWidth + _windowPaddingX - 2}px`;
wO.append(w)
wC.append(wH, wO);
document.body.append(wC);
WINDOWS[config.id] = {
element: wC,
height: realHeight,
width: realWidth,
posX: posX,
posY: posY,
mouseDown: false,
fullscreen: false,
vars: {}
};
function mouseMoveEvent(x, y) {
WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
wC.style.left = `${WINDOWS[config.id].posX}px`;
wC.style.top = `${WINDOWS[config.id].posY}px`;
}
wC.addEventListener("mousedown", function() {
wC.style.zIndex = globalIncrement;
globalIncrement++;
})
wH.addEventListener("mousedown", function(e) {
if (e.target.dataset.noMove !== undefined) {
return;
}
WINDOWS[config.id].mouseDown = true;
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
MOUSE_MOVE_PROCESSING[config.id] = {
callback: mouseMoveEvent,
mouseUp: true
};
});
wH.querySelector(".close").addEventListener("click", function() {
delete WINDOWS[config.id];
delete MOUSE_MOVE_PROCESSING[config.id];
wC.remove();
});
wH.querySelector(".fullscreen").addEventListener("click", function() {
if (WINDOWS[config.id].fullscreen) {
WINDOWS[config.id].posX = WINDOWS[config.id].vars.oldPosX;
WINDOWS[config.id].posY = WINDOWS[config.id].vars.oldPosY;
WINDOWS[config.id].width = WINDOWS[config.id].vars.oldWidth;
WINDOWS[config.id].height = WINDOWS[config.id].vars.oldHeight;
WINDOWS[config.id].fullscreen = false;
delete WINDOWS[config.id].vars.oldPosX;
delete WINDOWS[config.id].vars.oldPosY;
delete WINDOWS[config.id].vars.oldWidth;
delete WINDOWS[config.id].vars.oldHeight;
wC.style.left = `${WINDOWS[config.id].posX}px`;
wC.style.top = `${WINDOWS[config.id].posY}px`;
wC.style.width = `${WINDOWS[config.id].width + _windowPaddingX - 2}px`;
w.style.width = `${WINDOWS[config.id].width}px`;
w.style.height = `${WINDOWS[config.id].height}px`;
} else {
WINDOWS[config.id].vars.oldPosX = WINDOWS[config.id].posX;
WINDOWS[config.id].vars.oldPosY = WINDOWS[config.id].posY;
WINDOWS[config.id].vars.oldWidth = WINDOWS[config.id].width;
WINDOWS[config.id].vars.oldHeight = WINDOWS[config.id].height;
WINDOWS[config.id].fullscreen = true;
WINDOWS[config.id].posX = 0;
WINDOWS[config.id].posY = 0;
WINDOWS[config.id].width = innerWidth;
WINDOWS[config.id].height = innerHeight;
wC.style.left = "0px";
wC.style.top = "0px";
wC.style.width = `${WINDOWS[config.id].width}px`;
w.style.width = `${WINDOWS[config.id].width - _windowPaddingX}px`;
w.style.height = `${WINDOWS[config.id].height - _windowPaddingY}px`;
}
});
globalIncrement++;
if (typeof config.postCreation == "function") {
config.postCreation();
}
}
window.addEventListener("mousemove", function(e) {
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
MOUSE_MOVE_PROCESSING[key].callback(e.clientX, e.clientY);
}
});
window.addEventListener("mouseup", function() {
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
if (MOUSE_MOVE_PROCESSING[key].mouseUp) {
delete MOUSE_MOVE_PROCESSING[key];
};
}
});
function windowPreset(template) {
let el = document.querySelector(`#window-templates > [data-template-id="${template}"]`);
if (!el) { return; }
let config = {
id: template
};
for (const field of el.querySelectorAll("[data-template-field]")) {
config[field.dataset.templateField] = field.dataset.isNumber === "" ? +field.innerText : field.innerHTML;
}
createWindow(config);
}
function copyButton() {
navigator.clipboard.writeText("");
}