diff options
Diffstat (limited to 'src/client/views/collections')
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} |
