export default class DWindow extends EventTarget { static allWindows = []; // açık pencereler static zCounter = 1; // global sayaç static normalizeThreshold = 9999; // yeniden sıfırlama eşiği /** @type {JQuery} */ panel = null; /** @type {JQuery} */ title = null; /** @type {JQuery} */ content = null; /** @type {JQuery} */ headtext = null; constructor() { super(); this.initpanel(); this.enableFocus(); DWindow.allWindows.push(this); this.bringToFront(); requestAnimationFrame(()=>{ this.enableDragging(); this.enableResize(); }) } activeDragging = true; activeResizing = true; initpanel() { this.panel = $(`
`).css({ width: 450, //height: 500, position: "fixed", left: (Math.random() * 300 | 0) + 100, top: (Math.random() * 100 | 0) + 100, boxShadow: "black 0px 0px 20px -10px", borderRadius: "10px", backgroundColor: "#3333335b", backdropFilter: "blur(3px)", border: "solid 1px #a2a2a2", display: "flex", flexDirection: "column", outlineOffset: "-5px", //overflow: "hidden", userSelect: "none", minWidth: "max-content", minHeight: "max-content" }); $("body").append(this.panel); this.title = $(`
`).css({ display: "flex", flex: "0 0 auto", flexDirection: "row", lineHeight: "2em", backgroundColor: "#333333", color: "white", paddingLeft: "10px", cursor: "move", borderTopLeftRadius: "10px", borderTopRightRadius: "10px", }); this.content = $(`
`).css({ flex: "1 1 auto", overflow: "auto", borderBottomRightRadius: "10px", borderBottomLeftRadius: "10px", padding: "20px" }); this.panel.append(this.title, this.content); this.initTitle(); } initTitle() { this.headtext = $("
Başlıksız pencere
"); const divider = $("
"); this.exitbtn = $("
close
"); this.exitbtn.on('click',()=>{ this.dispatchEvent(new Event("close")); }) this.title.append( this.headtext, divider, this.exitbtn ); } enableDragging() { let isDragging = false; let startX, startY, startLeft, startTop; this.title.on("mousedown", (e) => { if(this.activeDragging == false){ return; } let isInput = $(e.target).closest("button, input, select, textarea,.btn"); if (isInput.length) return; e.preventDefault(); isDragging = true; startX = e.pageX; startY = e.pageY; startLeft = parseFloat(this.panel.css("left")); startTop = parseFloat(this.panel.css("top")); $("body").css("user-select", "none"); this.dispatchEvent(new Event("dragging")); this.panel.css("box-shadow","black 0px 0px 40px -20px"); this.panel.css("backdrop-filter","blur(10px)"); }); $(document).on("mousemove", (e) => { if (!isDragging) return; const dx = e.pageX - startX; const dy = e.pageY - startY; this.panel.css({ left: startLeft + dx, top: startTop + dy, }); }); $(document).on("mouseup", () => { if (isDragging) { isDragging = false; this.panel.css("box-shadow","black 0px 0px 20px -10px"); this.panel.css("backdrop-filter","blur(3px)"); $("body").css("user-select", "auto"); this.dispatchEvent(new Event("draggingend")); } }); } enableResize() { const offset = 5; // panelin dışından 5px alan let resizing = false; let resizeDir = ""; let startX, startY, startW, startH, startL, startT; const minW = 200, minH = 150; // overlay divleri oluştur const handles = {}; const names = ["n","s","e","w","ne","nw","se","sw"]; names.forEach(n => { handles[n] = $('
').css({ position: "absolute", zIndex: 1000, background: "transparent", cursor: n + "-resize", transition: "all 0.5s all", outlineOffset: "3px" }).appendTo(this.panel); }); // boyut ve pozisyonlarını ayarla const updateHandles = () => { const w = this.panel.outerWidth(); const h = this.panel.outerHeight(); // kenarlar handles.n.css({ top: -offset, left: 0, width: w, height: offset*2 }); handles.s.css({ bottom: -offset, left: 0, width: w, height: offset*2 }); handles.w.css({ top: 0, left: -offset, width: offset*2, height: h }); handles.e.css({ top: 0, right: -offset, width: offset*2, height: h }); // köşeler handles.nw.css({ top: -offset, left: -offset, width: offset*2, height: offset*2 }); handles.ne.css({ top: -offset, right: -offset, width: offset*2, height: offset*2 }); handles.sw.css({ bottom: -offset, left: -offset, width: offset*2, height: offset*2 }); handles.se.css({ bottom: -offset, right: -offset, width: offset*2, height: offset*2 }); }; updateHandles(); $(window).on("resize", updateHandles); let activeDir = null; // resize eventleri names.forEach(dir => { handles[dir].on("mousedown", (e) => { if(this.activeResizing == false){ return; } activeDir = e.target; e.preventDefault(); e.stopPropagation(); resizing = true; resizeDir = dir; startX = e.pageX; startY = e.pageY; startW = this.panel.outerWidth(); startH = this.panel.outerHeight(); startL = parseFloat(this.panel.css("left")); startT = parseFloat(this.panel.css("top")); this.dispatchEvent(new Event("resizing")); $("body").css("user-select","none"); }); }); $(document).on("mousemove", (e) => { if (!resizing) return; const dx = e.pageX - startX; const dy = e.pageY - startY; let newW = startW; let newH = startH; let newL = startL; let newT = startT; if (resizeDir.includes("e")) newW = Math.max(minW, startW + dx); if (resizeDir.includes("w")) { newW = Math.max(minW, startW - dx); newL = startL + (startW - newW); } if (resizeDir.includes("s")) newH = Math.max(minH, startH + dy); if (resizeDir.includes("n")) { newH = Math.max(minH, startH - dy); newT = startT + (startH - newH); } this.panel.css({ width: newW, height: newH, left: newL, top: newT }); updateHandles(); $(activeDir).css("outline", "solid 2px #00ff00"); }); $(document).on("mouseup", () => { if (resizing) { resizing = false; $("body").css("user-select","auto"); $(activeDir).css("outline", "solid 0px #00ff00"); this.dispatchEvent(new Event("resizingend")); } }); } enableFocus() { this.panel.on("mousedown", () => { this.bringToFront(); }); } bringToFront() { if (DWindow.zCounter > DWindow.normalizeThreshold) { DWindow.normalizeZ(); } DWindow.zCounter++; this.panel.css("z-index", DWindow.zCounter); } showing = true; show(){ this.dispatchEvent(new Event("show")); this.panel.show(); this.showing = true; } hide(){ this.dispatchEvent(new Event("hide")); this.panel.hide(); this.showing = false; } toggle(){ this.showing ? this.hide() : this.show(); } exit(){ this.dispatchEvent(new Event("exit")); this.panel.remove(); } /** @type {DWindow} */ parent = null; /** @param {DWindow} parent */ enableDialog(parent){ this.parent = parent; this.parent.activeDragging = false; this.parent.activeResizing = false; this.parent.panel.css('pointer-events',"none"); this.parent.panel.css('filter',"grayscale(1)"); let [{ left: parentL, top: parentT, width: parentW, height: parentH }] = this.parent.panel[0].getClientRects(); let [{ width: childW, height: childH }] = this.panel[0].getClientRects(); let newLeft = parentL + (parentW - childW) / 2; let newTop = parentT + (parentH - childH) / 2; debugger; newLeft = Math.max(newLeft, 20); newTop = Math.max(newTop, 20); newLeft = Math.min(newLeft, screen.availWidth - 100); newTop = Math.min(newTop, screen.availHeight - 100); Object.assign(this.panel[0].style, { left: `${Math.round(newLeft)}px`, top: `${Math.round(newTop)}px` }); } /** @param {DWindow} parent */ disableDialog(){ this.parent.activeDragging = true; this.parent.activeResizing = true; this.parent.panel.css('pointer-events',"all"); this.parent.panel.css('filter',"initial"); } }