From ff791402919478bf153179a6629752f2066edc29 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 7 Dec 2020 14:03:46 -0500 Subject: fixed lists to allow multiple null-value entries & be able to edit in KeyValuePane. cleaned up a lot of stuff with animation frames and got working again. fixed previews of links to text selections to preview properly. --- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ab0c3964b..fa84e5539 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -222,14 +222,17 @@ export class CollectionFreeFormView extends CollectionSubView 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]; -- cgit v1.2.3-70-g09d2 From 8bbe55468f2ea222ed8c4dc513e65707c8835737 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 7 Dec 2020 17:15:09 -0500 Subject: got rid of LibraryPath. Fixed collectionFreeFormDocViews to use pres Effects whenever doc is selected --- src/client/views/GestureOverlay.tsx | 1 - src/client/views/MainView.tsx | 9 +-- src/client/views/OverlayView.tsx | 1 - src/client/views/Palette.tsx | 1 - src/client/views/PropertiesView.tsx | 1 - src/client/views/TemplateMenu.tsx | 1 - .../views/collections/CollectionDockingView.tsx | 2 +- .../views/collections/CollectionLinearView.tsx | 1 - .../views/collections/CollectionSchemaView.tsx | 1 - .../views/collections/CollectionStackingView.tsx | 1 - .../views/collections/CollectionTreeView.tsx | 1 - src/client/views/collections/SchemaTable.tsx | 1 - src/client/views/collections/TabDocView.tsx | 4 +- src/client/views/collections/TreeView.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 +- .../CollectionMulticolumnView.tsx | 1 - .../CollectionMultirowView.tsx | 1 - .../views/nodes/CollectionFreeFormDocumentView.tsx | 90 ++++++++++------------ .../views/nodes/ContentFittingDocumentView.tsx | 1 - src/client/views/nodes/DocHolderBox.tsx | 2 - src/client/views/nodes/DocumentView.tsx | 6 +- src/client/views/nodes/FieldView.tsx | 1 - src/client/views/nodes/FilterBox.tsx | 1 - src/client/views/nodes/KeyValuePair.tsx | 1 - src/client/views/nodes/LinkDocPreview.tsx | 1 - .../views/nodes/formattedText/DashDocView.tsx | 1 - .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- .../formattedText/FormattedTextBoxComment.tsx | 1 - .../views/nodes/formattedText/RichTextSchema.tsx | 1 - src/client/views/pdf/PDFViewer.tsx | 1 - .../views/presentationview/PresElementBox.tsx | 1 - src/mobile/AudioUpload.tsx | 1 - src/mobile/MobileInterface.tsx | 1 - 33 files changed, 51 insertions(+), 98 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 35dedf016..c60060095 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -889,7 +889,6 @@ export class GestureOverlay extends Touchable { this._flyoutWidth; sidebarScreenToLocal = () => new Transform(0, -this.topOffset, 1); mainContainerXf = () => this.sidebarScreenToLocal().translate(-this.leftOffset, 0); - addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => { + addDocTabFunc = (doc: Doc, where: string): boolean => { return where === "close" ? CollectionDockingView.CloseSplit(doc) : doc.dockingConfig ? CurrentUserUtils.openDashboard(Doc.UserDoc(), doc) : CollectionDockingView.AddSplit(doc, "right"); } @@ -308,7 +307,6 @@ export class MainView extends React.Component { { { { rootSelected={returnFalse} onCheckedClick={this.scriptField} onChildClick={this.scriptField} - LibraryPath={emptyPath} dropAction={undefined} active={returnTrue} parentActive={returnFalse} 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) { 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 { 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 a8a95bf08..45658418c 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -288,7 +288,7 @@ export class TabDocView extends React.Component { // "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] : ""; @@ -335,7 +335,6 @@ export class TabDocView extends React.Component {
{ TraceMobx(); return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) : <> 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; @@ -521,7 +521,6 @@ export class TreeView extends React.Component { Document={this.doc} DataDoc={undefined} treeViewDoc={this.props.treeView.props.Document} - LibraryPath={emptyPath} addDocument={undefined} addDocTab={this.props.addDocTab} rootSelected={returnTrue} @@ -598,7 +597,6 @@ export class TreeView extends React.Component { 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} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index fa84e5539..652b926ce 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"; @@ -982,11 +982,10 @@ export class CollectionFreeFormView extends CollectionSubView 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); + backgroundHalo = this.Document._useClusters ? returnTrue : computedFn(function (doc: Doc) { return NumCast(doc.group, -1) !== -1; }); 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 { @@ -999,7 +998,6 @@ export class CollectionFreeFormView extends CollectionSubView doc._viewTransition = doc.dataTransition = "all 1s"); - setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit" }), 1010); + setTimeout(() => docs.forEach(doc => { doc._viewTransition = undefined; doc.dataTransition = "inherit"; }), 1010); } public static setupZoom(doc: Doc, targDoc: Doc) { @@ -153,41 +153,41 @@ export class CollectionFreeFormDocumentView extends DocComponent; - if (PresBox.Instance && this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) { - const effectProps = { - left: this.layoutDoc.presEffectDirection === PresEffect.Left, - right: this.layoutDoc.presEffectDirection === PresEffect.Right, - top: this.layoutDoc.presEffectDirection === PresEffect.Top, - bottom: this.layoutDoc.presEffectDirection === PresEffect.Bottom, - opposite: true, - delay: this.layoutDoc.presTransition, - // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc, - }; - switch (this.layoutDoc.presEffect) { - case "Zoom": return ({node}); break; - case PresEffect.Fade: return ({node}); break; - case PresEffect.Flip: return ({node}); break; - case PresEffect.Rotate: return ({node}); break; - case PresEffect.Bounce: return ({node}); break; - case PresEffect.Roll: return ({node}); break; - case "LightSpeed": return ({node}); break; - case PresEffect.None: return node; break; - default: return node; break; - } - } else { - return node; + const divProps = { + ...this.props, + nudge: this.nudge, + dragDivName: "collectionFreeFormDocumentView-container", + opacity: this.opacity, + ScreenToLocalTransform: this.getTransform, + NativeHeight: this.NativeHeight, + NativeWidth: this.NativeWidth, + PanelWidth: this.panelWidth, + PanelHeight: this.panelHeight + }; + return this.props.fitToBox ? + this._contentView = r)} /> : + ; + } + @computed get effectsNodeDiv() { + const effectProps = { + left: this.layoutDoc.presEffectDirection === PresEffect.Left, + right: this.layoutDoc.presEffectDirection === PresEffect.Right, + top: this.layoutDoc.presEffectDirection === PresEffect.Top, + bottom: this.layoutDoc.presEffectDirection === PresEffect.Bottom, + opposite: true, + delay: this.layoutDoc.presTransition, + // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc, + }; + switch (this.layoutDoc.presEffect) { + case "Zoom": return ({this.freeformNodeDiv}); + case PresEffect.Fade: return ({this.freeformNodeDiv}); + case PresEffect.Flip: return ({this.freeformNodeDiv}); + case PresEffect.Rotate: return ({this.freeformNodeDiv}); + case PresEffect.Bounce: return ({this.freeformNodeDiv}); + case PresEffect.Roll: return ({this.freeformNodeDiv}); + case "LightSpeed": return ({this.freeformNodeDiv}); + case PresEffect.None: + default: return this.freeformNodeDiv; } } @@ -207,6 +207,7 @@ export class CollectionFreeFormDocumentView extends DocComponent
} - {!this.props.fitToBox ? - <>{this.freeformNodeDiv} - : this._contentView = r)} - ContainingCollectionDoc={this.props.ContainingCollectionDoc} - DataDoc={this.props.DataDoc} - ScreenToLocalTransform={this.getTransform} - NativeHeight={this.NativeHeight} - NativeWidth={this.NativeWidth} - PanelWidth={this.panelWidth} - PanelHeight={this.panelHeight} - />} + {PresBox.Instance && this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ? + this.effectsNodeDiv + : + this.freeformNodeDiv + } ; } } diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index a54479f55..74d7cb24e 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -71,7 +71,6 @@ export class ContentFittingDocumentView extends React.Component any; LayoutTemplateString?: string; LayoutTemplate?: () => Opt; - LibraryPath: Doc[]; fitToBox?: boolean; ignoreAutoHeight?: boolean; contextMenuItems?: () => { script: ScriptField, label: string }[]; @@ -90,7 +89,7 @@ export interface DocumentViewProps { parentActive: (outsideReaction: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; bringToFront: (doc: Doc, sendToBack?: boolean) => void; - addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean; + addDocTab: (doc: Doc, where: string) => boolean; pinToPres: (document: Doc) => void; backgroundHalo?: (doc: Doc) => boolean; styleProvider?: (doc: Opt, props: DocumentViewProps, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any; @@ -386,7 +385,7 @@ export class DocumentView extends DocComponent(Docu // depending on the followLinkLocation property of the source (or the link itself as a fallback); public static followLinkClick = async (linkDoc: Opt, sourceDoc: Doc, docView: { focus: DocFocusFunc, - addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean, + addDocTab: (doc: Doc, where: string) => boolean, ContainingCollectionDoc?: Doc }, shiftKey: boolean, altKey: boolean) => { const batch = UndoManager.StartBatch("follow link click"); @@ -933,7 +932,6 @@ export class DocumentView extends DocComponent(Docu backgroundHalo={this.props.backgroundHalo} dontRegisterView={this.props.dontRegisterView} fitToBox={this.props.fitToBox} - LibraryPath={this.props.LibraryPath} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} moveDocument={this.props.moveDocument} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index ed91cf47d..f2fdf7a6b 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -25,7 +25,6 @@ export interface FieldViewProps { ContainingCollectionDoc: Opt; Document: Doc; DataDoc?: Doc; - LibraryPath: Doc[]; layerProvider?: (doc: Doc, assign?: boolean) => boolean; contentsActive?: (setActive: () => boolean) => void; onClick?: () => ScriptField; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 6f0828a7d..0161f51fd 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -193,7 +193,6 @@ export class FilterBox extends ViewBoxBaseComponent { const props: FieldViewProps = { Document: this.props.doc, DataDoc: this.props.doc, - LibraryPath: [], docFilters: returnEmptyFilter, docRangeFilters: returnEmptyFilter, searchFilterDocs: returnEmptyDoclist, diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index c4bb2b8d8..5017b3a71 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -94,7 +94,6 @@ export class LinkDocPreview extends React.Component { : { Date: Tue, 8 Dec 2020 12:55:54 -0500 Subject: simplified styleProvider arguments. fixed useClusters --- src/client/views/PropertiesView.tsx | 2 +- .../views/collections/CollectionCarouselView.tsx | 2 +- src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 12 ++++++------ .../collectionFreeForm/CollectionFreeFormView.tsx | 7 ++++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 6 +++--- src/client/views/nodes/DocHolderBox.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 21 +++++++++------------ src/client/views/nodes/FieldView.tsx | 2 +- src/client/views/nodes/FontIconBox.tsx | 2 +- src/client/views/nodes/LinkBox.tsx | 2 +- src/client/views/nodes/LinkDocPreview.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- .../views/presentationview/PresElementBox.tsx | 2 +- 15 files changed, 33 insertions(+), 35 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 9f1b8dad3..08394cd97 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -37,7 +37,7 @@ const _global = (window /* browser */ || global /* node */) as any; interface PropertiesViewProps { width: number; height: number; - styleProvider?: (doc: Opt, props: Opt, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any; + styleProvider?: (doc: Opt, props: Opt, property: string) => any; } @observer 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)
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ac01536c9..681584cc5 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -215,7 +215,7 @@ export class CollectionTreeView extends CollectionSubView {this.showIsTagged()} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 45658418c..e1fd47592 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -434,7 +434,7 @@ export class TabDocView extends React.Component { // // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // - public static styleProvider = (doc: Opt, props: DocumentViewProps | undefined, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean): any => { + public static styleProvider = (doc: Opt, props: DocumentViewProps | undefined, property: string): any => { switch (property) { case "backgroundColor": { if (Doc.UserDoc().renderStyle === "comic") return undefined; @@ -456,11 +456,11 @@ export class TabDocView extends React.Component { 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 : @@ -471,7 +471,7 @@ export class TabDocView extends React.Component { 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"; @@ -488,7 +488,7 @@ export class TabDocView extends React.Component { } } } - public static miniStyleProvider = (doc: Opt, props: Opt, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean): any => { + public static miniStyleProvider = (doc: Opt, props: Opt, property: string): any => { if (doc) { switch (property) { case "docContents": @@ -498,7 +498,7 @@ export class TabDocView extends React.Component { return
; default: if (property.startsWith("pointerEvents")) return "none"; - return TabDocView.styleProvider(doc, props, property, layerProvider); + return TabDocView.styleProvider(doc, props, property); } } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 652b926ce..136600164 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -396,8 +396,8 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, 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, props: Opt, 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) { @@ -985,7 +985,8 @@ export class CollectionFreeFormView extends CollectionSubView this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); - backgroundHalo = this.Document._useClusters ? returnTrue : computedFn(function (doc: Doc) { return NumCast(doc.group, -1) !== -1; }); + // @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 { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 51ed49df3..b4b887617 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -142,11 +142,11 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeHeight; @computed get pointerEvents() { if (this.props.pointerEvents === "none") return "none"; - return this.props.styleProvider?.(this.Document, this.props, !this._contentView?.docView?.isSelected() ? "pointerEvents:selected" : "pointerEvents", this.props.layerProvider); + return this.props.styleProvider?.(this.Document, this.props, !this._contentView?.docView?.isSelected() ? "pointerEvents:selected" : "pointerEvents"); } render() { TraceMobx(); - const backgroundColor = this.props.styleProvider?.(this.Document, this.props, "backgroundColor", this.props.layerProvider); + const backgroundColor = this.props.styleProvider?.(this.Document, this.props, "backgroundColor"); const borderRounding = StrCast(Doc.Layout(this.layoutDoc).borderRounding) || StrCast(this.layoutDoc.borderRounding) || StrCast(this.Document.borderRounding) || undefined; const divProps = { @@ -165,7 +165,7 @@ export class CollectionFreeFormDocumentView extends DocComponent boolean; pinToPres: (document: Doc) => void; backgroundHalo?: (doc: Doc) => boolean; - styleProvider?: (doc: Opt, props: DocumentViewProps, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any; + styleProvider?: (doc: Opt, props: DocumentViewProps, property: string) => any; forceHideLinkButton?: () => boolean; opacity?: () => number | undefined; ChromeHeight?: () => number; @@ -1062,7 +1062,7 @@ export class DocumentView extends DocComponent(Docu } @computed get pointerEvents() { if (this.props.pointerEvents === "none") return "none"; - return this.props.styleProvider?.(this.Document, this.props, this.isSelected() ? "pointerEvents:selected" : "pointerEvents", this.props.layerProvider); + return this.props.styleProvider?.(this.Document, this.props, this.isSelected() ? "pointerEvents:selected" : "pointerEvents"); } @undoBatch @action @@ -1086,8 +1086,8 @@ export class DocumentView extends DocComponent(Docu TraceMobx(); if (!(this.props.Document instanceof Doc)) return (null); if (GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate) return (null); - if (this.props.styleProvider?.(this.layoutDoc, this.props, "hidden", this.props.layerProvider)) return null; - const backgroundColor = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor", this.props.layerProvider); + if (this.props.styleProvider?.(this.layoutDoc, this.props, "hidden")) return null; + const backgroundColor = this.props.styleProvider?.(this.layoutDoc, this.props, "backgroundColor"); const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null))); const finalOpacity = this.props.opacity ? this.props.opacity() : opacity; const finalColor = this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor; @@ -1101,14 +1101,14 @@ export class DocumentView extends DocComponent(Docu let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear && this.props.Document.type !== DocumentType.INK; highlighting = highlighting && this.props.focus !== emptyFunction && this.layoutDoc.title !== "[pres element template]"; // bcz: hack to turn off highlighting onsidebar panel documents. need to flag a document as not highlightable in a more direct way const topmost = this.topMost ? "-topmost" : ""; - return this.props.styleProvider?.(this.rootDoc, this.props, "docContents", this.props.layerProvider) ??
!SnappingManager.GetIsDragging() && Doc.BrushDoc(this.props.Document))} onPointerLeave={action(e => { let entered = false; - for (let child = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y); child; child = child.parentElement) { + for (let child = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y); !entered && child; child = child.parentElement) { entered = entered || child === this.ContentDiv; } !entered && Doc.UnBrushDoc(this.props.Document); @@ -1131,12 +1131,9 @@ export class DocumentView extends DocComponent(Docu fontFamily: StrCast(this.Document._fontFamily, "inherit"), fontSize: !this.props.treeViewDoc ? Cast(this.Document._fontSize, "string", null) : undefined, }}> - {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <> - {this.innards} -
- : - this.innards} - {!this.props.treeViewDoc && this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations", this.props.layerProvider) || (null)} + {this.innards} + {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
: (null)} + {!this.props.treeViewDoc && this.props.styleProvider?.(this.rootDoc, this.props, this.isSelected() ? "decorations:selected" : "decorations") || (null)}
; } render() { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index f2fdf7a6b..5cd752fdb 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -42,7 +42,7 @@ export interface FieldViewProps { pinToPres: (document: Doc) => void; removeDocument?: (document: Doc | Doc[]) => boolean; moveDocument?: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; - styleProvider?: (document: Opt, props: Opt, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any; + styleProvider?: (document: Opt, props: Opt, property: string) => any; ScreenToLocalTransform: () => Transform; bringToFront: (doc: Doc, sendToBack?: boolean) => void; parentActive: (outsideReaction: boolean) => boolean; diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index c9ee4126e..a1bb0604e 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -61,7 +61,7 @@ export class FontIconBox extends DocComponent( render() { const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); const color = StrCast(this.layoutDoc.color, this._foregroundColor); - const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, "backgroundColor", this.props.layerProvider); + const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, "backgroundColor"); const shape = StrCast(this.layoutDoc.iconShape, label ? "round" : "circle"); const icon = StrCast(this.dataDoc.icon, "user") as any; const presSize = shape === 'round' ? 25 : 30; diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 1b181cef1..bf19457da 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -17,7 +17,7 @@ export class LinkBox extends ViewBoxBaseComponent( public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkBox, fieldKey); } render() { return
+ style={{ background: this.props.styleProvider?.(this.props.Document, this.props, "backgroundColor") }} > , props: Opt, property: string, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => any; + styleProvider?: (doc: Opt, props: Opt, property: string) => any; addDocTab: (document: Doc, where: string) => boolean; location: number[]; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 59909cea1..22e3ac1e9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1598,7 +1598,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const annotated = DocListCast(this.dataDoc[this.annotationKey]).filter(d => d?.author).length; return !this.props.isSelected() && !(annotated && !this.sidebarWidth()) ? (null) :
; } diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 9742faa2b..37752d6ee 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -322,7 +322,7 @@ export class PresElementBox extends ViewBoxBaseComponent} {miniView ? (null) :
-- cgit v1.2.3-70-g09d2 From 4473461d56720e8bdfd540fa67098ebccb29899c Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 8 Dec 2020 15:51:20 -0500 Subject: cleaned up MarqueeView code a bit. --- .../collections/collectionFreeForm/MarqueeView.tsx | 394 ++++++--------------- 1 file changed, 114 insertions(+), 280 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index eb781ed0a..ac82f60e1 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 { + 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) { this.props.Document.ink = value; } componentDidMount() { this.props.setPreviewCursor?.(this.setPreviewCursor); @@ -64,11 +73,9 @@ export class MarqueeView extends React.Component 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 { this._downX = this._lastX = e.clientX; @@ -210,13 +218,12 @@ export class MarqueeView extends React.Component { 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 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 { 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 { - 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 { 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(); - 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 { - 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(selected); Doc.GetProto(summary).layout_portal = CollectionView.LayoutString(Doc.LayoutFieldKey(summary) + "-annotations"); @@ -559,18 +520,18 @@ export class MarqueeView extends React.Component { 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 { - this._freeHand = !this._freeHand; - } - // @action - // marqueeInkSelect(ink: Map) { - // 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) { - // // 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 (var i = 0; i < this._lassoPts.length; i++) { + const topLeft = this.Transform.transformPoint(this._lassoPts[i][0], this._lassoPts[i][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 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 (let i = 0; i < this._lassoPts.length; i++) { + const truePoint = this.Transform.transformPoint(this._lassoPts[i][0], this._lassoPts[i][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 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
- -
; - - } 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
- - - -
; - } + @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
{this._lassoFreehand ? + + s + pt[0] + "," + pt[1] + " ", "")} fill="none" stroke="black" strokeWidth="1" strokeDasharray="3" /> + + : + } +
; } render() { -- cgit v1.2.3-70-g09d2 From 7a09a2e77af9d236265cd975f24a38cda1735493 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 9 Dec 2020 13:59:31 -0500 Subject: final improvements to audio waveform rendering. --- .../collections/collectionFreeForm/MarqueeView.tsx | 6 +- src/client/views/nodes/AudioBox.tsx | 83 +++++++++------------- 2 files changed, 38 insertions(+), 51 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index ac82f60e1..df3d3106e 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -559,10 +559,11 @@ export class MarqueeView extends React.Component tl[0] && truePoint[0] < r1.left) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height); diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 785bb5ce8..c89e21312 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -1,34 +1,34 @@ import React = require("react"); -import { FieldViewProps, FieldView } from './FieldView'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import axios from "axios"; +import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import "./AudioBox.scss"; -import { Cast, DateCast, NumCast, FieldValue, ScriptCast } from "../../../fields/Types"; -import { AudioField, nullAudio } from "../../../fields/URLField"; -import { ViewBoxAnnotatableComponent } from "../DocComponent"; -import { makeInterface, createSchema, listSpec } from "../../../fields/Schema"; -import { documentSchema } from "../../../fields/documentSchemas"; -import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero, formatTime, setupMoveUpEvents } from "../../../Utils"; -import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace, toJS } from "mobx"; +import Waveform from "react-audio-waveform"; import { DateField } from "../../../fields/DateField"; -import { SelectionManager } from "../../util/SelectionManager"; import { Doc, DocListCast, Opt } from "../../../fields/Doc"; -import { ContextMenuProps } from "../ContextMenuItem"; -import { ContextMenu } from "../ContextMenu"; +import { documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { DocumentView, DocumentViewProps } from "./DocumentView"; -import { Docs, DocUtils } from "../../documents/Documents"; +import { List } from "../../../fields/List"; +import { createSchema, listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; +import { Cast, DateCast, NumCast } from "../../../fields/Types"; +import { AudioField, nullAudio } from "../../../fields/URLField"; +import { emptyFunction, formatTime, returnFalse, returnOne, returnTrue, setupMoveUpEvents, Utils, numberRange } from "../../../Utils"; +import { Docs, DocUtils } from "../../documents/Documents"; import { Networking } from "../../Network"; -import { LinkAnchorBox } from "./LinkAnchorBox"; -import { List } from "../../../fields/List"; +import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { Scripting } from "../../util/Scripting"; -import Waveform from "react-audio-waveform"; -import axios from "axios"; +import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; -import { CurrentUserUtils } from "../../util/CurrentUserUtils"; -import { LinkDocPreview } from "./LinkDocPreview"; +import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; +import { ViewBoxAnnotatableComponent } from "../DocComponent"; +import "./AudioBox.scss"; +import { DocumentView, DocumentViewProps } from "./DocumentView"; +import { FieldView, FieldViewProps } from './FieldView'; import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment"; +import { LinkAnchorBox } from "./LinkAnchorBox"; +import { LinkDocPreview } from "./LinkDocPreview"; declare class MediaRecorder { // whatever MediaRecorder has @@ -43,6 +43,7 @@ const AudioDocument = makeInterface(documentSchema, audioSchema); export class AudioBox extends ViewBoxAnnotatableComponent(AudioDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(AudioBox, fieldKey); } public static Enabled = false; + public static NUMBER_OF_BUCKETS = 100; static Instance: AudioBox; static RangeScript: ScriptField; @@ -508,7 +509,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.buckets()); + !audioBuckets.length && setTimeout(() => this.createWaveformBuckets()); return ; } // decodes the audio file into peaks for generating the waveform - @action - buckets = async () => { - const audioCtx = new (window.AudioContext)(); - + createWaveformBuckets = async () => { axios({ url: this.path, responseType: "arraybuffer" }) - .then(response => { - const audioData = response.data; - - audioCtx.decodeAudioData(audioData, action(buffer => { + .then(response => (new (window.AudioContext)()).decodeAudioData(response.data, + action(buffer => { const decodedAudioData = buffer.getChannelData(0); - const NUMBER_OF_BUCKETS = 100; - const bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS); - let _buckets: number[] = []; - for (let i = 0; i < NUMBER_OF_BUCKETS; i++) { - const startingPoint = i * bucketDataSize; - const endingPoint = i * bucketDataSize + bucketDataSize; - let max = 0; - for (let j = startingPoint; j < endingPoint; j++) { - if (decodedAudioData[j] > max) { - max = decodedAudioData[j]; - } - } - const size = Math.abs(max); - _buckets.push(size / 2); - } - this.dataDoc.audioBuckets = new List(_buckets); - })); - }); + const bucketDataSize = Math.floor(decodedAudioData.length / AudioBox.NUMBER_OF_BUCKETS); + const brange = Array.from(Array(bucketDataSize)); + this.dataDoc.audioBuckets = new List( + numberRange(AudioBox.NUMBER_OF_BUCKETS).map(i => + brange.reduce((p, x, j) => Math.abs(Math.max(p, decodedAudioData[i * bucketDataSize + j])), 0) / 2)); + })) + ); } rangeScript = () => AudioBox.RangeScript; -- cgit v1.2.3-70-g09d2 From 3412313dcde569f1f23616fa5e8a92c3985e0449 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 9 Dec 2020 14:25:40 -0500 Subject: from last - fixed warnings. --- .../views/collections/collectionFreeForm/MarqueeView.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index df3d3106e..a963b9158 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -562,9 +562,8 @@ export class MarqueeView extends React.Component 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); -- cgit v1.2.3-70-g09d2