aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2020-12-10 22:28:43 +0530
committerusodhi <61431818+usodhi@users.noreply.github.com>2020-12-10 22:28:43 +0530
commit563d86f03f63f60ec47aef23d2022c660ee18697 (patch)
treeefd71242ac43dba47e7d44da3d4874dcc8f71d3e /src/client/views/collections
parent49491180cfbc03b72867970043b674dc1362cc81 (diff)
parent3412313dcde569f1f23616fa5e8a92c3985e0449 (diff)
merging
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx2
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx1
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx1
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx3
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/collections/SchemaTable.tsx1
-rw-r--r--src/client/views/collections/TabDocView.tsx23
-rw-r--r--src/client/views/collections/TreeView.tsx78
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx18
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx394
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx1
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx1
14 files changed, 185 insertions, 343 deletions
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 62c1bce3f..16ccdc6f4 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -65,7 +65,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
</div>
<div className="collectionCarouselView-caption" key="caption"
style={{
- background: StrCast(this.layoutDoc._captionBackgroundColor, this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor", this.props.layerProvider)),
+ background: StrCast(this.layoutDoc._captionBackgroundColor, this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor")),
color: StrCast(this.layoutDoc._captionColor, StrCast(this.layoutDoc.color)),
borderRadius: StrCast(this.layoutDoc._captionBorderRounding),
}}>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 57b038c73..eee939c07 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -90,7 +90,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
@undoBatch
- public static OpenFullScreen(doc: Doc, libraryPath?: Doc[]) {
+ public static OpenFullScreen(doc: Doc) {
const instance = CollectionDockingView.Instance;
if (doc._viewType === CollectionViewType.Docking && doc.layoutKey === "layout") {
return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index b427e35c3..c7c510306 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -140,7 +140,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
<ContentFittingDocumentView
Document={pair.layout}
DataDoc={pair.data}
- LibraryPath={this.props.LibraryPath}
addDocument={this.props.addDocument}
moveDocument={this.props.moveDocument}
addDocTab={this.props.addDocTab}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index a1df9d214..8ae70ce20 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -404,7 +404,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
FreezeDimensions={true}
dontCenter={"y"}
focus={emptyFunction}
- LibraryPath={this.props.LibraryPath}
renderDepth={this.props.renderDepth}
rootSelected={this.rootSelected}
PanelWidth={this.previewWidth}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4b3393e14..0e4029764 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -195,7 +195,6 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
styleProvider={this.props.styleProvider}
LayoutTemplate={this.props.ChildLayoutTemplate}
LayoutTemplateString={this.props.ChildLayoutString}
- LibraryPath={this.props.LibraryPath}
FreezeDimensions={this.props.freezeChildDimensions}
renderDepth={this.props.renderDepth + 1}
PanelWidth={width}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index add008952..572aae260 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -163,7 +163,6 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
Document={this.doc}
DataDoc={undefined}
LayoutTemplateString={FormattedTextBox.LayoutString("text")}
- LibraryPath={emptyPath}
renderDepth={this.props.renderDepth + 1}
rootSelected={returnTrue}
treeViewDoc={undefined}
@@ -216,7 +215,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
render() {
TraceMobx();
if (!(this.doc instanceof Doc)) return (null);
- const background = this.props.styleProvider?.(this.doc, this.props, "backgroundColor", this.props.layerProvider);
+ const background = this.props.styleProvider?.(this.doc, this.props, "backgroundColor");
const paddingX = `${NumCast(this.doc._xPadding, 10)}px`;
const paddingTop = `${NumCast(this.doc._yPadding, 20)}px`;
// const pointerEvents = !this.props.active() && !SnappingManager.GetIsDragging() && !this._isChildActive ? "none" : undefined;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0a9eeab50..8f402c427 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -399,7 +399,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
ChildLayoutString: this.childLayoutString,
};
const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.treeViewOutlineMode || this.collectionViewType === CollectionViewType.Linear ? undefined :
- this.props.styleProvider?.(this.props.Document, this.props, "boxShadow", this.props.layerProvider);
+ this.props.styleProvider?.(this.props.Document, this.props, "boxShadow");
return (<div className={"collectionView"} onContextMenu={this.onContextMenu}
style={{ pointerEvents: this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined, boxShadow }}>
{this.showIsTagged()}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 087d106c5..664b6115a 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -573,7 +573,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
fitToBox={true}
FreezeDimensions={true}
focus={emptyFunction}
- LibraryPath={emptyPath}
renderDepth={this.props.renderDepth}
rootSelected={() => false}
PanelWidth={() => 150}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 1026f043c..e1fd47592 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -32,7 +32,6 @@ import React = require("react");
import { List } from '../../../fields/List';
import { DocumentType } from '../../documents/DocumentTypes';
import Color = require('color');
-import { InkTool } from '../../../fields/InkField';
const _global = (window /* browser */ || global /* node */) as any;
interface TabDocViewProps {
@@ -289,7 +288,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
// "replace:right" - will replace the stack on the right named "right" if it exists, or create a stack on the right with that name,
// "replace:monkeys" - will replace any tab that has the label 'monkeys', or a tab with that label will be created by default on the right
// inPlace - will add the document to any collection along the path from the document to the docking view that has a field isInPlaceContainer. if none is found, inPlace adds a tab to current stack
- addDocTab = (doc: Doc, location: string, libraryPath?: Doc[]) => {
+ addDocTab = (doc: Doc, location: string) => {
SelectionManager.DeselectAll();
const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
const locationParams = locationFields.length > 1 ? locationFields[1] : "";
@@ -336,7 +335,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
<div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.tabColor }}>
<CollectionFreeFormView
Document={this._document!}
- LibraryPath={emptyPath}
CollectionView={undefined}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
@@ -417,9 +415,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
}
- @undoBatch
- @action
- static toggleBackground = (doc: Doc) => {
+ static toggleBackground = undoBatch(action((doc: Doc) => {
const layers = StrListCast(doc.layers);
if (!layers.includes("background")) {
if (!layers.length) doc.layers = new List<string>(["background"]);
@@ -434,11 +430,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
// Doc.SetNativeWidth(this.props.Document[DataSym], wid);
// Doc.SetNativeHeight(this.props.Document[DataSym], hgt);
}
- }
+ }));
//
// a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
//
- public static styleProvider = (doc: Opt<Doc>, props: DocumentViewProps | undefined, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean): any => {
+ public static styleProvider = (doc: Opt<Doc>, props: DocumentViewProps | undefined, property: string): any => {
switch (property) {
case "backgroundColor": {
if (Doc.UserDoc().renderStyle === "comic") return undefined;
@@ -460,11 +456,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
default: docColor = TabDocView.darkScheme ? "black" : "white"; break;
}
}
- if (docColor && (!doc || layerProvider?.(doc) === false)) docColor = Color(docColor).fade(0.5).toString();
+ if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor).fade(0.5).toString();
return docColor;
}
case "widgetColor": return TabDocView.darkScheme ? "lightgrey" : "dimgrey";
- case "hidden": return (BoolCast(doc?.hidden) /* || layerProvider?.(doc) === false*/);
+ case "hidden": return (BoolCast(doc?.hidden) /* || props?.layerProvider?.(doc) === false*/);
case "boxShadow": {
switch (doc?.type) {
case DocumentType.COL: return StrListCast(doc.layers).includes("background") ? undefined :
@@ -475,7 +471,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
case "docContents": return undefined;
default:
if (property.startsWith("pointerEvents")) {
- const layer = doc && layerProvider?.(doc);
+ const layer = doc && props?.layerProvider?.(doc);
if (doc?.Opacity === 0 || doc?.type === DocumentType.INK || doc?.isInkMask) return "none";
if (layer === false && !property.includes(":selected") && !SnappingManager.GetIsDragging()) return "none";
if (doc?.type !== DocumentType.INK && layer === true) return "all";
@@ -492,7 +488,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
}
}
- public static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean): any => {
+ public static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
if (doc) {
switch (property) {
case "docContents":
@@ -502,7 +498,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
return <div style={{ width: doc[WidthSym](), height: doc[HeightSym](), position: "absolute", display: "block", background }} />;
default:
if (property.startsWith("pointerEvents")) return "none";
- return TabDocView.styleProvider(doc, props, property, layerProvider);
+ return TabDocView.styleProvider(doc, props, property);
}
}
}
@@ -510,7 +506,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
TraceMobx();
return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) :
<><DocumentView key={this._document[Id]}
- LibraryPath={emptyPath}
Document={this._document}
getView={this.setView}
DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 31f028727..675ba60c0 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -39,7 +39,7 @@ export interface TreeViewProps {
removeDoc: ((doc: Doc | Doc[]) => boolean) | undefined;
moveDocument: DragManager.MoveFunction;
dropAction: dropActionType;
- addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean;
+ addDocTab: (doc: Doc, where: string) => boolean;
pinToPres: (document: Doc) => void;
panelWidth: () => number;
panelHeight: () => number;
@@ -376,15 +376,29 @@ export class TreeView extends React.Component<TreeViewProps> {
if (["links", "annotations", this.fieldKey].includes(expandKey)) {
const remDoc = (doc: Doc | Doc[]) => this.remove(doc, expandKey);
const localAdd = (doc: Doc, addBefore?: Doc, before?: boolean) => {
+ // if there's a sort ordering specified that can be modified on drop (eg, zorder can be modified, alphabetical can't),
+ // then the modification would be done here
+ const ordering = StrCast(this.doc[this.fieldKey + "-sortCriteria"]);
+ if (ordering === "zorder") {
+ const docs = TreeView.sortDocs(this.childDocs || ([] as Doc[]), ordering);
+ doc.zIndex = addBefore ? (before ? NumCast(addBefore.zIndex) - 0.5 : NumCast(addBefore.zIndex) + 0.5) : 1000;
+ docs.push(doc);
+ docs.sort((a, b) => NumCast(a.zIndex) > NumCast(b.zIndex) ? 1 : -1);
+ docs.forEach((d, i) => d.zIndex = i);
+ }
const added = Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, false, true);
added && (doc.context = this.doc.context);
return added;
};
const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && localAdd(doc, addBefore, before), true);
const docs = expandKey === "links" ? this.childLinks : expandKey === "annotations" ? this.childAnnos : this.childDocs;
- const sortKey = `${this.fieldKey}-sortAscending`;
+ const sortKey = `${this.fieldKey}-sortCriteria`;
return <ul key={expandKey + "more"} className={this.doc.treeViewHideTitle ? "no-indent" : ""} onClick={(e) => {
- !this.outlineMode && (this.doc[sortKey] = (this.doc[sortKey] ? false : (this.doc[sortKey] === false ? undefined : true)));
+ !this.outlineMode && (this.doc[sortKey] =
+ (this.doc[sortKey] === "ascending" ? "descending" :
+ (this.doc[sortKey] === "descending" ? "zorder" :
+ (this.doc[sortKey] === "zorder" ? undefined :
+ "ascending"))));
e.stopPropagation();
}}>
{!docs ? (null) :
@@ -507,7 +521,6 @@ export class TreeView extends React.Component<TreeViewProps> {
Document={this.doc}
DataDoc={undefined}
treeViewDoc={this.props.treeView.props.Document}
- LibraryPath={emptyPath}
addDocument={undefined}
addDocTab={this.props.addDocTab}
rootSelected={returnTrue}
@@ -584,7 +597,6 @@ export class TreeView extends React.Component<TreeViewProps> {
focus={asText ? this.refocus : returnFalse}
dontRegisterView={asText ? undefined : this.props.dontRegisterView}
ScreenToLocalTransform={this.docTransform}
- LibraryPath={emptyPath}
renderDepth={this.props.renderDepth + 1}
rootSelected={returnTrue}
treeViewDoc={undefined}
@@ -614,9 +626,9 @@ export class TreeView extends React.Component<TreeViewProps> {
}
@computed get renderBorder() {
- const sorting = this.doc[`${this.fieldKey}-sortAscending`];
+ const sorting = this.doc[`${this.fieldKey}-sortCriteria`];
return <div className={`treeView-border${this.outlineMode ? "outline" : ""}`}
- style={{ borderColor: sorting === undefined ? undefined : sorting ? "crimson" : "blue" }}>
+ style={{ borderColor: sorting === undefined ? undefined : sorting === "ascending" ? "crimson" : sorting === "descending" ? "blue" : "green" }}>
{!this.treeViewOpen ? (null) : this.renderContent}
</div>;
}
@@ -656,6 +668,34 @@ export class TreeView extends React.Component<TreeViewProps> {
</div>;
}
+ public static sortDocs(childDocs: Doc[], criterion: string | undefined) {
+ const docs = childDocs.slice();
+ if (criterion) {
+ const sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
+ const reN = /[0-9]*$/;
+ const aA = a.replace(reN, ""); // get rid of trailing numbers
+ const bA = b.replace(reN, "");
+ if (aA === bA) { // if header string matches, then compare numbers numerically
+ const aN = parseInt(a.match(reN)![0], 10);
+ const bN = parseInt(b.match(reN)![0], 10);
+ return aN === bN ? 0 : aN > bN ? 1 : -1;
+ } else {
+ return aA > bA ? 1 : -1;
+ }
+ };
+ docs.sort(function (d1, d2): 0 | 1 | -1 {
+ const a = (criterion === "ascending" ? d2 : d1);
+ const b = (criterion === "ascending" ? d1 : d2);
+ const first = a[criterion === "zorder" ? "zIndex" : "title"];
+ const second = b[criterion === "zorder" ? "zIndex" : "title"];
+ if (typeof first === 'number' && typeof second === 'number') return (first - second) > 0 ? 1 : -1;
+ if (typeof first === 'string' && typeof second === 'string') return sortAlphaNum(first, second);
+ return criterion ? 1 : -1;
+ });
+ }
+ return docs;
+ }
+
public static GetChildElements(
childDocs: Doc[],
treeView: CollectionTreeView,
@@ -691,29 +731,7 @@ export class TreeView extends React.Component<TreeViewProps> {
childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
}
- const docs = childDocs.slice();
- const ascending = containingCollection?.[key + "-sortAscending"];
- if (ascending !== undefined) {
- const sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
- const reN = /[0-9]*$/;
- const aA = a.replace(reN, ""); // get rid of trailing numbers
- const bA = b.replace(reN, "");
- if (aA === bA) { // if header string matches, then compare numbers numerically
- const aN = parseInt(a.match(reN)![0], 10);
- const bN = parseInt(b.match(reN)![0], 10);
- return aN === bN ? 0 : aN > bN ? 1 : -1;
- } else {
- return aA > bA ? 1 : -1;
- }
- };
- docs.sort(function (a, b): 0 | 1 | -1 {
- const first = (ascending ? b : a).title;
- const second = (ascending ? a : b).title;
- if (typeof first === 'number' && typeof second === 'number') return (first - second) > 0 ? 1 : -1;
- if (typeof first === 'string' && typeof second === 'string') return sortAlphaNum(first, second);
- return ascending ? 1 : -1;
- });
- }
+ const docs = TreeView.sortDocs(childDocs, StrCast(containingCollection?.[key + "-sortCriteria"]));
const rowWidth = () => panelWidth() - 20;
return docs.filter(child => child instanceof Doc).map((child, i) => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ab0c3964b..136600164 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -12,7 +12,7 @@ import { ScriptField } from "../../../../fields/ScriptField";
import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
import { TraceMobx } from "../../../../fields/util";
import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnVal } from "../../../../Utils";
+import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnVal, returnTrue } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
@@ -222,14 +222,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const zsorted = this.childLayoutPairs.map(pair => pair.layout).slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
zsorted.forEach((doc, index) => doc.zIndex = doc.isInkMask ? 5000 : index + 1);
const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
- const dropPos = this.Document._currentFrame !== undefined ? [dvals.x, dvals.y] : [NumCast(refDoc.x), NumCast(refDoc.y)];
+ const dropPos = this.Document._currentFrame !== undefined ? [dvals.x || 0, dvals.y || 0] : [NumCast(refDoc.x), NumCast(refDoc.y)];
for (let i = 0; i < docDragData.droppedDocuments.length; i++) {
const d = docDragData.droppedDocuments[i];
const layoutDoc = Doc.Layout(d);
if (this.Document._currentFrame !== undefined) {
CollectionFreeFormDocumentView.setupKeyframes([d], this.Document._currentFrame, false);
const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000));
- CollectionFreeFormDocumentView.setValues(this.Document._currentFrame, d, x + vals.x - dropPos[0], y + vals.y - dropPos[1], vals.h, vals.w, this.Document.editScrollProgressivize ? vals.scroll : undefined, vals.opacity);
+ vals.x = x + (vals.x || 0) - dropPos[0];
+ vals.y = y + (vals.y || 0) - dropPos[1];
+ vals._scrollTop = this.Document.editScrollProgressivize ? vals._scrollTop : undefined;
+ CollectionFreeFormDocumentView.setValues(this.Document._currentFrame, d, vals);
} else {
d.x = x + NumCast(d.x) - dropPos[0];
d.y = y + NumCast(d.y) - dropPos[1];
@@ -393,8 +396,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}
- getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => {
- let clusterColor = this.props.styleProvider?.(doc, props, property, layerProvider); // bcz: check 'props' used to be renderDepth + 1
+ getClusterColor = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => {
+ let clusterColor = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1
if (property !== "backgroundColor") return clusterColor;
const cluster = NumCast(doc?.cluster);
if (this.Document._useClusters) {
@@ -979,11 +982,11 @@ 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 libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; }
@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);
- backgroundHalo = computedFn(function (doc: Doc) { return BoolCast(this.Document._useClusters) || (NumCast(doc.group, -1) !== -1); }).bind(this);
+ // @ts-ignore
+ backgroundHalo = computedFn(function (doc: Doc) { return this.Document._useClusters || NumCast(doc.group, -1) !== -1; }).bind(this);
parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false;
getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps {
return {
@@ -996,7 +999,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
fitToBox: false,
DataDoc: childData,
Document: childLayout,
- LibraryPath: this.libraryPath,
LayoutTemplate: childLayout.z ? undefined : this.props.ChildLayoutTemplate,
LayoutTemplateString: childLayout.z ? undefined : this.props.ChildLayoutString,
FreezeDimensions: this.props.freezeChildDimensions,
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index eb781ed0a..a963b9158 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,31 +1,32 @@
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { AclAddonly, AclAdmin, AclEdit, DataSym, Doc, DocListCast, Opt } from "../../../../fields/Doc";
+import { AclAddonly, AclAdmin, AclEdit, DataSym, Doc, Opt } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
import { InkData, InkField, InkTool } from "../../../../fields/InkField";
import { List } from "../../../../fields/List";
import { RichTextField } from "../../../../fields/RichTextField";
import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types";
import { GetEffectiveAcl } from "../../../../fields/util";
-import { Utils } from "../../../../Utils";
+import { Utils, intersectRect } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents";
+import { DocumentType } from "../../../documents/DocumentTypes";
+import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
import { DocumentManager } from "../../../util/DocumentManager";
import { SelectionManager } from "../../../util/SelectionManager";
import { Transform } from "../../../util/Transform";
import { undoBatch, UndoManager } from "../../../util/UndoManager";
import { ContextMenu } from "../../ContextMenu";
import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
+import { PresBox, PresMovement } from "../../nodes/PresBox";
import { PreviewCursor } from "../../PreviewCursor";
import { CollectionDockingView } from "../CollectionDockingView";
import { SubCollectionViewProps } from "../CollectionSubView";
-import { CollectionView, CollectionViewType } from "../CollectionView";
+import { CollectionView } from "../CollectionView";
import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu";
import "./MarqueeView.scss";
import React = require("react");
-import { Id } from "../../../../fields/FieldSymbols";
-import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
-import { PresBox, PresMovement } from "../../nodes/PresBox";
interface MarqueeViewProps {
getContainerTransform: () => Transform;
@@ -38,20 +39,28 @@ interface MarqueeViewProps {
nudge?: (x: number, y: number) => boolean;
setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void;
}
-
@observer
export class MarqueeView extends React.Component<SubCollectionViewProps & MarqueeViewProps>
{
+ private _commandExecuted = false;
@observable public static DragMarquee = false;
@observable _lastX: number = 0;
@observable _lastY: number = 0;
@observable _downX: number = 0;
@observable _downY: number = 0;
@observable _visible: boolean = false;
- _commandExecuted = false;
- @observable _pointsX: number[] = [];
- @observable _pointsY: number[] = [];
- @observable _freeHand: boolean = false;
+ @observable _lassoPts: [number, number][] = [];
+ @observable _lassoFreehand: boolean = false;
+
+ @computed get Transform() { return this.props.getTransform(); }
+ @computed get Bounds() {
+ const topLeft = this.Transform.transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY);
+ const size = this.Transform.transformDirection(this._lastX - this._downX, this._lastY - this._downY);
+ return { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
+ }
+ get inkDoc() { return this.props.Document; }
+ get ink() { return Cast(this.props.Document.ink, InkField); }
+ set ink(value: Opt<InkField>) { this.props.Document.ink = value; }
componentDidMount() {
this.props.setPreviewCursor?.(this.setPreviewCursor);
@@ -64,11 +73,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
document.removeEventListener("pointermove", this.onPointerMove, true);
}
document.removeEventListener("keydown", this.marqueeCommand, true);
- if (hideMarquee) {
- this._visible = false;
- }
- this._pointsX = [];
- this._pointsY = [];
+ hideMarquee && this.hideMarquee();
+
+ this._lassoPts = [];
}
@undoBatch
@@ -77,7 +84,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
//make textbox and add it to this collection
// tslint:disable-next-line:prefer-const
const cm = ContextMenu.Instance;
- const [x, y] = this.props.getTransform().transformPoint(this._downX, this._downY);
+ const [x, y] = this.Transform.transformPoint(this._downX, this._downY);
if (e.key === "?") {
cm.setDefaultItem("?", (str: string) => this.props.addDocTab(
Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _fitWidth: true, _width: 400, x, y, _height: 512, _nativeWidth: 850, isAnnotating: false, title: "bing", useCors: true }), "add:right"));
@@ -115,7 +122,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const indent = line.search(/\S|$/);
const newBox = Docs.Create.TextDocument(line, { _width: 200, _height: 35, x: x + indent / 3 * 10, y: ypos, title: line });
this.props.addDocument(newBox);
- ypos += 40 * this.props.getTransform().Scale;
+ ypos += 40 * this.Transform.Scale;
});
})();
e.stopPropagation();
@@ -187,6 +194,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.props.addDocument(newCol);
}
}
+
@action
onPointerDown = (e: React.PointerEvent): void => {
this._downX = this._lastX = e.clientX;
@@ -210,13 +218,12 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
onPointerMove = (e: PointerEvent): void => {
this._lastX = e.pageX;
this._lastY = e.pageY;
- this._pointsX.push(e.clientX);
- this._pointsY.push(e.clientY);
+ this._lassoPts.push([e.clientX, e.clientY]);
if (!e.cancelBubble) {
if (Math.abs(this._lastX - this._downX) > Utils.DRAG_THRESHOLD ||
Math.abs(this._lastY - this._downY) > Utils.DRAG_THRESHOLD) {
if (!this._commandExecuted) {
- this._visible = true;
+ this.showMarquee();
}
e.stopPropagation();
e.preventDefault();
@@ -267,6 +274,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
e.preventDefault();
}
}
+
clearSelection() {
if (window.getSelection) { window.getSelection()?.removeAllRanges(); }
else if (document.getSelection()) { document.getSelection()?.empty(); }
@@ -314,41 +322,11 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
}
- 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);
- }
-
- @computed
- get Bounds() {
- const left = this._downX < this._lastX ? this._downX : this._lastX;
- const top = this._downY < this._lastY ? this._downY : this._lastY;
- const topLeft = this.props.getTransform().transformPoint(left, top);
- const size = this.props.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
- return { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
- }
-
- get inkDoc() {
- return this.props.Document;
- }
-
- get ink() { // ink will be stored on the extension doc for the field (fieldKey) where the container's data is stored.
- return Cast(this.props.Document.ink, InkField);
- }
-
- set ink(value: InkField | undefined) {
- this.props.Document.ink = value;
- }
-
@action
- showMarquee = () => {
- this._visible = true;
- }
+ showMarquee = () => { this._visible = true; }
@action
- hideMarquee = () => {
- this._visible = false;
- }
+ hideMarquee = () => { this._visible = false; }
@undoBatch
@action
@@ -393,11 +371,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- @undoBatch @action
+ @undoBatch
+ @action
pinWithView = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const doc = this.props.Document;
- const bounds = this.Bounds;
- const selected = this.marqueeSelect(false);
const curPres = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
if (curPres) {
if (doc === curPres) { alert("Cannot pin presentation document to itself"); return; }
@@ -407,9 +384,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
pinDoc.groupWithUp = false;
pinDoc.context = curPres;
pinDoc.title = doc.title + " - Slide";
- const presArray: Doc[] = PresBox.Instance?.sortArray();
- const size: number = PresBox.Instance?._selectedArray.size;
- const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
+ const presArray = PresBox.Instance?.sortArray();
+ const size = PresBox.Instance?._selectedArray.size;
+ const presSelected = presArray && size ? presArray[size - 1] : undefined;
Doc.AddDocToList(curPres, "data", pinDoc, presSelected);
if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
if (!DocumentManager.Instance.getDocumentView(curPres)) {
@@ -420,14 +397,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const index = PresBox.Instance?.childDocs.indexOf(pinDoc);
index && (curPres._itemIndex = index);
if (e instanceof KeyboardEvent ? e.key === "c" : true) {
- const x = this.Bounds.left + this.Bounds.width / 2;
- const y = this.Bounds.top + this.Bounds.height / 2;
- const panelWidth: number = this.props.PanelWidth();
- const panelHeight: number = this.props.PanelHeight();
- const scale = Math.min(Number(panelWidth) / this.Bounds.width, Number(panelHeight) / this.Bounds.height);
+ const scale = Math.min(this.props.PanelWidth() / this.Bounds.width, this.props.PanelHeight() / this.Bounds.height);
pinDoc.presPinView = true;
- pinDoc.presPinViewX = x;
- pinDoc.presPinViewY = y;
+ pinDoc.presPinViewX = this.Bounds.left + this.Bounds.width / 2;
+ pinDoc.presPinViewY = this.Bounds.top + this.Bounds.height / 2;
pinDoc.presPinViewScale = scale;
}
}
@@ -435,9 +408,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- @undoBatch @action
+ @undoBatch
+ @action
collection = (e: KeyboardEvent | React.PointerEvent | undefined) => {
- const bounds = this.Bounds;
const selected = this.marqueeSelect(false);
if (e instanceof KeyboardEvent ? e.key === "c" : true) {
selected.map(action(d => {
@@ -447,8 +420,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
delete d.y;
delete d.activeFrame;
delete d.displayTimecode; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
- d.x = dx - bounds.left - bounds.width / 2;
- d.y = dy - bounds.top - bounds.height / 2;
+ d.x = dx - this.Bounds.left - this.Bounds.width / 2;
+ d.y = dy - this.Bounds.top - this.Bounds.height / 2;
return d;
}));
this.props.removeDocument(selected);
@@ -460,33 +433,23 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- @undoBatch @action
+ @undoBatch
+ @action
syntaxHighlight = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const selected = this.marqueeSelect(false);
if (e instanceof KeyboardEvent ? e.key === "i" : true) {
- const inks = selected.filter(s => s.proto?.type === "ink");
- const setDocs = selected.filter(s => s.proto?.type === "text" && s.color);
- const sets = setDocs.map((sd) => {
- return Cast(sd.data, RichTextField)?.Text as string;
- });
+ const inks = selected.filter(s => s.proto?.type === DocumentType.INK);
+ const setDocs = selected.filter(s => s.proto?.type === DocumentType.RTF && s.color);
+ const sets = setDocs.map((sd) => Cast(sd.data, RichTextField)?.Text as string);
const colors = setDocs.map(sd => FieldValue(sd.color) as string);
const wordToColor = new Map<string, string>();
- sets.forEach((st: string, i: number) => {
- const words = st.split(",");
- words.forEach(word => {
- wordToColor.set(word, colors[i]);
- });
- });
+ sets.forEach((st: string, i: number) => st.split(",").forEach(word => wordToColor.set(word, colors[i])));
const strokes: InkData[] = [];
- inks.forEach(i => {
- const d = Cast(i.data, InkField);
- const x = NumCast(i.x);
- const y = NumCast(i.y);
+ inks.filter(i => Cast(i.data, InkField)).forEach(i => {
+ const d = Cast(i.data, InkField, null);
const left = Math.min(...d?.inkData.map(pd => pd.X) ?? [0]);
const top = Math.min(...d?.inkData.map(pd => pd.Y) ?? [0]);
- if (d) {
- strokes.push(d.inkData.map(pd => ({ X: pd.X + x - left, Y: pd.Y + y - top })));
- }
+ strokes.push(d.inkData.map(pd => ({ X: pd.X + NumCast(i.x) - left, Y: pd.Y + NumCast(i.y) - top })));
});
CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then((results) => {
// const wordResults = results.filter((r: any) => r.category === "inkWord");
@@ -536,18 +499,16 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
}
- @undoBatch @action
+ @undoBatch
+ @action
summary = (e: KeyboardEvent | React.PointerEvent | undefined) => {
- const bounds = this.Bounds;
- const selected = this.marqueeSelect(false);
- selected.map(d => {
+ const selected = this.marqueeSelect(false).map(d => {
this.props.removeDocument(d);
- d.x = NumCast(d.x) - bounds.left;
- d.y = NumCast(d.y) - bounds.top;
- d.page = -1;
+ d.x = NumCast(d.x) - this.Bounds.left;
+ d.y = NumCast(d.y) - this.Bounds.top;
return d;
});
- const summary = Docs.Create.TextDocument("", { x: bounds.left, y: bounds.top, _width: 200, _height: 200, _fitToBox: true, _showSidebar: true, title: "overview" });
+ const summary = Docs.Create.TextDocument("", { x: this.Bounds.left, y: this.Bounds.top, _width: 200, _height: 200, _fitToBox: true, _showSidebar: true, title: "overview" });
const portal = Doc.MakeAlias(summary);
Doc.GetProto(summary)[Doc.LayoutFieldKey(summary) + "-annotations"] = new List<Doc>(selected);
Doc.GetProto(summary).layout_portal = CollectionView.LayoutString(Doc.LayoutFieldKey(summary) + "-annotations");
@@ -559,18 +520,18 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.props.addLiveTextDocument(summary);
MarqueeOptionsMenu.Instance.fadeOut(true);
}
+
@action
background = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const newCollection = this.getCollection([], undefined, ["background"]);
this.props.addDocument(newCollection);
MarqueeOptionsMenu.Instance.fadeOut(true);
this.hideMarquee();
- setTimeout(() => this.props.selectDocuments([newCollection]), 0);
+ setTimeout(() => this.props.selectDocuments([newCollection]));
}
@undoBatch
- @action
- marqueeCommand = async (e: KeyboardEvent) => {
+ marqueeCommand = action((e: KeyboardEvent) => {
if (this._commandExecuted || (e as any).propagationIsStopped) {
return;
}
@@ -581,83 +542,30 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.delete();
e.stopPropagation();
}
- if (e.key === "c" || e.key === "b" || e.key === "t" || e.key === "s" || e.key === "S" || e.key === "p") {
+ if ("cbtsSp".indexOf(e.key) !== -1) {
this._commandExecuted = true;
e.stopPropagation();
e.preventDefault();
(e as any).propagationIsStopped = true;
- if (e.key === "c" || e.key === "t") {
- this.collection(e);
- }
- if (e.key === "s" || e.key === "S") {
- this.summary(e);
- }
- if (e.key === "b") {
- this.background(e);
- }
- if (e.key === "p") {
- this.pileup(e);
- }
+ if (e.key === "c" || e.key === "t") this.collection(e);
+ if (e.key === "s" || e.key === "S") this.summary(e);
+ if (e.key === "b") this.background(e);
+ if (e.key === "p") this.pileup(e);
this.cleanupInteractions(false);
}
if (e.key === "r" || e.key === " ") {
this._commandExecuted = true;
e.stopPropagation();
e.preventDefault();
- this.changeFreeHand(true);
+ this._lassoFreehand = !this._lassoFreehand;
}
- }
+ });
- @action
- changeFreeHand = (x: boolean) => {
- this._freeHand = !this._freeHand;
- }
- // @action
- // marqueeInkSelect(ink: Map<any, any>) {
- // let idata = new Map();
- // let centerShiftX = 0 - (this.Bounds.left + this.Bounds.width / 2); // moves each point by the offset that shifts the selection's center to the origin.
- // let centerShiftY = 0 - (this.Bounds.top + this.Bounds.height / 2);
- // ink.forEach((value: PointData, key: string, map: any) => {
- // if (InkingCanvas.IntersectStrokeRect(value, this.Bounds)) {
- // // let transform = this.props.container.props.ScreenToLocalTransform().scale(this.props.container.props.ContentScaling());
- // idata.set(key,
- // {
- // pathData: value.pathData.map(val => {
- // let tVal = this.props.getTransform().inverse().transformPoint(val.x, val.y);
- // return { x: tVal[0], y: tVal[1] };
- // // return { x: val.x + centerShiftX, y: val.y + centerShiftY }
- // }),
- // color: value.color,
- // width: value.width,
- // tool: value.tool,
- // page: -1
- // });
- // }
- // });
- // // InkSelectDecorations.Instance.SetSelected(idata);
- // return idata;
- // }
-
- // @action
- // marqueeInkDelete(ink?: Map<any, any>) {
- // // bcz: this appears to work but when you restart all the deleted strokes come back -- InkField isn't observing its changes so they aren't written to the DB.
- // // ink.forEach((value: StrokeData, key: string, map: any) =>
- // // InkingCanvas.IntersectStrokeRect(value, this.Bounds) && ink.delete(key));
-
- // if (ink) {
- // let idata = new Map();
- // ink.forEach((value: PointData, key: string, map: any) =>
- // !InkingCanvas.IntersectStrokeRect(value, this.Bounds) && idata.set(key, value));
- // this.ink = new InkField(idata);
- // }
- // }
touchesLine(r1: { left: number, top: number, width: number, height: number }) {
- for (var i = 0; i < this._pointsX.length; i++) {
- const topLeft = this.props.getTransform().transformPoint(this._pointsX[i], this._pointsY[i]);
- if (topLeft[0] > r1.left &&
- topLeft[0] < r1.left + r1.width &&
- topLeft[1] > r1.top &&
- topLeft[1] < r1.top + r1.height) {
+ for (const lassoPt of this._lassoPts) {
+ const topLeft = this.Transform.transformPoint(lassoPt[0], lassoPt[1]);
+ if (r1.left < topLeft[0] && topLeft[0] < r1.left + r1.width &&
+ r1.top < topLeft[1] && topLeft[1] < r1.top + r1.height) {
return true;
}
}
@@ -665,30 +573,22 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
boundingShape(r1: { left: number, top: number, width: number, height: number }) {
- const trueLeft = this.props.getTransform().transformPoint(Math.min(...this._pointsX), Math.min(...this._pointsY))[0];
- const trueTop = this.props.getTransform().transformPoint(Math.min(...this._pointsX), Math.min(...this._pointsY))[1];
- const trueRight = this.props.getTransform().transformPoint(Math.max(...this._pointsX), Math.max(...this._pointsY))[0];
- const trueBottom = this.props.getTransform().transformPoint(Math.max(...this._pointsX), Math.max(...this._pointsY))[1];
-
- if (r1.left > trueLeft && r1.top > trueTop && r1.left + r1.width < trueRight && r1.top + r1.height < trueBottom) {
- var hasTop = false;
- var hasLeft = false;
- var hasBottom = false;
- var hasRight = false;
- for (var i = 0; i < this._pointsX.length; i++) {
- const truePoint = this.props.getTransform().transformPoint(this._pointsX[i], this._pointsY[i]);
- if (!hasLeft && (truePoint[0] > trueLeft && truePoint[0] < r1.left) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height)) {
- hasLeft = true;
- }
- if (!hasTop && (truePoint[1] > trueTop && truePoint[1] < r1.top) && (truePoint[0] > r1.left && truePoint[0] < r1.left + r1.width)) {
- hasTop = true;
- }
- if (!hasRight && (truePoint[0] < trueRight && truePoint[0] > r1.left + r1.width) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height)) {
- hasRight = true;
- }
- if (!hasBottom && (truePoint[1] < trueBottom && truePoint[1] > r1.top + r1.height) && (truePoint[0] > r1.left && truePoint[0] < r1.left + r1.width)) {
- hasBottom = true;
- }
+ const xs = this._lassoPts.map(pair => pair[0]);
+ const ys = this._lassoPts.map(pair => pair[1]);
+ const tl = this.Transform.transformPoint(Math.min(...xs), Math.min(...ys));
+ const br = this.Transform.transformPoint(Math.max(...xs), Math.max(...ys));
+
+ if (r1.left > tl[0] && r1.top > tl[1] && r1.left + r1.width < br[0] && r1.top + r1.height < br[1]) {
+ let hasTop = false;
+ let hasLeft = false;
+ let hasBottom = false;
+ let hasRight = false;
+ for (const lassoPt of this._lassoPts) {
+ const truePoint = this.Transform.transformPoint(lassoPt[0], lassoPt[1]);
+ hasLeft = hasLeft || (truePoint[0] > tl[0] && truePoint[0] < r1.left) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height);
+ hasTop = hasTop || (truePoint[1] > tl[1] && truePoint[1] < r1.top) && (truePoint[0] > r1.left && truePoint[0] < r1.left + r1.width);
+ hasRight = hasRight || (truePoint[0] < br[0] && truePoint[0] > r1.left + r1.width) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height);
+ hasBottom = hasBottom || (truePoint[1] < br[1] && truePoint[1] > r1.top + r1.height) && (truePoint[0] > r1.left && truePoint[0] < r1.left + r1.width);
if (hasTop && hasLeft && hasBottom && hasRight) {
return true;
}
@@ -696,106 +596,40 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
return false;
}
+
marqueeSelect(selectBackgrounds: boolean = true) {
- const selRect = this.Bounds;
const selection: Doc[] = [];
- this.props.activeDocuments().filter(doc => this.props.layerProvider?.(doc) !== false && !doc.z).map(doc => {
+ const selectFunc = (doc: Doc) => {
const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- if (this._freeHand === false) {
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
- selection.push(doc);
- }
+ const bounds = { left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(layoutDoc._width), height: NumCast(layoutDoc._height) };
+ if (!this._lassoFreehand) {
+ intersectRect(bounds, this.Bounds) && selection.push(doc);
} else {
- if (this.touchesLine({ left: x, top: y, width: w, height: h }) ||
- this.boundingShape({ left: x, top: y, width: w, height: h })) {
- selection.push(doc);
- }
+ (this.touchesLine(bounds) || this.boundingShape(bounds)) && selection.push(doc);
}
- });
- if (!selection.length && selectBackgrounds) {
- this.props.activeDocuments().filter(doc => doc.z === undefined).map(doc => {
- const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
- selection.push(doc);
- }
- });
- }
- if (!selection.length) {
- const left = this._downX < this._lastX ? this._downX : this._lastX;
- const top = this._downY < this._lastY ? this._downY : this._lastY;
- const topLeft = this.props.getContainerTransform().transformPoint(left, top);
- const size = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
- const otherBounds = { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
- this.props.activeDocuments().filter(doc => doc.z !== undefined).map(doc => {
- const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- if (this._freeHand === false) {
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
- selection.push(doc);
- }
- } else {
- if (this.touchesLine({ left: x, top: y, width: w, height: h }) ||
- this.boundingShape({ left: x, top: y, width: w, height: h })) {
- selection.push(doc);
- }
- }
- });
- }
+ };
+ this.props.activeDocuments().filter(doc => this.props.layerProvider?.(doc) !== false && !doc.z).map(selectFunc);
+ if (!selection.length && selectBackgrounds) this.props.activeDocuments().filter(doc => doc.z === undefined).map(selectFunc);
+ if (!selection.length) this.props.activeDocuments().filter(doc => doc.z !== undefined).map(selectFunc);
return selection;
}
- @computed
- get marqueeDiv() {
- const p = this._visible ? this.props.getContainerTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY) : [0, 0];
- const v = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
- /**
- * @RE - The commented out span below
- * This contains the "C for collection, ..." text on marquees.
- * Commented out by syip2 when the marquee menu was added.
- */
- if (!this._freeHand) {
- return <div className="marquee" style={{
- transform: `translate(${p[0]}px, ${p[1]}px)`,
- width: `${Math.abs(v[0])}`,
- height: `${Math.abs(v[1])}`, zIndex: 2000
- }} >
- <span className="marquee-legend"></span>
- </div>;
-
- } else {
- var str: string = "";
- for (var i = 0; i < this._pointsX.length; i++) {
- const pt = this.props.getContainerTransform().transformPoint(this._pointsX[i], this._pointsY[i]);
- str += pt[0].toString();
- str += ",";
- str += pt[1].toString();
- str += (" ");
- }
-
- //hardcoded height and width.
- return <div className="marquee" style={{ zIndex: 2000 }}>
- <svg height={2000} width={2000}>
- <polyline
- points={str}
- fill="none"
- stroke="black"
- strokeWidth="1"
- strokeDasharray="3"
- />
- </svg>
- </div>;
- }
+ @computed get marqueeDiv() {
+ const cpt = this._lassoFreehand || !this._visible ? [0, 0] : [this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY];
+ const p = this.props.getContainerTransform().transformPoint(cpt[0], cpt[1]);
+ const v = this._lassoFreehand ? [0, 0] : 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]),
+ zIndex: 2000
+ }}> {this._lassoFreehand ?
+ <svg height={2000} width={2000}>
+ <polyline points={this._lassoPts.reduce((s, pt) => s + pt[0] + "," + pt[1] + " ", "")} fill="none" stroke="black" strokeWidth="1" strokeDasharray="3" />
+ </svg>
+ :
+ <span className="marquee-legend" />}
+ </div>;
}
render() {
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 2e7cdf6d0..7ce269c92 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -219,7 +219,6 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu
styleProvider={this.props.styleProvider}
LayoutTemplate={this.props.ChildLayoutTemplate}
LayoutTemplateString={this.props.ChildLayoutString}
- LibraryPath={this.props.LibraryPath}
FreezeDimensions={this.props.freezeChildDimensions}
renderDepth={this.props.renderDepth + 1}
PanelWidth={width}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 4206a5171..7700ea128 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -219,7 +219,6 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument)
styleProvider={this.props.styleProvider}
LayoutTemplate={this.props.ChildLayoutTemplate}
LayoutTemplateString={this.props.ChildLayoutString}
- LibraryPath={this.props.LibraryPath}
FreezeDimensions={this.props.freezeChildDimensions}
renderDepth={this.props.renderDepth + 1}
PanelWidth={width}