feat: UI Overhaul
This commit is contained in:
112
extension/modules/ui/overlays/window_manager.js
Normal file
112
extension/modules/ui/overlays/window_manager.js
Normal file
@@ -0,0 +1,112 @@
|
||||
export const WindowManager = (function () {
|
||||
let zIndexCounter = 9999990;
|
||||
|
||||
function makeDraggable(el, header) {
|
||||
let isDragging = false, offX = 0, offY = 0;
|
||||
|
||||
header.addEventListener('mousedown', (e) => {
|
||||
isDragging = true;
|
||||
offX = e.clientX - el.offsetLeft;
|
||||
offY = e.clientY - el.offsetTop;
|
||||
|
||||
// Bring to front
|
||||
zIndexCounter++;
|
||||
el.style.zIndex = zIndexCounter;
|
||||
});
|
||||
|
||||
window.addEventListener('mousemove', (e) => {
|
||||
if (isDragging) {
|
||||
el.style.left = (e.clientX - offX) + 'px';
|
||||
el.style.top = (e.clientY - offY) + 'px';
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('mouseup', () => isDragging = false);
|
||||
}
|
||||
|
||||
function createWindow(id, title, props = {}) {
|
||||
let win = document.getElementById(id);
|
||||
if (win) {
|
||||
// Just bring to front if exists
|
||||
zIndexCounter++;
|
||||
win.style.zIndex = zIndexCounter;
|
||||
return { win, content: document.getElementById(id + '-content') };
|
||||
}
|
||||
|
||||
const x = props.x || 100;
|
||||
const y = props.y || 100;
|
||||
const w = props.width || 300;
|
||||
const h = props.height || 200;
|
||||
|
||||
win = document.createElement('div');
|
||||
win.id = id;
|
||||
win.style.cssText = `
|
||||
position: fixed;
|
||||
top: ${y}px;
|
||||
left: ${x}px;
|
||||
width: ${w}px;
|
||||
height: ${h}px;
|
||||
background: rgba(10, 10, 20, 0.95);
|
||||
border: 1px solid #444;
|
||||
border-radius: 8px;
|
||||
z-index: ${++zIndexCounter};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.6);
|
||||
font-family: sans-serif;
|
||||
color: #eee;
|
||||
backdrop-filter: blur(5px);
|
||||
resize: both;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.id = id + '-header';
|
||||
header.style.cssText = `
|
||||
padding: 8px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
border-bottom: 1px solid #444;
|
||||
cursor: move;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const titleSpan = document.createElement('span');
|
||||
titleSpan.textContent = title;
|
||||
|
||||
const closeBtn = document.createElement('span');
|
||||
closeBtn.textContent = '✕';
|
||||
closeBtn.style.cssText = 'cursor: pointer; color: #ff5252; font-size: 14px;';
|
||||
closeBtn.onclick = () => win.remove();
|
||||
|
||||
header.appendChild(titleSpan);
|
||||
header.appendChild(closeBtn);
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.id = id + '-content';
|
||||
content.style.cssText = 'flex: 1; overflow-y: auto; padding: 10px;';
|
||||
|
||||
win.appendChild(header);
|
||||
win.appendChild(content);
|
||||
document.body.appendChild(win);
|
||||
|
||||
makeDraggable(win, header);
|
||||
|
||||
// Allow clicking anywhere on window to bring to front
|
||||
win.addEventListener('mousedown', () => {
|
||||
if (win.style.zIndex != zIndexCounter) {
|
||||
zIndexCounter++;
|
||||
win.style.zIndex = zIndexCounter;
|
||||
}
|
||||
});
|
||||
|
||||
return { win, content };
|
||||
}
|
||||
|
||||
return {
|
||||
create: createWindow
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user