First commit
This commit is contained in:
518
WindowController.js
Normal file
518
WindowController.js
Normal file
@@ -0,0 +1,518 @@
|
||||
|
||||
var orderIndex = 1000;
|
||||
|
||||
export class WindowController {
|
||||
|
||||
win = null;
|
||||
titlebar = null;
|
||||
canvas = null;
|
||||
resizers = null;
|
||||
btnClose = null;
|
||||
btnMaximize = null;
|
||||
|
||||
isSnapped = false;
|
||||
isMaximized = false;
|
||||
isDragging = false;
|
||||
dragType = null;
|
||||
currentResizer = null;
|
||||
|
||||
savedPosition = null;
|
||||
savedBeforeMaximize = null;
|
||||
|
||||
order = orderIndex++;
|
||||
|
||||
startX = 0;
|
||||
startY = 0;
|
||||
startLeft = 100;
|
||||
startTop = 100;
|
||||
startWidth = 500;
|
||||
startHeight = 500;
|
||||
|
||||
width = this.startWidth;
|
||||
|
||||
height = this.startHeight;
|
||||
|
||||
constructor() {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
setElement( element ) {
|
||||
|
||||
this.canvas = element;
|
||||
|
||||
console.log("set element",element);
|
||||
|
||||
}
|
||||
|
||||
create( element ) {
|
||||
|
||||
var windowFrame = document.createElement( "div" );
|
||||
|
||||
windowFrame.id = "win"
|
||||
|
||||
windowFrame.style.width = this.startWidth + "px";
|
||||
|
||||
windowFrame.style.height = this.startHeight + "px";
|
||||
|
||||
|
||||
windowFrame.style.left = this.startLeft + "px";
|
||||
|
||||
windowFrame.style.top = this.startTop + "px";
|
||||
|
||||
|
||||
// Title bar
|
||||
var titleBar = document.createElement( "div" );
|
||||
titleBar.className = "titlebar";
|
||||
titleBar.textContent = "Source Code Graph";
|
||||
|
||||
var buttons = document.createElement( "div" );
|
||||
buttons.className = "buttons";
|
||||
|
||||
var btnMaximize = document.createElement( "button" );
|
||||
btnMaximize.id = "btnMaximize";
|
||||
btnMaximize.title = "Maximize";
|
||||
btnMaximize.textContent = "m";
|
||||
|
||||
var btnClose = document.createElement( "button" );
|
||||
btnClose.id = "btnClose";
|
||||
btnClose.title = "Close";
|
||||
btnClose.textContent = "×";
|
||||
|
||||
buttons.appendChild( btnMaximize );
|
||||
buttons.appendChild( btnClose );
|
||||
titleBar.appendChild( buttons );
|
||||
windowFrame.appendChild( titleBar );
|
||||
|
||||
// Content
|
||||
var content = document.createElement( "div" );
|
||||
content.className = "content";
|
||||
|
||||
|
||||
console.log(this.canvas);
|
||||
|
||||
content.appendChild( this.canvas );
|
||||
|
||||
|
||||
|
||||
windowFrame.appendChild( content );
|
||||
|
||||
// Resizers
|
||||
var resizerClasses = [
|
||||
"top-left", "top", "top-right", "right",
|
||||
"bottom-right", "bottom", "bottom-left", "left"
|
||||
];
|
||||
|
||||
this.resizers = new Array();
|
||||
|
||||
for (var i = 0; i < resizerClasses.length; i++) {
|
||||
|
||||
var resizer = document.createElement( "div" );
|
||||
|
||||
resizer.className = "resizer " + resizerClasses[i];
|
||||
|
||||
windowFrame.appendChild( resizer );
|
||||
|
||||
this.resizers.push(resizer)
|
||||
|
||||
}
|
||||
|
||||
this.win = windowFrame;
|
||||
this.titlebar = titleBar;
|
||||
|
||||
this.btnClose = btnClose;
|
||||
this.btnMaximize = btnMaximize;
|
||||
|
||||
this.titlebar.addEventListener("mousedown", this.onTitlebarMouseDown.bind(this));
|
||||
|
||||
this.resizers.forEach(this.bindResizer.bind(this));
|
||||
|
||||
this.btnClose.addEventListener("click", this.onCloseClick.bind(this));
|
||||
this.btnMaximize.addEventListener("click", this.onMaximizeClick.bind(this));
|
||||
|
||||
document.body.appendChild( windowFrame );
|
||||
|
||||
this.win.addEventListener("mousedown", this.reOrder.bind( this ) );
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
this.create();
|
||||
|
||||
}
|
||||
|
||||
setGraphExplorer( graphExplorer ) {
|
||||
|
||||
this.graphExplorer = graphExplorer;
|
||||
|
||||
}
|
||||
|
||||
saveWindowState() {
|
||||
|
||||
this.savedPosition = {
|
||||
left: this.win.offsetLeft,
|
||||
top: this.win.offsetTop,
|
||||
width: this.win.offsetWidth,
|
||||
height: this.win.offsetHeight
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
hide() {
|
||||
|
||||
this.win.style.display = "none"
|
||||
|
||||
}
|
||||
|
||||
show() {
|
||||
|
||||
this.win.style.display = "flex"
|
||||
|
||||
}
|
||||
|
||||
restoreWindowState() {
|
||||
|
||||
if (!this.savedPosition) return;
|
||||
|
||||
this.win.style.left = this.savedPosition.left + "px";
|
||||
this.win.style.top = this.savedPosition.top + "px";
|
||||
this.win.style.width = this.savedPosition.width + "px";
|
||||
this.win.style.height = this.savedPosition.height + "px";
|
||||
|
||||
this.savedPosition = null;
|
||||
this.isSnapped = false;
|
||||
|
||||
}
|
||||
|
||||
resizeCanvas() {
|
||||
|
||||
const style = getComputedStyle(this.win);
|
||||
const width = parseInt(style.width);
|
||||
const height = parseInt(style.height);
|
||||
|
||||
//this.canvas.width = width;
|
||||
//this.canvas.height = height;
|
||||
//this.canvas.style.width = width + "px";
|
||||
//this.canvas.style.height = height + "px";
|
||||
|
||||
//console.log(this.graphExplorer);
|
||||
|
||||
if(this.graphExplorer)
|
||||
this.graphExplorer.onResize( width, height );
|
||||
//this.draw();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
snapWindow(mouseX, mouseY) {
|
||||
|
||||
if (this.isMaximized) return;
|
||||
|
||||
const snapMargin = 30;
|
||||
const vw = window.innerWidth;
|
||||
const vh = window.innerHeight;
|
||||
|
||||
const nearLeft = mouseX <= snapMargin;
|
||||
const nearRight = mouseX >= vw - snapMargin;
|
||||
const nearTop = mouseY <= snapMargin;
|
||||
const nearBottom = mouseY >= vh - snapMargin;
|
||||
|
||||
if (!this.isSnapped && (nearLeft || nearRight || nearTop || nearBottom)) {
|
||||
|
||||
this.saveWindowState();
|
||||
this.isSnapped = true;
|
||||
|
||||
} else if (!nearLeft && !nearRight && !nearTop && !nearBottom && this.isSnapped) {
|
||||
|
||||
this.restoreWindowState();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!this.isSnapped) return;
|
||||
|
||||
if (nearTop && nearLeft) {
|
||||
|
||||
this.setWindowRect(0, 0, vw / 2, vh / 2);
|
||||
|
||||
} else if (nearTop && nearRight) {
|
||||
|
||||
this.setWindowRect(vw / 2, 0, vw / 2, vh / 2);
|
||||
|
||||
} else if (nearBottom && nearLeft) {
|
||||
|
||||
this.setWindowRect(0, vh / 2, vw / 2, vh / 2);
|
||||
|
||||
} else if (nearBottom && nearRight) {
|
||||
|
||||
this.setWindowRect(vw / 2, vh / 2, vw / 2, vh / 2);
|
||||
|
||||
} else if (nearTop) {
|
||||
|
||||
this.setWindowRect(0, 0, vw, vh / 2);
|
||||
|
||||
} else if (nearBottom) {
|
||||
|
||||
this.setWindowRect(0, vh / 2, vw, vh / 2);
|
||||
|
||||
} else if (nearLeft) {
|
||||
|
||||
this.setWindowRect(0, 0, vw / 2, vh);
|
||||
|
||||
} else if (nearRight) {
|
||||
|
||||
this.setWindowRect(vw / 2, 0, vw / 2, vh);
|
||||
|
||||
}
|
||||
|
||||
this.resizeCanvas();
|
||||
|
||||
}
|
||||
|
||||
setWindowRect(left, top, width, height) {
|
||||
|
||||
this.win.style.left = Math.floor(left) + "px";
|
||||
this.win.style.top = Math.floor(top) + "px";
|
||||
this.win.style.width = Math.floor(width) + "px";
|
||||
this.win.style.height = Math.floor(height) + "px";
|
||||
|
||||
}
|
||||
|
||||
onTitlebarMouseDown(event) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.dragType = "move";
|
||||
|
||||
const offsetX = event.clientX - this.win.offsetLeft;
|
||||
const offsetY = event.clientY - this.win.offsetTop;
|
||||
|
||||
if (this.isSnapped) {
|
||||
|
||||
this.restoreWindowState();
|
||||
|
||||
this.startX = event.clientX;
|
||||
this.startY = event.clientY;
|
||||
this.startLeft = event.clientX - 100;
|
||||
this.startTop = event.clientY - offsetY;
|
||||
|
||||
this.win.style.left = this.startLeft + "px";
|
||||
this.win.style.top = this.startTop + "px";
|
||||
|
||||
} else {
|
||||
|
||||
this.startX = event.clientX;
|
||||
this.startY = event.clientY;
|
||||
this.startLeft = this.win.offsetLeft;
|
||||
this.startTop = this.win.offsetTop;
|
||||
|
||||
}
|
||||
|
||||
this.isDragging = true;
|
||||
|
||||
document.addEventListener("mousemove", this.onDragMove);
|
||||
document.addEventListener("mouseup", this.onDragEnd);
|
||||
|
||||
}
|
||||
|
||||
onDragMove = (event) => {
|
||||
|
||||
|
||||
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (!this.isDragging) return;
|
||||
|
||||
const dx = event.clientX - this.startX;
|
||||
const dy = event.clientY - this.startY;
|
||||
|
||||
if (this.dragType === "move") {
|
||||
|
||||
let newLeft = this.startLeft + dx;
|
||||
let newTop = this.startTop + dy;
|
||||
|
||||
newLeft = Math.max(0, Math.min(window.innerWidth - this.win.offsetWidth, newLeft));
|
||||
newTop = Math.max(0, Math.min(window.innerHeight - this.win.offsetHeight, newTop));
|
||||
|
||||
this.win.style.left = newLeft + "px";
|
||||
this.win.style.top = newTop + "px";
|
||||
|
||||
this.snapWindow(event.clientX, event.clientY);
|
||||
|
||||
} else if (this.dragType === "resize") {
|
||||
|
||||
let newWidth = this.startWidth;
|
||||
let newHeight = this.startHeight;
|
||||
let newLeft = this.startLeft;
|
||||
let newTop = this.startTop;
|
||||
|
||||
switch (this.currentResizer) {
|
||||
case "top":
|
||||
newHeight = this.startHeight - dy;
|
||||
newTop = this.startTop + dy;
|
||||
break;
|
||||
case "bottom":
|
||||
newHeight = this.startHeight + dy;
|
||||
break;
|
||||
case "left":
|
||||
newWidth = this.startWidth - dx;
|
||||
newLeft = this.startLeft + dx;
|
||||
break;
|
||||
case "right":
|
||||
newWidth = this.startWidth + dx;
|
||||
break;
|
||||
case "top-left":
|
||||
newWidth = this.startWidth - dx;
|
||||
newLeft = this.startLeft + dx;
|
||||
newHeight = this.startHeight - dy;
|
||||
newTop = this.startTop + dy;
|
||||
break;
|
||||
case "top-right":
|
||||
newWidth = this.startWidth + dx;
|
||||
newHeight = this.startHeight - dy;
|
||||
newTop = this.startTop + dy;
|
||||
break;
|
||||
case "bottom-left":
|
||||
newWidth = this.startWidth - dx;
|
||||
newLeft = this.startLeft + dx;
|
||||
newHeight = this.startHeight + dy;
|
||||
break;
|
||||
case "bottom-right":
|
||||
newWidth = this.startWidth + dx;
|
||||
newHeight = this.startHeight + dy;
|
||||
break;
|
||||
}
|
||||
|
||||
if (newWidth > 100) {
|
||||
this.win.style.width = newWidth + "px";
|
||||
this.win.style.left = newLeft + "px";
|
||||
}
|
||||
|
||||
if (newHeight > 100) {
|
||||
this.win.style.height = newHeight + "px";
|
||||
this.win.style.top = newTop + "px";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.resizeCanvas();
|
||||
|
||||
};
|
||||
|
||||
onDragEnd = () => {
|
||||
|
||||
this.isDragging = false;
|
||||
this.dragType = null;
|
||||
this.currentResizer = null;
|
||||
|
||||
document.removeEventListener("mousemove", this.onDragMove);
|
||||
document.removeEventListener("mouseup", this.onDragEnd);
|
||||
|
||||
};
|
||||
|
||||
reOrder() {
|
||||
|
||||
orderIndex++;
|
||||
|
||||
this.win.style['z-index'] = orderIndex;
|
||||
|
||||
|
||||
console.log("this.win.style['z-index']", this.win.style['z-index']);
|
||||
}
|
||||
|
||||
onResizerMouseDown(event) {
|
||||
|
||||
|
||||
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.startX = event.clientX;
|
||||
this.startY = event.clientY;
|
||||
this.startLeft = this.win.offsetLeft;
|
||||
this.startTop = this.win.offsetTop;
|
||||
this.startWidth = this.win.offsetWidth;
|
||||
this.startHeight = this.win.offsetHeight;
|
||||
|
||||
this.isDragging = true;
|
||||
this.dragType = "resize";
|
||||
this.currentResizer = event.target.classList[1];
|
||||
|
||||
document.addEventListener("mousemove", this.onDragMove);
|
||||
document.addEventListener("mouseup", this.onDragEnd);
|
||||
|
||||
}
|
||||
|
||||
bindResizer(resizerElement) {
|
||||
|
||||
resizerElement.addEventListener("mousedown", this.onResizerMouseDown.bind(this));
|
||||
|
||||
}
|
||||
|
||||
maximizeWindow() {
|
||||
|
||||
if (this.isMaximized) return;
|
||||
|
||||
this.savedBeforeMaximize = {
|
||||
left: this.win.offsetLeft,
|
||||
top: this.win.offsetTop,
|
||||
width: this.win.offsetWidth,
|
||||
height: this.win.offsetHeight
|
||||
};
|
||||
|
||||
this.setWindowRect(0, 0, window.innerWidth, window.innerHeight);
|
||||
|
||||
this.resizeCanvas();
|
||||
|
||||
this.isMaximized = true;
|
||||
this.isSnapped = false;
|
||||
this.savedPosition = null;
|
||||
|
||||
}
|
||||
|
||||
restoreFromMaximize() {
|
||||
|
||||
if (!this.isMaximized || !this.savedBeforeMaximize) return;
|
||||
|
||||
this.setWindowRect(
|
||||
this.savedBeforeMaximize.left,
|
||||
this.savedBeforeMaximize.top,
|
||||
this.savedBeforeMaximize.width,
|
||||
this.savedBeforeMaximize.height
|
||||
);
|
||||
|
||||
this.resizeCanvas();
|
||||
|
||||
this.isMaximized = false;
|
||||
this.savedBeforeMaximize = null;
|
||||
|
||||
}
|
||||
|
||||
onMaximizeClick() {
|
||||
|
||||
|
||||
|
||||
if (this.isMaximized) {
|
||||
|
||||
this.restoreFromMaximize();
|
||||
|
||||
} else {
|
||||
|
||||
this.maximizeWindow();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onCloseClick() {
|
||||
|
||||
this.win.style.display = "none";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user