aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
diff options
context:
space:
mode:
authorAubrey Li <Aubrey-Li>2021-09-15 14:41:24 -0400
committerAubrey Li <Aubrey-Li>2021-09-15 14:41:24 -0400
commiteb63330e172935343767d0dcc7ffad9bfa1a75c4 (patch)
tree031bf155df50200f9652e881aec18002bc9e399e /src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
parentb7a88c6292c2e7bfffc3cdc4f7c7037922b3de25 (diff)
parent8386ad690c10d5c76bbd1b4f85314514b7f11b55 (diff)
merge master into trails-aubrey
Diffstat (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx85
1 files changed, 52 insertions, 33 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d09d9b9d7..be0b078ec 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,7 @@
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
+import { DateField } from "../../../../fields/DateField";
import { Doc, HeightSym, Opt, StrListCast, WidthSym } from "../../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas";
import { Id } from "../../../../fields/FieldSymbols";
@@ -17,6 +18,7 @@ import { aggregateBounds, emptyFunction, intersectRect, returnFalse, setupMoveUp
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
+import { DocumentType } from "../../../documents/DocumentTypes";
import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager, dropActionType } from "../../../util/DragManager";
@@ -48,8 +50,7 @@ import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCurso
import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { DateField } from "../../../../fields/DateField";
+import Color = require("color");
export const panZoomSchema = createSchema({
_panX: "number",
@@ -74,6 +75,8 @@ export type collectionFreeformViewProps = {
scaleField?: string;
noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale)
engineProps?: any;
+ dontRenderDocuments?: boolean; // used for annotation overlays which need to distribute documents into different freeformviews with different mixBlendModes depending on whether they are trnasparent or not.
+ // However, this screws up interactions since only the top layer gets events. so we render the freeformview a 3rd time with all documents in order to get interaction events (eg., marquee) but we don't actually want to display the documents.
};
@observer
@@ -115,7 +118,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); }
@computed get backgroundEvents() { return this.props.layerProvider?.(this.layoutDoc) === false && SnappingManager.GetIsDragging(); }
- @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.isContentActive() || this.props.isContentActive()); }
+ @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && this.props.isContentActive(); }
@computed get fitToContentVals() {
return {
bounds: { ...this.contentBounds, cx: (this.contentBounds.x + this.contentBounds.r) / 2, cy: (this.contentBounds.y + this.contentBounds.b) / 2 },
@@ -168,6 +171,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
getContainerTransform = () => this.cachedGetContainerTransform.copy();
getTransformOverlay = () => this.getContainerTransform().translate(1, 1);
getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
+ isAnyChildContentActive = () => this.props.isAnyChildContentActive();
addLiveTextBox = (newBox: Doc) => {
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);
@@ -179,7 +183,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
addDocument = (newBox: Doc | Doc[]) => {
let retVal = false;
if (newBox instanceof Doc) {
- if (retVal = this.props.addDocument?.(newBox) || false) {
+ if (retVal = (this.props.addDocument?.(newBox) || false)) {
this.bringToFront(newBox);
this.updateCluster(newBox);
}
@@ -205,25 +209,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return retVal;
}
- updateGroupBounds = () => {
- if (!this.props.Document._isGroup) return;
- const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() }));
- const cbounds = aggregateBounds(clist, 0, 0);
- const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[HeightSym]() / 2];
- const p = [NumCast(this.layoutDoc._panX), NumCast(this.layoutDoc._panY)];
- const pbounds = {
- x: (cbounds.x - p[0]) * this.zoomScaling() + c[0], y: (cbounds.y - p[1]) * this.zoomScaling() + c[1],
- r: (cbounds.r - p[0]) * this.zoomScaling() + c[0], b: (cbounds.b - p[1]) * this.zoomScaling() + c[1]
- };
-
- this.layoutDoc._width = (pbounds.r - pbounds.x);
- this.layoutDoc._height = (pbounds.b - pbounds.y);
- this.layoutDoc._panX = (cbounds.r + cbounds.x) / 2;
- this.layoutDoc._panY = (cbounds.b + cbounds.y) / 2;
- this.layoutDoc.x = pbounds.x;
- this.layoutDoc.y = pbounds.y;
- }
-
isCurrent(doc: Doc) {
const dispTime = NumCast(doc._timecodeToShow, -1);
const endTime = NumCast(doc._timecodeToHide, dispTime + 1.5);
@@ -265,8 +250,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
!StrListCast(d._layerTags).includes(StyleLayers.Background) && (d._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : d._raiseWhenDragged) && (d.zIndex = zsorted.length + 1 + i); // bringToFront
}
- this.updateGroupBounds();
-
(docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments);
return true;
}
@@ -506,7 +489,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const points = ge.points;
const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
const inkDoc = Docs.Create.InkDocument(ActiveInkColor(), CurrentUserUtils.SelectedTool, ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), points,
- { title: "ink stroke", x: B.x - Number(ActiveInkWidth()) / 2, y: B.y - Number(ActiveInkWidth()) / 2, _width: B.width + Number(ActiveInkWidth()), _height: B.height + Number(ActiveInkWidth()) });
+ { title: "ink stroke", x: B.x - ActiveInkWidth() / 2, y: B.y - ActiveInkWidth() / 2, _width: B.width + ActiveInkWidth(), _height: B.height + ActiveInkWidth() });
this.addDocument(inkDoc);
e.stopPropagation();
break;
@@ -1031,7 +1014,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
docFilters={this.childDocFilters}
docRangeFilters={this.childDocRangeFilters}
searchFilterDocs={this.searchFilterDocs}
- isContentActive={this.isAnnotationOverlay ? this.props.isContentActive : returnFalse}
+ isContentActive={returnFalse}
isDocumentActive={this.props.childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
focus={this.focusDocument}
addDocTab={this.addDocTab}
@@ -1048,7 +1031,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
freezeDimensions={this.props.childFreezeDimensions}
dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
bringToFront={this.bringToFront}
- dontRegisterView={this.props.dontRegisterView}
+ showTitle={this.props.childShowTitle}
+ dontRegisterView={this.props.dontRenderDocuments || this.props.dontRegisterView}
pointerEvents={this.backgroundActive || this.props.childPointerEvents ? "all" :
(this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? "none" : undefined}
jitterRotation={this.props.styleProvider?.(childLayout, this.props, StyleProp.JitterRotation) || 0}
@@ -1231,6 +1215,30 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
{ fireImmediately: true, name: "doLayout" });
this._marqueeRef.current?.addEventListener("dashDragAutoScroll", this.onDragAutoScroll as any);
+
+ this._disposers.groupBounds = reaction(() => {
+ if (this.props.Document._isGroup && this.childDocs.length === this.childDocList?.length) {
+ const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() }));
+ return aggregateBounds(clist, NumCast(this.layoutDoc._xPadding), NumCast(this.layoutDoc._yPadding));
+ }
+ return undefined;
+ },
+ (cbounds) => {
+ if (cbounds) {
+ const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[HeightSym]() / 2];
+ const p = [NumCast(this.layoutDoc._panX), NumCast(this.layoutDoc._panY)];
+ const pbounds = {
+ x: (cbounds.x - p[0]) * this.zoomScaling() + c[0], y: (cbounds.y - p[1]) * this.zoomScaling() + c[1],
+ r: (cbounds.r - p[0]) * this.zoomScaling() + c[0], b: (cbounds.b - p[1]) * this.zoomScaling() + c[1]
+ };
+ this.layoutDoc._width = (pbounds.r - pbounds.x);
+ this.layoutDoc._height = (pbounds.b - pbounds.y);
+ this.layoutDoc._panX = (cbounds.r + cbounds.x) / 2;
+ this.layoutDoc._panY = (cbounds.b + cbounds.y) / 2;
+ this.layoutDoc.x = pbounds.x;
+ this.layoutDoc.y = pbounds.y;
+ }
+ }, { fireImmediately: true });
}
componentWillUnmount() {
@@ -1322,8 +1330,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
!options && ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
const mores = ContextMenu.Instance.findByDescription("More...");
const moreItems = mores && "subitems" in mores ? mores.subitems : [];
- moreItems.push({ description: "Export collection", icon: "download", event: async () => Doc.Zip(this.props.Document) });
- moreItems.push({ description: "Import exported collection", icon: "upload", event: ({ x, y }) => this.importDocument(x, y) });
+ if (!Doc.UserDoc().noviceMode) {
+ moreItems.push({ description: "Export collection", icon: "download", event: async () => Doc.Zip(this.props.Document) });
+ moreItems.push({ description: "Import exported collection", icon: "upload", event: ({ x, y }) => this.importDocument(x, y) });
+ }
!mores && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "eye" });
}
@@ -1395,6 +1405,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
chooseGridSpace = (gridSpace: number): number => {
+ if (!this.zoomScaling()) return 50;
const divisions = this.props.PanelWidth() / this.zoomScaling() / gridSpace + 3;
return divisions < 60 ? gridSpace : this.chooseGridSpace(gridSpace * 10);
}
@@ -1452,8 +1463,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
getContainerTransform={this.getContainerTransform}
getTransform={this.getTransform}
isAnnotationOverlay={this.isAnnotationOverlay}>
- <div ref={this._marqueeRef}>
- {this.layoutDoc["_backgroundGrid-show"] ? this.backgroundGrid : (null)}
+ <div ref={this._marqueeRef} style={{ display: this.props.dontRenderDocuments ? "none" : undefined }}>
+ {this.layoutDoc._backgroundGridShow ? this.backgroundGrid : (null)}
<CollectionFreeFormViewPannableContents
isAnnotationOverlay={this.isAnnotationOverlay}
transform={this.contentTransform}
@@ -1479,6 +1490,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return wscale < hscale ? wscale : hscale;
}
+ private groupDropDisposer?: DragManager.DragDropDisposer;
+ protected createGroupEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
+ this.groupDropDisposer?.();
+ if (ele) {
+ this.groupDropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this));
+ }
+ }
+
render() {
TraceMobx();
const clientRect = this._mainCont?.getBoundingClientRect();
@@ -1522,7 +1541,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
</div>}
{this.props.Document._isGroup && SnappingManager.GetIsDragging() && (this.ChildDrag || this.props.layerProvider?.(this.props.Document) === false) ?
- <div className="collectionFreeForm-groupDropper" ref={this.createDashEventsTarget} style={{
+ <div className="collectionFreeForm-groupDropper" ref={this.createGroupEventsTarget} style={{
width: this.ChildDrag ? "10000" : "100%",
height: this.ChildDrag ? "10000" : "100%",
left: this.ChildDrag ? "-5000" : 0,