From b377a01261b6356c8b13b73bece635056e38efe6 Mon Sep 17 00:00:00 2001 From: Alex Vitkov Date: Thu, 25 Mar 2021 10:46:07 +0200 Subject: asdf --- front/dragging.ts | 57 ++++++++++++++++++++++++++++++++++++------------------- front/explorer.ts | 38 +++++++++++++++++++++++++++++++++---- front/window.ts | 9 ++++++++- style.css | 50 ++++++++++++++++++++++++++++++------------------ 4 files changed, 112 insertions(+), 42 deletions(-) diff --git a/front/dragging.ts b/front/dragging.ts index f01e414..b65f1f4 100644 --- a/front/dragging.ts +++ b/front/dragging.ts @@ -1,23 +1,42 @@ -import { FileView } from './explorer'; + +export class Draggable { + el: HTMLElement; + + canDragX: boolean = true; + canDragY: boolean = true; + reparent: boolean = true; + + lockSize: boolean = true; + + onBeforeDragStart: () => void = null; + onAfterDragEnd: () => void = null; + + Draggable(el: HTMLElement) { + this.el = el; + } +} + + + // If we're currently dragging something (a window or a file), this is the DOM object we're dragging // dragging_offset_x and dragging_offset_y are the difference between the objec's top left point and the cursor position // this is then added to the cursor position when the mouse is moved -export var dragging = null; +export var dragging: Draggable = null; export var dragging_offset_x = 0, dragging_offset_y = 0; // If we have pressed down a window's title bar but haven't yet started dragging it, it's the drag candidate // This is needed because we don't yet know whether we want to start dragging the window or click an element in the titlebar // Once the mouse has moved sufficiently far away from dragging_candidate_x or y, we start dragging -export var dragging_candidate: HTMLElement = null; +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 var dragging_fileview: FileView; +// export var dragging_placeholder = null; -export function set_dragging_candidate(e, candidate: HTMLElement) { +export function set_dragging_candidate(e, candidate: Draggable) { dragging_candidate = candidate; dragging_candidate_x = e.clientX; dragging_candidate_y = e.clientY; @@ -26,29 +45,29 @@ export function set_dragging_candidate(e, candidate: HTMLElement) { // 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, obj: HTMLElement, dont_set_width?: boolean) { +export function begin_drag(e, d: Draggable) { set_iframe_enabled(false); - dragging = obj; + dragging = d; dragging_candidate = null; - dragging.classList.add("dragged"); + dragging.el.classList.add("dragged"); - var elemRect = dragging.getBoundingClientRect(); + var elemRect = dragging.el.getBoundingClientRect(); dragging_offset_x = e.clientX - elemRect.left; dragging_offset_y = -e.clientY + elemRect.top; - if (dragging_placeholder) - obj.parentNode.insertBefore(dragging_placeholder, obj); + //if (dragging_placeholder) + // dragging.el.parentNode.insertBefore(dragging_placeholder, dragging.el); - dragging.style.left = (e.clientX - dragging_offset_x) + "px"; - dragging.style.top = (e.clientY + dragging_offset_y) + "px"; + dragging.el.style.left = (e.clientX - dragging_offset_x) + "px"; + dragging.el.style.top = (e.clientY + dragging_offset_y) + "px"; - if (!dont_set_width) { - dragging.style.width = elemRect.width + "px"; - dragging.style.height = elemRect.height + "px"; + if (dragging.lockSize) { + dragging.el.style.width = elemRect.width + "px"; + dragging.el.style.height = elemRect.height + "px"; } - dragging.style.position = "absolute"; - document.body.appendChild(dragging); + dragging.el.style.position = "absolute"; + document.body.appendChild(dragging.el); } export function end_drag(_e) { diff --git a/front/explorer.ts b/front/explorer.ts index 3a488ee..9b35f5d 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, dragging_fileview, begin_drag_fileview, end_drag } from './dragging' +import { dragging, Draggable, end_drag } from './dragging' import { ShareWindow } from './share_window'; import { context } from './contextmenu'; @@ -53,6 +53,36 @@ export class FileView { } } +class FileViewDraggable extends Draggable { + + fileview: FileView; + placeholder: HTMLDivElement; + + FileViewDraggable(fileview: FileView) { + this.fileview = fileview; + + this.onBeforeDragStart = () => { + this.placeholder = document.createElement('div'); + fileview.visuals.parentNode.insertBefore(this.placeholder, fileview.visuals); + // fileview.style.zIndex = 50000; + }; + + 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.remove(); + + fileview.visuals.style.removeProperty("position"); + fileview.visuals.style.removeProperty("width"); + fileview.visuals.style.removeProperty("height"); + fileview.visuals.style.removeProperty("left"); + fileview.visuals.style.removeProperty("top"); + + + } + } +} + // make_window creates an explorer window - the kind that can list directories/open files function make_window(wnd, has_close: boolean): BaseWindow { mk(wnd.h2, 'div', 'path'); @@ -66,7 +96,7 @@ function make_window(wnd, has_close: boolean): BaseWindow { // wnd.foldercontents is where the FileViews will be stored // it also has a subheader (h3) with 'Upload' and 'New FOlder' buttons { - wnd.foldercontents = mk(wnd.visuals, 'div', 'foldercontents'); + wnd.foldercontents = mk(wnd.wc, 'div', 'foldercontents'); var h3 = mk(wnd.foldercontents, 'h3'); var upload_btn = mk(h3, 'button'); @@ -90,7 +120,7 @@ function make_window(wnd, has_close: boolean): BaseWindow { // wnd.filecontentsroot is where the filedata will be stored for open files // it also has a subheader (h3) with Share and Download buttons { - wnd.filecontentsroot = mk(wnd.visuals, 'div', 'filecontentsroot'); + wnd.filecontentsroot = mk(wnd.wc, 'div', 'filecontentsroot'); var h3 = mk(wnd.filecontentsroot, 'h3'); let download_btn = mk(h3, 'button'); @@ -200,7 +230,7 @@ function add_file_visuals(fileview: FileView, wnd: ExplorerWindow) { x_button.innerText = "X"; x_button.onclick = () => { wnd.destroy(); }; - const contents = mk(wnd.visuals, 'div', 'filecontentsroot'); + const contents = mk(wnd.wc, 'div', 'filecontentsroot'); const iframe = mk(contents, 'iframe') as HTMLIFrameElement; iframe.style.flex = '1 0 0'; iframe.src = url; diff --git a/front/window.ts b/front/window.ts index eb81095..b9de2b6 100644 --- a/front/window.ts +++ b/front/window.ts @@ -23,6 +23,9 @@ export class BaseWindow { files: any[]; txt_editor: HTMLElement; // For editable text files, this is the DOM element the user can edit + grid: HTMLElement; + wc: HTMLElement; + constructor(pwd, x, y, w, h) { this.pwd = pwd; // pwd = [ "Folder1", "Folder2" ] means the current directory of that window is /Folder1/Folder2 @@ -91,6 +94,8 @@ function make_window_base(wnd, pwd, x, y, w, h) { windows.push(wnd); wnd.visuals = mk(document.body, 'div', 'window'); + wnd.grid = mk(wnd.visuals, 'div', 'windowgrid'); + wnd.wc = mk(wnd.grid, 'div', 'wc'); wnd.visuals.style.width = w + "px"; wnd.visuals.style.height = h ? (h + "px") : "unset"; @@ -98,7 +103,9 @@ function make_window_base(wnd, pwd, x, y, w, h) { wnd.visuals.style.left = x + "px"; wnd.visuals.style.top = y + "px"; - wnd.h2 = mk(wnd.visuals, 'h2'); + wnd.h2 = mk(wnd.wc, 'h2'); + + mk(wnd.grid, 'div', 'nw-resize'); wnd.visuals.onmousedown = (_e) => { wnd.focus(); diff --git a/style.css b/style.css index 81573bf..f7ec8e2 100644 --- a/style.css +++ b/style.css @@ -166,8 +166,8 @@ form > h2 { } -.window h3 button, -.window > h2 button +.window .wc h3 button, +.window .wc > h2 button { border: none; padding: 0.3rem 1rem; @@ -175,17 +175,17 @@ form > h2 { border-radius: 0; } -.window h3 button:not(.pathentry):hover { +.window .wc h3 button:not(.pathentry):hover { background: white; } -.window h3 .separator { +.window .wc h3 .separator { flex: 0 0 1px; align-self: stretch; background: #bbb; } -.window > h2 > *:first-child { +.window .wc > h2 > *:first-child { border-top-left-radius: 0.5rem; } form p { @@ -277,24 +277,38 @@ input[type=submit]:hover { } .window { - overflow: hidden; box-sizing: border-box; margin: 0rem; padding: 0; box-shadow: 0 0.8rem 1.3rem rgba(0,0,0,0.2); border-radius: var(--window-border-radius); border: 1px solid #b9b9b9; + overflow: hidden; - display: block; position: absolute; - top: 0; - left: 0; - width: 800px; - height: 600px; - +} + +.windowgrid { + display: grid; + grid-template-columns: 10px auto 10px; + grid-template-rows: 10px auto 10px; + height: 100%; +} + +.window .wc { transition: opacity 0.3s; display: flex; flex-direction: column; + + grid-row: 2; + grid-column: 2; +} + +.nw-resize { + background: red; + grid-row: 1; + grid-column: 1; + cursor: nw-resize; } .window.focus { @@ -340,8 +354,8 @@ pre { box-sizing: border-box; } -.window h3, -.window > h2 { +.window .wc h3, +.window .wc > h2 { color: #4d4d4d; background: #f0f0f0; margin: 0; @@ -354,7 +368,7 @@ pre { border-bottom: 1px solid #bbb; } -.window > h2 { +.window .wc > h2 { font-size: 1.3rem; cursor: grab; @@ -363,7 +377,7 @@ pre { -ms-user-select: none; } -.window h3 { +.window .wc h3 { font-size: 1.2rem; } @@ -486,7 +500,7 @@ pre { background: rgba(255,255,255, 0.9); } -.window > h2 .close_button { +.window .wc > h2 .close_button { border-left: 1px solid #ccc; } @@ -510,4 +524,4 @@ iframe { .filename { word-wrap: break-word; word-break: break-word; -} +} \ No newline at end of file -- cgit v1.2.3