diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2019-07-04 18:20:54 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2019-07-04 18:20:54 -0400 |
commit | d236da11dcd635440eecb897a195df8ade4ca7b0 (patch) | |
tree | 045279b216721fa3479060faa4bf25aedbe542a0 | |
parent | 79f3c8151aa0a52037ae726c12d16a26758ea3d9 (diff) |
added dropping and reordering within Stacking views. needs GUI feedback.
-rw-r--r-- | src/client/util/DragManager.ts | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 58 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 9 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 4 |
4 files changed, 68 insertions, 5 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index d4b1bc8f4..ce1f9d890 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -448,7 +448,7 @@ export namespace DragManager { x: e.x, y: e.y, data: dragData, - mods: e.altKey ? "AltKey" : "" + mods: e.altKey ? "AltKey" : e.ctrlKey ? "CtrlKey" : "" } }) ); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index b10907937..6b4eddec9 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -11,6 +11,8 @@ import { CollectionSchemaPreview } from "./CollectionSchemaView"; import "./CollectionStackingView.scss"; import { CollectionSubView } from "./CollectionSubView"; import { resolve } from "bluebird"; +import { undoBatch } from "../../util/UndoManager"; +import { DragManager } from "../../util/DragManager"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -96,8 +98,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { </div>; }); } + docXfs: any[] = [] @computed get children() { + this.docXfs.length = 0; return this.childDocs.filter(d => !d.isMinimized).map((d, i) => { let aspect = d.nativeHeight ? NumCast(d.nativeWidth) / NumCast(d.nativeHeight) : undefined; let dref = React.createRef<HTMLDivElement>(); @@ -105,6 +109,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { let width = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth; let height = () => aspect ? width() / aspect : d[HeightSym](); let rowSpan = Math.ceil((height() + this.gridGap) / (this._gridSize + this.gridGap)); + this.docXfs.push({ dxf: dxf, width: width, height: height }); return (<div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} @@ -166,13 +171,64 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { }); } } + + @undoBatch + @action + drop = (e: Event, de: DragManager.DropEvent) => { + let targInd = -1; + let where = [de.x, de.y]; + if (de.data instanceof DragManager.DocumentDragData) { + this.docXfs.map((cd, i) => { + let pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap); + let pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height()); + if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) { + targInd = i; + } + }) + } + if (super.drop(e, de)) { + if (targInd !== -1) { + let newDoc = de.data.droppedDocuments[0]; + let docs = this.childDocList; + if (docs) { + let srcInd = docs.indexOf(newDoc); + docs.splice(srcInd, 1); + docs.splice(targInd > srcInd ? targInd - 1 : targInd, 0, newDoc); + } + } + } + return false; + } + @undoBatch + @action + onDrop = (e: React.DragEvent): void => { + let where = [e.clientX, e.clientY]; + let targInd = -1; + this.docXfs.map((cd, i) => { + let pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap); + let pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height()); + if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) { + targInd = i; + } + }) + super.onDrop(e, {}, () => { + if (targInd !== -1) { + let newDoc = this.childDocs[this.childDocs.length - 1]; + let docs = this.childDocList; + if (docs) { + docs.splice(docs.length - 1, 1); + docs.splice(targInd, 0, newDoc); + } + } + }); + } render() { let cols = this.singleColumn ? 1 : Math.max(1, Math.min(this.childDocs.filter(d => !d.isMinimized).length, Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap)))); let templatecols = ""; for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `; return ( - <div className="collectionStackingView" ref={this.createRef} onContextMenu={this.onContextMenu} onWheel={(e: React.WheelEvent) => e.stopPropagation()} > + <div className="collectionStackingView" ref={this.createRef} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onWheel={(e: React.WheelEvent) => e.stopPropagation()} > <div className={`collectionStackingView-masonry${this.singleColumn ? "Single" : "Grid"}`} style={{ padding: this.singleColumn ? `${this.yMargin}px ${this.xMargin}px ${this.yMargin}px ${this.xMargin}px` : `${this.yMargin}px ${this.xMargin}px`, diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 3b3bbdbd9..79c23d71a 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -53,6 +53,11 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) { //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue) return DocListCast((BoolCast(this.props.Document.isTemplate) ? this.extensionDoc : this.props.Document)[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey]); } + get childDocList() { + //TODO tfs: This might not be what we want? + //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue) + return Cast((BoolCast(this.props.Document.isTemplate) ? this.extensionDoc : this.props.Document)[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey], listSpec(Doc)); + } @action protected async setCursorPosition(position: [number, number]) { @@ -145,7 +150,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) { @undoBatch @action - protected onDrop(e: React.DragEvent, options: DocumentOptions): void { + protected onDrop(e: React.DragEvent, options: DocumentOptions, completed?: () => void) { if (e.ctrlKey) { e.stopPropagation(); // bcz: this is a hack to stop propagation when dropping an image on a text document with shift+ctrl return; @@ -255,7 +260,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) { } if (promises.length) { - Promise.all(promises).finally(() => batch.end()); + Promise.all(promises).finally(() => { completed && completed(); batch.end(); }); } else { batch.end(); } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 06bf65f73..dd4e4262d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -73,7 +73,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD if (de.mods === "AltKey" && /*this.dataDoc !== this.props.Document &&*/ drop.data instanceof ImageField) { Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new ImageField(drop.data.url); e.stopPropagation(); - } else { + } else if (de.mods === "CtrlKey") { if (this.extensionDoc !== this.dataDoc) { let layout = StrCast(drop.backgroundLayout); if (layout.indexOf(ImageBox.name) !== -1) { @@ -205,6 +205,8 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD requestImageSize(window.origin + RouteStore.corsProxy + "/" + srcpath) .then((size: any) => { let aspect = size.height / size.width; + let rotation = NumCast(this.dataDoc.rotation) % 180; + if (rotation === 90 || rotation === 270) aspect = 1 / aspect; if (Math.abs(layoutdoc[HeightSym]() / layoutdoc[WidthSym]() - aspect) > 0.01) { setTimeout(action(() => { layoutdoc.height = layoutdoc[WidthSym]() * aspect; |