diff options
author | Alex Vitkov <alexvitkov98@gmail.com> | 2021-03-25 11:59:30 +0200 |
---|---|---|
committer | Alex Vitkov <alexvitkov98@gmail.com> | 2021-03-25 11:59:30 +0200 |
commit | dfb48a23e4a7ac455be3a475ebf28027b6d2c148 (patch) | |
tree | 6740cb58ba28695a24fd9c7b014f64f61cd68ead /front | |
parent | b377a01261b6356c8b13b73bece635056e38efe6 (diff) | |
download | fileup-dfb48a23e4a7ac455be3a475ebf28027b6d2c148.tar.gz |
Draggable windows
Diffstat (limited to 'front')
-rw-r--r-- | front/dragging.ts | 74 | ||||
-rw-r--r-- | front/explorer.ts | 23 | ||||
-rw-r--r-- | front/window.ts | 57 |
3 files changed, 88 insertions, 66 deletions
diff --git a/front/dragging.ts b/front/dragging.ts index b65f1f4..bcf6e9f 100644 --- a/front/dragging.ts +++ b/front/dragging.ts @@ -2,16 +2,15 @@ export class Draggable { el: HTMLElement; - canDragX: boolean = true; - canDragY: boolean = true; reparent: boolean = true; lockSize: boolean = true; onBeforeDragStart: () => void = null; onAfterDragEnd: () => void = null; + customMoveHandler: (x: number, y: number) => void = null; - Draggable(el: HTMLElement) { + constructor(el: HTMLElement) { this.el = el; } } @@ -31,11 +30,6 @@ export var dragging_offset_x = 0, dragging_offset_y = 0; export var dragging_candidate: Draggable = null; export var dragging_candidate_x, dragging_candidate_y; -// If we're dragging a fileview, this is set to the fileview class instance itself, because 'dragging' is just a DOM object -// The placeholder is a dummy DIV that we insert in the object's place on the grid to keep things nicely aligned -// export var dragging_fileview: FileView; -// export var dragging_placeholder = null; - export function set_dragging_candidate(e, candidate: Draggable) { dragging_candidate = candidate; dragging_candidate_x = e.clientX; @@ -46,6 +40,8 @@ export function set_dragging_candidate(e, candidate: Draggable) { // Start dragging the 'obj' DOM element // e is a DOM event, this should only get called in response of a DOM event export function begin_drag(e, d: Draggable) { + if (d.onBeforeDragStart) + d.onBeforeDragStart() set_iframe_enabled(false); dragging = d; dragging_candidate = null; @@ -55,42 +51,27 @@ export function begin_drag(e, d: Draggable) { dragging_offset_x = e.clientX - elemRect.left; dragging_offset_y = -e.clientY + elemRect.top; - //if (dragging_placeholder) - // dragging.el.parentNode.insertBefore(dragging_placeholder, dragging.el); - - dragging.el.style.left = (e.clientX - dragging_offset_x) + "px"; - dragging.el.style.top = (e.clientY + dragging_offset_y) + "px"; if (dragging.lockSize) { + dragging.el.style.left = (e.clientX - dragging_offset_x) + "px"; + dragging.el.style.top = (e.clientY + dragging_offset_y) + "px"; dragging.el.style.width = elemRect.width + "px"; dragging.el.style.height = elemRect.height + "px"; + dragging.el.style.position = "absolute"; } - dragging.el.style.position = "absolute"; - document.body.appendChild(dragging.el); + + + if (dragging.reparent) + document.body.appendChild(dragging.el); } export function end_drag(_e) { set_iframe_enabled(true); - // If there's a dragging placeholder remove it and put the dragged node back into its place - if (dragging_placeholder) { - dragging_placeholder.parentNode.insertBefore(dragging, dragging_placeholder); - dragging_placeholder.remove(); - dragging_placeholder = null; - } - - // If we were dragging a FileView, we need to reset some CSS - if (dragging_fileview) { - dragging.style.removeProperty("position"); - dragging.style.removeProperty("width"); - dragging.style.removeProperty("height"); - dragging.style.removeProperty("left"); - dragging.style.removeProperty("top"); - dragging_fileview = null; - } - - dragging.classList.remove("dragged"); + dragging.el.classList.remove("dragged"); + if (dragging.onAfterDragEnd) + dragging.onAfterDragEnd(); dragging = null; } @@ -109,30 +90,21 @@ document.body.onmouseup = (_e) => { document.body.onmousemove = (e) => { if (dragging) { - dragging.style.left = (e.clientX - dragging_offset_x) + "px"; - dragging.style.top = (e.clientY + dragging_offset_y) + "px"; + const x = e.clientX - dragging_offset_x; + const y = e.clientY + dragging_offset_y; + if (dragging.customMoveHandler) { + dragging.customMoveHandler(x, y) + } else { + dragging.el.style.left = x + "px"; + dragging.el.style.top = y + "px"; + } } else if (dragging_candidate) { var d = Math.abs(e.clientX - dragging_candidate_x) + Math.abs(e.clientY - dragging_candidate_y); if (d > 15) - begin_drag(e, dragging_candidate, true); + begin_drag(e, dragging_candidate); } } -// Dragging a fileview is a bit different from dragging a window -// This does some setup work before calling the common begin_drag -export function begin_drag_fileview(e, fileview) { - if (dragging) - end_drag(e); - - // The dragging_placeholder is inserted into its place by the begin_drag function - dragging_placeholder = document.createElement('div'); - dragging_fileview = fileview; - - dragging = fileview.visuals; - dragging.style.zIndex = 50000; - - begin_drag(e, fileview.visuals); -} export function oncontextmenu_hook(e) { if (dragging) { diff --git a/front/explorer.ts b/front/explorer.ts index 9b35f5d..f5104bc 100644 --- a/front/explorer.ts +++ b/front/explorer.ts @@ -1,7 +1,7 @@ import { BaseWindow } from './window' import { mk, path_combine, base64ArrayBuffer } from './util'; import { show_upload_dialog, show_upload_dialog_replace_file } from './upload_form'; -import { dragging, Draggable, end_drag } from './dragging' +import { dragging, Draggable, end_drag, begin_drag } from './dragging' import { ShareWindow } from './share_window'; import { context } from './contextmenu'; @@ -58,7 +58,8 @@ class FileViewDraggable extends Draggable { fileview: FileView; placeholder: HTMLDivElement; - FileViewDraggable(fileview: FileView) { + constructor(fileview: FileView) { + super(fileview.visuals); this.fileview = fileview; this.onBeforeDragStart = () => { @@ -69,7 +70,7 @@ class FileViewDraggable extends Draggable { this.onAfterDragEnd = () => { // If there's a dragging placeholder remove it and put the dragged node back into its place - this.placeholder.parentNode.insertBefore(dragging, dragging_placeholder); + this.placeholder.parentNode.insertBefore(this.el, this.placeholder); this.placeholder.remove(); fileview.visuals.style.removeProperty("position"); @@ -77,8 +78,6 @@ class FileViewDraggable extends Draggable { fileview.visuals.style.removeProperty("height"); fileview.visuals.style.removeProperty("left"); fileview.visuals.style.removeProperty("top"); - - } } } @@ -271,7 +270,7 @@ function add_file_visuals(fileview: FileView, wnd: ExplorerWindow) { e.preventDefault(); return; } - begin_drag_fileview(e, fileview); + begin_drag(e, new FileViewDraggable(fileview)); e.preventDefault(); }; @@ -280,13 +279,13 @@ function add_file_visuals(fileview: FileView, wnd: ExplorerWindow) { if (fileview.is_directory) { if (wnd.get_path() == "/" && fileview.filename == "trash") { // If we've dragged something onto the trashcan, it's trash - move_to_trash(wnd, dragging_fileview.filename); + move_to_trash(wnd, (dragging as FileViewDraggable).fileview.filename); } else if (wnd.get_path() == "/" && fileview.filename == "share") { // move to 'share' is invalid } else { // If we've dragged something onto a directory, move it into that directory - move_file(dragging_fileview.wnd, wnd, path_combine(wnd.get_path(), fileview.filename), dragging_fileview.filename); + move_file((dragging as FileViewDraggable).fileview.wnd, wnd, path_combine(wnd.get_path(), fileview.filename), (dragging as FileViewDraggable).fileview.filename); } } else { // alert(`Dropped ${dst.filename} on ${src.filename}`); @@ -422,8 +421,8 @@ function openfile_dir(wnd) { wnd.foldercontents.style.display = 'flex'; wnd.foldercontents.onmouseup = () => { - if (dragging && dragging_fileview) { - move_file(dragging_fileview.wnd, wnd, wnd.get_path(), dragging_fileview.filename); + if (dragging && dragging instanceof FileViewDraggable) { + move_file((dragging as FileViewDraggable).fileview.wnd, wnd, wnd.get_path(), (dragging as FileViewDraggable).fileview.filename); } } } @@ -557,9 +556,9 @@ function update_path_visuals(wnd) { // We can drop files onto the path, which will omve them to teh folder entry.onmouseup = (e) => { - if (dragging && dragging_fileview) { + if (dragging && dragging instanceof FileViewDraggable) { var new_folder = wnd.get_path(i + 1); - move_file(dragging_fileview.wnd, wnd, new_folder, dragging_fileview.filename); + move_file((dragging as FileViewDraggable).fileview.wnd, wnd, new_folder, (dragging as FileViewDraggable).fileview.filename); end_drag(e); e.preventDefault(); diff --git a/front/window.ts b/front/window.ts index b9de2b6..840f7a2 100644 --- a/front/window.ts +++ b/front/window.ts @@ -14,6 +14,43 @@ import * as drag from './dragging' // We then increment the depth, and the next window we click will go on top of the current one var depth = 20; +export class WindowResizeHandleDraggable extends drag.Draggable { + window: HTMLDivElement; + xDir: number; + yDir: number; + + constructor(window: HTMLDivElement, el: HTMLElement, xDir: number, yDir: number) { + super(el); + this.window = window; + this.reparent = false; + this.lockSize = false; + this.xDir = xDir; + this.yDir = yDir; + + this.customMoveHandler = (x, y) => { + if (this.xDir == -1) { + const oldX = parseInt(this.window.style.left.slice(0, -2)); + const oldWidth = parseInt(this.window.style.width.slice(0, -2)); + this.window.style.left = x + "px"; + this.window.style.width = (oldWidth + (oldX - x)).toString() + "px"; + } + if (this.yDir == -1) { + const oldY = parseInt(this.window.style.top.slice(0, -2)); + const oldHeight = parseInt(this.window.style.height.slice(0, -2)); + this.window.style.top = y + "px"; + this.window.style.height = (oldHeight + (oldY - y)).toString() + "px"; + } + if (this.xDir == 1) { + const oldX = parseInt(this.window.style.left.slice(0, -2)); + this.window.style.width = (x - oldX).toString() + "px"; + } + if (this.yDir == 1) { + const oldY = parseInt(this.window.style.top.slice(0, -2)); + this.window.style.height = (y - oldY).toString() + "px"; + } + } + } +} export class BaseWindow { pwd: string[]; @@ -87,10 +124,16 @@ export function unfocus_window() { } } +function mkdraghandle(wnd, _class, x, y) { + const d = mk(wnd.grid, 'div', _class); + const dd = new WindowResizeHandleDraggable(wnd.visuals as HTMLDivElement, d, x, y); + d.onmousedown = (e) => drag.begin_drag(e, dd); +} + // This creates the parts of a window that are common between all window types // This should only really be called by another function that will then fill up the window -function make_window_base(wnd, pwd, x, y, w, h) { +function make_window_base(wnd: BaseWindow, pwd, x, y, w, h) { windows.push(wnd); wnd.visuals = mk(document.body, 'div', 'window'); @@ -105,7 +148,15 @@ function make_window_base(wnd, pwd, x, y, w, h) { wnd.h2 = mk(wnd.wc, 'h2'); - mk(wnd.grid, 'div', 'nw-resize'); + + mkdraghandle(wnd, 'nw-resize', -1, -1) + mkdraghandle(wnd, 'w-resize', -1, 0); + mkdraghandle(wnd, 'sw-resize', -1, 1); + mkdraghandle(wnd, 's-resize', 0, 1); + mkdraghandle(wnd, 'se-resize', 1, 1); + mkdraghandle(wnd, 'e-resize', 1, 0); + mkdraghandle(wnd, 'ne-resize', 1, -1); + mkdraghandle(wnd, 'n-resize', 0, -1); wnd.visuals.onmousedown = (_e) => { wnd.focus(); @@ -113,7 +164,7 @@ function make_window_base(wnd, pwd, x, y, w, h) { wnd.h2.onmousedown = (e) => { if (!drag.dragging) - drag.set_dragging_candidate(e, wnd.visuals); + drag.set_dragging_candidate(e, new drag.Draggable(wnd.visuals)); }; return wnd; |