diff options
| author | Bob Zeleznik <zzzman@gmail.com> | 2019-04-14 21:44:36 -0400 |
|---|---|---|
| committer | Bob Zeleznik <zzzman@gmail.com> | 2019-04-14 21:44:36 -0400 |
| commit | a5ae4d9867ed98e0e3ae52dee47596c62e2f74f7 (patch) | |
| tree | 46bd0ab317c5a61892071071a5ab6889a1a97911 /src/client/views/collections/collectionFreeForm | |
| parent | 7b7f1fb2865522da414314afbdb09847e7a9409c (diff) | |
| parent | c787b0eac374b4dabf6ede7ee40e77a28815d5c8 (diff) | |
Merge branch 'master' into interaction_changes
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
4 files changed, 97 insertions, 68 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 647c83d4d..2f684a54e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -1,7 +1,6 @@ -import { computed, reaction, trace, IReactionDisposer } from "mobx"; +import { computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../../fields/Document"; -import { FieldWaiting } from "../../../../fields/Field"; import { KeyStore } from "../../../../fields/KeyStore"; import { ListField } from "../../../../fields/ListField"; import { Utils } from "../../../../Utils"; @@ -85,19 +84,17 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP let targetViews = this.documentAnchors(connection.b); let possiblePairs: { a: Document, b: Document, }[] = []; srcViews.map(sv => targetViews.map(tv => possiblePairs.push({ a: sv.props.Document, b: tv.props.Document }))); - possiblePairs.map(possiblePair => { - if (!drawnPairs.reduce((found, drawnPair) => { + possiblePairs.map(possiblePair => + drawnPairs.reduce((found, drawnPair) => { let match = (possiblePair.a === drawnPair.a && possiblePair.b === drawnPair.b); - if (match) { - if (!drawnPair.l.reduce((found, link) => found || link.Id === connection.l.Id, false)) { - drawnPair.l.push(connection.l); - } + if (match && !drawnPair.l.reduce((found, link) => found || link.Id === connection.l.Id, false)) { + drawnPair.l.push(connection.l); } return match || found; - }, false)) { - drawnPairs.push({ a: possiblePair.a, b: possiblePair.b, l: [connection.l] }); - } - }); + }, false) + || + drawnPairs.push({ a: possiblePair.a, b: possiblePair.b, l: [connection.l] }) + ); return drawnPairs; }, [] as { a: Document, b: Document, l: Document[] }[]); return connections.map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l} />); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index e19dc98fa..cb4e8fb2e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,10 +1,9 @@ -import { action, computed, observable, runInAction } from "mobx"; +import { action, computed, observable, runInAction, untracked } from "mobx"; import { observer } from "mobx-react"; import Measure from "react-measure"; import { Document } from "../../../../fields/Document"; import { FieldWaiting } from "../../../../fields/Field"; import { KeyStore } from "../../../../fields/KeyStore"; -import { NumberField } from "../../../../fields/NumberField"; import { TextField } from "../../../../fields/TextField"; import { emptyFunction, returnFalse } from "../../../../Utils"; import { DocumentManager } from "../../../util/DocumentManager"; @@ -18,13 +17,14 @@ import { Main } from "../../Main"; import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentContentsView } from "../../nodes/DocumentContentsView"; import { DocumentViewProps } from "../../nodes/DocumentView"; -import { CollectionSubView } from "../CollectionSubView"; +import { CollectionSubView, SubCollectionViewProps } from "../CollectionSubView"; import { CollectionFreeFormLinksView } from "./CollectionFreeFormLinksView"; import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors"; import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); +import { MainOverlayTextBox } from "../../MainOverlayTextBox"; @observer export class CollectionFreeFormView extends CollectionSubView { @@ -38,19 +38,16 @@ export class CollectionFreeFormView extends CollectionSubView { } public addDocument = (newBox: Document, allowDuplicates: boolean) => { - let added = this.props.addDocument(newBox, false); - this.bringToFront(newBox); - return added; + if (this.isAnnotationOverlay) { + newBox.SetNumber(KeyStore.Zoom, this.props.Document.GetNumber(KeyStore.Scale, 1)); + } + return this.props.addDocument(this.bringToFront(newBox), false); } public selectDocuments = (docs: Document[]) => { SelectionManager.DeselectAll; - docs.map(doc => { - const dv = DocumentManager.Instance.getDocumentView(doc); - if (dv) { - SelectionManager.SelectDoc(dv, true); - } - }); + docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).filter(dv => dv).map(dv => + SelectionManager.SelectDoc(dv!, true)); } public getActiveDocuments = () => { @@ -84,41 +81,28 @@ export class CollectionFreeFormView extends CollectionSubView { @undoBatch @action drop = (e: Event, de: DragManager.DropEvent) => { - if (super.drop(e, de)) { - if (de.data instanceof DragManager.DocumentDragData) { - let droppedDocs = de.data.droppedDocuments; - let xoff = de.data.xOffset as number || 0; - let yoff = de.data.yOffset as number || 0; - if (droppedDocs.length) { - let screenX = de.x - xoff; - let screenY = de.y - yoff; - const [x, y] = this.getTransform().transformPoint(screenX, screenY); - let dragDoc = droppedDocs[0]; - let dragX = dragDoc.GetNumber(KeyStore.X, 0); - let dragY = dragDoc.GetNumber(KeyStore.Y, 0); - droppedDocs.map(async d => { - let docX = d.GetNumber(KeyStore.X, 0); - let docY = d.GetNumber(KeyStore.Y, 0); - d.SetNumber(KeyStore.X, x + (docX - dragX)); - d.SetNumber(KeyStore.Y, y + (docY - dragY)); - let docW = await d.GetTAsync(KeyStore.Width, NumberField); - let docH = await d.GetTAsync(KeyStore.Height, NumberField); - if (!docW) { - d.SetNumber(KeyStore.Width, 300); - } - if (!docH) { - d.SetNumber(KeyStore.Height, 300); - } - this.bringToFront(d); - }); - } + if (super.drop(e, de) && de.data instanceof DragManager.DocumentDragData) { + const [x, y] = this.getTransform().transformPoint(de.x - de.data.xOffset, de.y - de.data.yOffset); + if (de.data.droppedDocuments.length) { + let dropX = de.data.droppedDocuments[0].GetNumber(KeyStore.X, 0); + let dropY = de.data.droppedDocuments[0].GetNumber(KeyStore.Y, 0); + de.data.droppedDocuments.map(d => { + d.SetNumber(KeyStore.X, x + (d.GetNumber(KeyStore.X, 0) - dropX)); + d.SetNumber(KeyStore.Y, y + (d.GetNumber(KeyStore.Y, 0) - dropY)); + if (!d.GetNumber(KeyStore.Width, 0)) { + d.SetNumber(KeyStore.Width, 300); + } + if (!d.GetNumber(KeyStore.Height, 0)) { + d.SetNumber(KeyStore.Height, 300); + } + this.bringToFront(d); + }); } return true; } return false; } - @action cleanupInteractions = () => { document.removeEventListener("pointermove", this.onPointerMove); @@ -150,7 +134,28 @@ export class CollectionFreeFormView extends CollectionSubView { if ((!this.isAnnotationOverlay || this.zoomScaling !== 1) && !e.shiftKey) { let x = this.props.Document.GetNumber(KeyStore.PanX, 0); let y = this.props.Document.GetNumber(KeyStore.PanY, 0); + let docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); + if (!this.isAnnotationOverlay) { + let minx = docs.length ? docs[0].GetNumber(KeyStore.X, 0) : 0; + let maxx = docs.length ? docs[0].GetNumber(KeyStore.Width, 0) + minx : minx; + let miny = docs.length ? docs[0].GetNumber(KeyStore.Y, 0) : 0; + let maxy = docs.length ? docs[0].GetNumber(KeyStore.Height, 0) + miny : miny; + let ranges = docs.filter(doc => doc).reduce((range, doc) => { + let x = doc.GetNumber(KeyStore.X, 0); + let xe = x + doc.GetNumber(KeyStore.Width, 0); + let y = doc.GetNumber(KeyStore.Y, 0); + let ye = y + doc.GetNumber(KeyStore.Height, 0); + return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]], + [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]]; + }, [[minx, maxx], [miny, maxy]]); + let panelwidth = this._pwidth / this.scale / 2; + let panelheight = this._pheight / this.scale / 2; + if (x - dx < ranges[0][0] - panelwidth) x = ranges[0][1] + panelwidth + dx; + if (x - dx > ranges[0][1] + panelwidth) x = ranges[0][0] - panelwidth + dx; + if (y - dy < ranges[1][0] - panelheight) y = ranges[1][1] + panelheight + dy; + if (y - dy > ranges[1][1] + panelheight) y = ranges[1][0] - panelheight + dy; + } this.SetPan(x - dx, y - dy); this._lastX = e.pageX; this._lastY = e.pageY; @@ -162,7 +167,9 @@ export class CollectionFreeFormView extends CollectionSubView { @action onPointerWheel = (e: React.WheelEvent): void => { - this.props.select(false); + // if (!this.props.active()) { + // return; + // } e.stopPropagation(); let coefficient = 1000; @@ -192,12 +199,14 @@ export class CollectionFreeFormView extends CollectionSubView { this.props.Document.SetNumber(KeyStore.Scale, localTransform.Scale); this.SetPan(-localTransform.TranslateX / localTransform.Scale, -localTransform.TranslateY / localTransform.Scale); + e.stopPropagation(); + e.preventDefault(); } } @action private SetPan(panX: number, panY: number) { - Main.Instance.SetTextDoc(); + MainOverlayTextBox.Instance.SetTextDoc(); var x1 = this.getLocalTransform().inverse().Scale; const newPanX = Math.min((1 - 1 / x1) * this.nativeWidth, Math.max(0, panX)); const newPanY = Math.min((1 - 1 / x1) * this.nativeHeight, Math.max(0, panY)); @@ -227,9 +236,9 @@ export class CollectionFreeFormView extends CollectionSubView { return -1; } return doc1.GetNumber(KeyStore.ZIndex, 0) - doc2.GetNumber(KeyStore.ZIndex, 0); - }).map((doc, index) => { - doc.SetNumber(KeyStore.ZIndex, index + 1); - }); + }).map((doc, index) => + doc.SetNumber(KeyStore.ZIndex, index + 1)); + return doc; } @computed get backgroundLayout(): string | undefined { @@ -252,9 +261,10 @@ export class CollectionFreeFormView extends CollectionSubView { this.props.focus(this.props.Document); } - getDocumentViewProps(document: Document): DocumentViewProps { + getDocumentViewProps(document: Document, opacity: number): DocumentViewProps { return { Document: document, + opacity: opacity, addDocument: this.props.addDocument, removeDocument: this.props.removeDocument, moveDocument: this.props.moveDocument, @@ -264,7 +274,7 @@ export class CollectionFreeFormView extends CollectionSubView { PanelWidth: document.Width, PanelHeight: document.Height, ContentScaling: this.noScaling, - ContainingCollectionView: undefined, + ContainingCollectionView: this.props.CollectionView, focus: this.focusDocument, parentActive: this.props.active, onActiveChanged: this.props.active, @@ -274,25 +284,34 @@ export class CollectionFreeFormView extends CollectionSubView { @computed get views() { var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1); - return this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => { + let docviews = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => { var page = doc.GetNumber(KeyStore.Page, -1); - if (page === curPage || page === -1) { - prev.push(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc)} />); + var zoom = doc.GetNumber(KeyStore.Zoom, 1); + var dv = DocumentManager.Instance.getDocumentView(doc); + let opacity = this.isAnnotationOverlay && (!dv || !SelectionManager.IsSelected(dv)) ? 1 - Math.abs(zoom - this.scale) : 1; + if ((page === curPage || page === -1)) { + prev.push(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc, opacity)} />); } return prev; }, [] as JSX.Element[]); + + setTimeout(() => { // bcz: surely there must be a better way .... + this._selectOnLoaded = ""; + }, 600); + + return docviews; } @computed get backgroundView() { return !this.backgroundLayout ? (null) : - (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)} + (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document, 1)} layoutKey={KeyStore.BackgroundLayout} isTopMost={this.props.isTopMost} isSelected={returnFalse} select={emptyFunction} />); } @computed get overlayView() { return !this.overlayLayout ? (null) : - (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)} + (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document, 1)} layoutKey={KeyStore.OverlayLayout} isTopMost={this.props.isTopMost} isSelected={returnFalse} select={emptyFunction} />); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.scss b/src/client/views/collections/collectionFreeForm/MarqueeView.scss index e5ffcec76..ae0a9fd48 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.scss +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.scss @@ -13,4 +13,14 @@ border-width: 1px; border-color: black; pointer-events: none; + .marquee-legend { + bottom:-18px; + left:0; + position: absolute; + font-size: 9; + white-space:nowrap; + } + .marquee-legend::after { + content: "Press: C (collection), or Delete" + } }
\ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index a4722a6f8..dbab790d4 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -209,10 +209,11 @@ export class MarqueeView extends React.Component<MarqueeViewProps> let selRect = this.Bounds; let selection: Document[] = []; this.props.activeDocuments().map(doc => { + var z = doc.GetNumber(KeyStore.Zoom, 1); var x = doc.GetNumber(KeyStore.X, 0); var y = doc.GetNumber(KeyStore.Y, 0); - var w = doc.GetNumber(KeyStore.Width, 0); - var h = doc.GetNumber(KeyStore.Height, 0); + var w = doc.GetNumber(KeyStore.Width, 0) / z; + var h = doc.GetNumber(KeyStore.Height, 0) / z; if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) { selection.push(doc); } @@ -224,7 +225,9 @@ export class MarqueeView extends React.Component<MarqueeViewProps> get marqueeDiv() { let p = this.props.getContainerTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY); let v = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY); - return <div className="marquee" style={{ transform: `translate(${p[0]}px, ${p[1]}px)`, width: `${Math.abs(v[0])}`, height: `${Math.abs(v[1])}` }} />; + return <div className="marquee" style={{ transform: `translate(${p[0]}px, ${p[1]}px)`, width: `${Math.abs(v[0])}`, height: `${Math.abs(v[1])}` }} > + <span className="marquee-legend" /> + </div>; } render() { |
