aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-12-10 23:11:46 -0500
committerbobzel <zzzman@gmail.com>2020-12-10 23:11:46 -0500
commitf9f7e0aac784d3b32c5adab04d8ec5d7807b0390 (patch)
tree6673b0d5deb7784a54245b1bc16027227d3b4488 /src
parent784d1bfccf65437942d4b7d373d5f1295eda8c87 (diff)
a little refactoring in CollecftionFreeFormView
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx95
1 files changed, 35 insertions, 60 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1b6cfbd21..75411b3c5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,7 +1,7 @@
import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from "../../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas";
import { Id } from "../../../../fields/FieldSymbols";
import { InkData, InkField, InkTool } from "../../../../fields/InkField";
@@ -80,6 +80,8 @@ export type collectionFreeformViewProps = {
@observer
export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, Partial<collectionFreeformViewProps>>(PanZoomDocument) {
+ public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive
+
private _lastX: number = 0;
private _lastY: number = 0;
private _downX: number = 0;
@@ -94,18 +96,22 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
private _layoutPoolData = new ObservableMap<string, PoolData>();
private _layoutSizeData = new ObservableMap<string, { width?: number, height?: number }>();
private _cachedPool: Map<string, PoolData> = new Map();
+ private _lastTap = 0;
+ private _nudgeTime = 0;
+ private _thumbIdentifier?: number;
+
+ @observable private _hLines: number[] | undefined;
+ @observable private _vLines: number[] | undefined;
@observable private _pullCoords: number[] = [0, 0];
@observable private _pullDirection: string = "";
+ @observable private _showAnimTimeline = false;
- public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive
@observable.shallow _layoutElements: ViewDefResult[] = []; // shallow because some layout items (eg pivot labels) are just generated 'divs' and can't be frozen as observables
@observable _clusterSets: (Doc[])[] = [];
@observable _timelineRef = React.createRef<Timeline>();
-
@observable _marqueeRef = React.createRef<HTMLDivElement>();
- @observable canPanX: boolean = true;
- @observable canPanY: boolean = true;
+ @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); }
@computed get fitToContentScaling() { return this.fitToContent ? NumCast(this.layoutDoc.fitToContentScaling, 1) : 1; }
@computed get fitToContent() { return (this.props.fitToBox || this.Document._fitToBox) && !this.isAnnotationOverlay; }
@computed get parentScaling() { return this.props.ContentScaling && this.fitToContent ? this.props.ContentScaling() : 1; }
@@ -154,6 +160,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newBox);
}
+
addDocument = action((newBox: Doc | Doc[]) => {
let retVal = false;
if (newBox instanceof Doc) {
@@ -303,6 +310,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return cluster;
}, -1);
}
+
tryDragCluster(e: PointerEvent | TouchEvent, cluster: number) {
if (cluster !== -1) {
const ptsParent = e instanceof PointerEvent ? e : e.targetTouches.item(0);
@@ -415,7 +423,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return clusterColor;
}
-
@action
onPointerDown = (e: React.PointerEvent): void => {
if (e.nativeEvent.cancelBubble || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) {
@@ -595,8 +602,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}
- _lastTap = 0;
-
@action
onPointerUp = (e: PointerEvent): void => {
if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) return;
@@ -768,7 +773,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}
-
this.removeMoveListeners();
this.addMoveListeners();
this.removeEndListeners();
@@ -796,7 +800,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.removeEndListeners();
}
-
@action
zoom = (pointX: number, pointY: number, deltaY: number): void => {
let deltaScale = deltaY > 0 ? (1 / 1.05) : 1.05;
@@ -981,7 +984,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height)));
}
- @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); }
onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
// @ts-ignore
@@ -1047,6 +1049,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
return this.props.addDocTab(doc, where);
});
+
getCalculatedPositions(params: { pair: { layout: Doc, data?: Doc }, index: number, collection: Doc, docs: Doc[], state: any }): PoolData {
const layoutDoc = Doc.Layout(params.pair.layout);
const { x, y, opacity } = this.Document._currentFrame === undefined ?
@@ -1097,6 +1100,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc, replica: string) {
return this._layoutPoolData.get(doc[Id] + (replica || ""));
}.bind(this));
+
childSizeProvider = computedFn(function childSizeProvider(this: any, doc: Doc, replica: string) {
return this._layoutSizeData.get(doc[Id] + (replica || ""));
}.bind(this));
@@ -1220,9 +1224,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
// super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
}
-
- // <div ref={this._marqueeRef}>
-
@action
onDragAutoScroll = (e: CustomEvent<React.DragEvent>) => {
if ((e as any).handlePan || this.props.isAnnotationOverlay) return;
@@ -1254,7 +1255,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.props.ContainingCollectionView?.removeDocument(this.props.Document);
}));
-
@undoBatch
layoutDocsInGrid = action(() => {
const docs = this.childLayoutPairs;
@@ -1288,8 +1288,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.layoutDoc._lockedTransform = this.layoutDoc._lockedTransform ? undefined : true;
}
- private thumbIdentifier?: number;
-
onContextMenu = (e: React.MouseEvent) => {
if (this.props.isAnnotationOverlay || this.props.Document.annotationOn || !ContextMenu.Instance) return;
@@ -1304,7 +1302,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const viewctrls = ContextMenu.Instance.findByDescription("UI Controls...");
const viewCtrlItems = viewctrls && "subitems" in viewctrls ? viewctrls.subitems : [];
-
!Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null;
!Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document._useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document._useClusters), icon: "braille" }) : null;
!viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" });
@@ -1312,7 +1309,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const options = ContextMenu.Instance.findByDescription("Options...");
const optionItems = options && "subitems" in options ? options.subitems : [];
!this.props.isAnnotationOverlay && !Doc.UserDoc().noviceMode &&
- optionItems.push({ description: (this.showTimeline ? "Close" : "Open") + " Animation Timeline", event: action(() => this.showTimeline = !this.showTimeline), icon: "eye" });
+ optionItems.push({ description: (this._showAnimTimeline ? "Close" : "Open") + " Animation Timeline", event: action(() => this._showAnimTimeline = !this._showAnimTimeline), icon: "eye" });
this.props.ContainingCollectionView &&
optionItems.push({ description: "Move Items Out of Collection", event: this.promoteCollection, icon: "table" });
optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" });
@@ -1320,7 +1317,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
if (!Doc.UserDoc().noviceMode) {
optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
optionItems.push({ description: `${this.Document._freeformLOD ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._freeformLOD = !this.Document._freeformLOD, icon: "table" });
-
}
!options && ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
const mores = ContextMenu.Instance.findByDescription("More...");
@@ -1349,11 +1345,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const [xx, yy] = this.props.ScreenToLocalTransform().transformPoint(x, y);
doc.x = xx, doc.y = yy;
this.props.addDocument?.(doc);
- setTimeout(() => {
+ setTimeout(() =>
SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => {
docs.docs.forEach(d => LinkManager.Instance.addLink(d));
- });
- }, 2000); // need to give solr some time to update so that this query will find any link docs we've added.
+ }), 2000); // need to give solr some time to update so that this query will find any link docs we've added.
}
}
}
@@ -1361,57 +1356,38 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
input.click();
}
-
- @observable showTimeline = false;
-
- intersectRect(r1: { left: number, top: number, width: number, height: number },
- r2: { left: number, top: number, width: number, height: number }) {
- return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top);
- }
-
@action
setupDragLines = (snapToDraggedDoc: boolean = false) => {
const activeDocs = this.getActiveDocuments();
- if (activeDocs.length > 50) {
- DragManager.SetSnapLines([], []);
- return;
- }
const size = this.getTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight());
const selRect = { left: this.panX() - size[0] / 2, top: this.panY() - size[1] / 2, width: size[0], height: size[1] };
const docDims = (doc: Doc) => ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) });
- const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => {
- if (this.intersectRect(docDims(doc), rect)) {
- snappableDocs.push(doc);
- }
- };
- const snappableDocs: Doc[] = []; // the set of documents in the visible viewport that we will try to snap to;
+ const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => intersectRect(docDims(doc), rect);
+
const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) };
- this.getActiveDocuments().filter(doc => !Cast(doc.layers, listSpec("string"), []).includes("background") && doc.z === undefined).map(doc => isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to
- !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => isDocInView(doc, selRect)); // if not, see if there are background docs to snap to
- !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => isDocInView(doc, otherBounds)); // if not, then why not snap to floating docs
+ let snappableDocs = activeDocs.filter(doc => !StrListCast(doc.layers).includes("background") && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to
+ !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect))); // if not, see if there are background docs to snap to
+ !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z !== undefined && isDocInView(doc, otherBounds))); // if not, then why not snap to floating docs
const horizLines: number[] = [];
const vertLines: number[] = [];
+ const invXf = this.getTransform().inverse();
snappableDocs.filter(doc => snapToDraggedDoc || !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)).forEach(doc => {
const { left, top, width, height } = docDims(doc);
- const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top);
- const docSize = this.getTransform().inverse().transformDirection(width, height);
+ const topLeftInScreen = invXf.transformPoint(left, top);
+ const docSize = invXf.transformDirection(width, height);
horizLines.push(topLeftInScreen[1], topLeftInScreen[1] + docSize[1] / 2, topLeftInScreen[1] + docSize[1]); // horiz center line
vertLines.push(topLeftInScreen[0], topLeftInScreen[0] + docSize[0] / 2, topLeftInScreen[0] + docSize[0]);// right line
});
DragManager.SetSnapLines(horizLines, vertLines);
}
+
onPointerOver = (e: React.PointerEvent) => {
- if (SnappingManager.GetIsDragging()) {
- this.setupDragLines(e.ctrlKey || e.shiftKey);
- }
+ SnappingManager.GetIsDragging() && this.setupDragLines(e.ctrlKey || e.shiftKey);
e.stopPropagation();
}
- @observable private _hLines: number[] | undefined;
- @observable private _vLines: number[] | undefined;
-
private childViews = () => {
const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
return [
@@ -1426,13 +1402,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
return eles;
}
+
@computed get placeholder() {
return <div className="collectionfreeformview-placeholder" style={{ background: this.Document.backgroundColor }}>
<span className="collectionfreeformview-placeholderSpan">{this.props.Document.title?.toString()}</span>
</div>;
}
- _nudgeTime = 0;
nudge = action((x: number, y: number) => {
if (this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ||
this.props.ContainingCollectionDoc._panX !== undefined) { // bcz: this isn't ideal, but want to try it out...
@@ -1450,7 +1426,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return divisions < 60 ? gridSpace : this.chooseGridSpace(gridSpace * 10);
}
- @computed get grid() {
+ @computed get backgroundGrid() {
const gridSpace = this.chooseGridSpace(NumCast(this.layoutDoc["_backgroundGrid-spacing"], 50));
const shiftX = (this.props.isAnnotationOverlay ? 0 : -this.panX() % gridSpace - gridSpace) * this.zoomScaling();
const shiftY = (this.props.isAnnotationOverlay ? 0 : -this.panY() % gridSpace - gridSpace) * this.zoomScaling();
@@ -1482,17 +1458,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}} />;
}
+
trySelectCluster = (addToSel: boolean) => {
if (this._hitCluster !== -1) {
- if (!addToSel) {
- SelectionManager.DeselectAll();
- }
+ !addToSel && SelectionManager.DeselectAll();
const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.props.Document._useClusters ? NumCast(cd.cluster) : NumCast(cd.group, -1)) === this._hitCluster);
this.selectDocuments(eles);
return true;
}
return false;
}
+
@computed get marqueeView() {
return <MarqueeView
{...this.props}
@@ -1507,7 +1483,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
getTransform={this.getTransform}
isAnnotationOverlay={this.isAnnotationOverlay}>
<div ref={this._marqueeRef}>
- {this.layoutDoc["_backgroundGrid-show"] ? this.grid : (null)}
+ {this.layoutDoc["_backgroundGrid-show"] ? this.backgroundGrid : (null)}
<CollectionFreeFormViewPannableContents
isAnnotationOverlay={this.isAnnotationOverlay}
centeringShiftX={this.centeringShiftX}
@@ -1521,11 +1497,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
{this.children}
</CollectionFreeFormViewPannableContents>
</div>
- {this.showTimeline ? <Timeline ref={this._timelineRef} {...this.props} /> : (null)}
+ {this._showAnimTimeline ? <Timeline ref={this._timelineRef} {...this.props} /> : (null)}
</MarqueeView>;
}
-
@computed get contentScaling() {
if (this.props.isAnnotationOverlay && !this.props.forceScaling) return 0;
const nw = returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document));