From 175d3fca55bd1838203d67884bb5206597e68b60 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 20 Nov 2020 19:23:02 -0500 Subject: added a preliminary Layer mechanism. changed documentDecrations to not go out of the mainDocument area. changed parentActive to work "recursively" through stacks of background documents. --- .../views/nodes/CollectionFreeFormDocumentView.tsx | 24 +++++++++--- .../views/nodes/ContentFittingDocumentView.tsx | 2 +- src/client/views/nodes/DocHolderBox.tsx | 2 +- src/client/views/nodes/DocumentContentsView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 45 ++++++++++++++-------- src/client/views/nodes/FieldView.tsx | 4 +- src/client/views/nodes/FilterBox.tsx | 1 + src/client/views/nodes/FontIconBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 3 +- src/client/views/nodes/KeyValuePair.tsx | 1 + src/client/views/nodes/LinkAnchorBox.tsx | 2 +- src/client/views/nodes/LinkBox.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 8 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 16 files changed, 67 insertions(+), 37 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index c87239ee9..e6cb160dd 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,4 +1,4 @@ -import { computed, IReactionDisposer, observable, reaction, trace } from "mobx"; +import { computed, IReactionDisposer, observable, reaction, trace, action } from "mobx"; import { observer } from "mobx-react"; import { Doc, HeightSym, WidthSym } from "../../../fields/Doc"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; @@ -18,10 +18,13 @@ import { DocumentType } from "../../documents/DocumentTypes"; import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal'; import { PresBox, PresEffect } from "./PresBox"; import { InkingStroke } from "../InkingStroke"; +import { SnappingManager } from "../../util/SnappingManager"; +import { InkTool } from "../../../fields/InkField"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; sizeProvider?: (doc: Doc, replica: string) => { width: number, height: number } | undefined; + layerProvider?: (doc: Doc, assign?: boolean) => boolean; zIndex?: number; highlight?: boolean; jitterRotation: number; @@ -33,6 +36,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { @observer export class CollectionFreeFormDocumentView extends DocComponent(Document) { @observable _animPos: number[] | undefined = undefined; + @observable _contentView: ContentFittingDocumentView | undefined | null; random(min: number, max: number) { // min should not be equal to max const mseed = Math.abs(this.X * this.Y); const seed = (mseed * 9301 + 49297) % 233280; @@ -206,6 +210,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.Opacity; NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; + @computed get pointerEvents() { + if (this.props.pointerEvents === "none") return "none"; + const layer = this.props.layerProvider?.(this.Document); + if (layer === false && !this._contentView?.docView?.isSelected() && !SnappingManager.GetIsDragging()) return "none"; + if (this.Document.type === DocumentType.INK && Doc.GetSelectedTool() !== InkTool.None) return "none"; + if (layer === true) return "all"; + return this.props.pointerEvents; + } render() { TraceMobx(); - const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document, this.props.renderDepth); + const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document, this.props.renderDepth, this.props.layerProvider); const borderRounding = StrCast(Doc.Layout(this.layoutDoc).borderRounding) || StrCast(this.layoutDoc.borderRounding) || StrCast(this.Document.borderRounding) || undefined; return
{Doc.UserDoc().renderStyle !== "comic" ? (null) : @@ -280,6 +293,7 @@ export class CollectionFreeFormDocumentView extends DocComponent{this.freeformNodeDiv} : this._contentView = r)} ContainingCollectionDoc={this.props.ContainingCollectionDoc} DataDoc={this.props.DataDoc} ScreenToLocalTransform={this.getTransform} diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index d5b91f4a7..d963369f8 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -45,7 +45,7 @@ export class ContentFittingDocumentView extends React.Component this.props.ScreenToLocalTransform(). - translate(this.props.dontCenter?.includes("x") ? 0 : -this.centeringOffset, this.props.dontCenter?.includes("y") ? 0 : -this.centeringYOffset); + translate(this.props.dontCenter?.includes("x") ? 0 : -this.centeringOffset, this.props.dontCenter?.includes("y") ? 0 : -this.centeringYOffset) private get centeringOffset() { return this.nativeWidth && !this.props.Document._fitWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } private get centeringYOffset() { return Math.abs(this.centeringOffset) < 0.001 && this.nativeHeight ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx index dd254ae93..b5e0df659 100644 --- a/src/client/views/nodes/DocHolderBox.tsx +++ b/src/client/views/nodes/DocHolderBox.tsx @@ -184,7 +184,7 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent, onInput: Opt): JsxBindings { const list = { - ...OmitKeys(this.props, ['parentActive', 'NativeWidth', 'NativeHeight'], "", (obj: any) => obj.active = this.props.parentActive).omit, + ...OmitKeys(this.props, ['NativeWidth', 'NativeHeight'], "", (obj: any) => obj.active = this.props.parentActive).omit, RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc, Document: this.layoutDoc, DataDoc: this.dataDoc, diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f6262310f..9b26094b3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -41,6 +41,7 @@ import { LinkDescriptionPopup } from './LinkDescriptionPopup'; import { RadialMenu } from './RadialMenu'; import { TaskCompletionBox } from './TaskCompletedBox'; import React = require("react"); +import { List } from '../../../fields/List'; export type DocAfterFocusFunc = (notFocused: boolean) => boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; @@ -57,6 +58,7 @@ export interface DocumentViewProps { NativeHeight?: () => number; Document: Doc; DataDoc?: Doc; + layerProvider?: (doc: Doc, assign?: boolean) => boolean; getView?: (view: DocumentView) => any; LayoutTemplateString?: string; LayoutTemplate?: () => Opt; @@ -91,7 +93,7 @@ export interface DocumentViewProps { addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean; pinToPres: (document: Doc) => void; backgroundHalo?: () => boolean; - backgroundColor?: (doc: Opt, renderDepth: number) => string | undefined; + backgroundColor?: (doc: Opt, renderDepth: number, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => string | undefined; forcedBackgroundColor?: (doc: Doc) => string | undefined; opacity?: () => number | undefined; ChromeHeight?: () => number; @@ -313,7 +315,7 @@ export class DocumentView extends DocComponent(Docu (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { let stopPropagate = true; let preventDefault = true; - !this.props.Document._isBackground && (this.rootDoc._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : this.rootDoc._raiseWhenDragged) && this.props.bringToFront(this.rootDoc); + !Cast(this.props.Document.layers, listSpec("string"), []).includes("background") && (this.rootDoc._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : this.rootDoc._raiseWhenDragged) && this.props.bringToFront(this.rootDoc); if (this._doubleTap && ((this.props.renderDepth && this.props.Document.type !== DocumentType.FONTICON) || this.onDoubleClickHandler)) {// && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click if (this._timeout) { clearTimeout(this._timeout); @@ -746,9 +748,14 @@ export class DocumentView extends DocComponent(Docu @undoBatch @action toggleBackground = () => { - this.Document._isBackground = (this.Document._isBackground ? undefined : true); - this.Document._overflow = this.Document._isBackground ? "visible" : undefined; - if (this.Document._isBackground) { + const layers = Cast(this.Document.layers, listSpec("string"), []); + if (!layers.includes("background")) { + if (!layers.length) this.Document.layers = new List(["background"]); + else layers.push("background"); + } + else layers.splice(layers.indexOf("background"), 1); + this.Document._overflow = !layers.includes("background") ? "visible" : undefined; + if (!layers.includes("background")) { this.props.bringToFront(this.props.Document, true); const wid = this.Document[WidthSym](); // change the nativewidth and height if the background is to be a collection that aggregates stuff that is added to it. const hgt = this.Document[HeightSym](); @@ -920,7 +927,8 @@ export class DocumentView extends DocComponent(Docu childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling()); @computed.struct get linkOffset() { return this.topMost ? [0, undefined, undefined, 10] : [-15, undefined, undefined, -20]; } @observable contentsActive: () => boolean = returnFalse; - @action setContentsActive = (setActive: () => boolean) => { this.contentsActive = setActive; } + @action setContentsActive = (setActive: () => boolean) => this.contentsActive = setActive; + parentActive = (outsideReaction: boolean) => this.props.layerProvider?.(this.layoutDoc) === false ? this.props.parentActive(outsideReaction) : false; @computed get contents() { TraceMobx(); return (
@@ -935,6 +943,7 @@ export class DocumentView extends DocComponent(Docu NativeHeight={this.NativeHeight} Document={this.props.Document} DataDoc={this.props.DataDoc} + layerProvider={this.props.layerProvider} LayoutTemplateString={this.props.LayoutTemplateString} LayoutTemplate={this.props.LayoutTemplate} makeLink={this.makeLink} @@ -952,7 +961,7 @@ export class DocumentView extends DocComponent(Docu PanelHeight={this.props.PanelHeight} ignoreAutoHeight={this.props.ignoreAutoHeight} focus={this.props.focus} - parentActive={this.props.parentActive} + parentActive={this.parentActive} whenActiveChanged={this.props.whenActiveChanged} bringToFront={this.props.bringToFront} addDocTab={this.props.addDocTab} @@ -1072,10 +1081,13 @@ export class DocumentView extends DocComponent(Docu {captionView}
; } - @computed get ignorePointerEvents() { - return this.props.pointerEvents === "none" || - (this.Document._isBackground && !this.isSelected() && !SnappingManager.GetIsDragging()) || - (this.Document.type === DocumentType.INK && Doc.GetSelectedTool() !== InkTool.None); + @computed get pointerEvents() { + if (this.props.pointerEvents === "none") return "none"; + const layer = this.props.layerProvider?.(this.Document); + if (layer === false && !this.isSelected() && !SnappingManager.GetIsDragging()) return "none"; + if (this.Document.type === DocumentType.INK && Doc.GetSelectedTool() !== InkTool.None) return "none"; + if (layer === true) return "all"; + return undefined; } @undoBatch @action @@ -1096,11 +1108,12 @@ export class DocumentView extends DocComponent(Docu }); renderLock() { - return (this.Document._isBackground !== undefined || this.isSelected(false)) && - ((this.Document.type === DocumentType.COL && this.Document._viewType !== CollectionViewType.Pile) || this.Document.type === DocumentType.IMG || this.Document.type === DocumentType.INK) && + const isBackground = Cast(this.Document.layers, listSpec("string"), []).includes("background"); + return (isBackground || this.isSelected(false)) && + ((this.Document.type === DocumentType.COL && this.Document._viewType !== CollectionViewType.Pile) || this.Document.type === DocumentType.RTF || this.Document.type === DocumentType.IMG || this.Document.type === DocumentType.INK) && this.props.renderDepth > 0 && !this.props.treeViewDoc ?
- +
: (null); } @@ -1110,7 +1123,7 @@ export class DocumentView extends DocComponent(Docu if (!(this.props.Document instanceof Doc)) return (null); if (GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate) return (null); if (this.props.Document.hidden) return (null); - const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : this.props.forcedBackgroundColor?.(this.Document) || StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document, this.props.renderDepth); + const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : this.props.forcedBackgroundColor?.(this.Document) || this.props.backgroundColor?.(this.layoutDoc, this.props.renderDepth, this.props.layerProvider); 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; @@ -1146,7 +1159,7 @@ export class DocumentView extends DocComponent(Docu transformOrigin: this._animateScalingTo ? "center center" : undefined, transform: this._animateScalingTo ? `scale(${this._animateScalingTo})` : undefined, transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : `transform 0.5s ease-${this._animateScalingTo < 1 ? "in" : "out"}`, - pointerEvents: this.ignorePointerEvents ? "none" : undefined, + pointerEvents: this.pointerEvents, color: StrCast(this.layoutDoc.color, "inherit"), outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px", border: highlighting && borderRounding && highlightStyles[fullDegree] === "dashed" ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined, diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index d7ff051cf..b8f2d5d6f 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -26,6 +26,7 @@ export interface FieldViewProps { Document: Doc; DataDoc?: Doc; LibraryPath: Doc[]; + layerProvider?: (doc: Doc, assign?: boolean) => boolean; contentsActive?: (setActive: () => boolean) => void; onClick?: () => ScriptField; dropAction: dropActionType; @@ -42,9 +43,10 @@ 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; - backgroundColor?: (document: Opt, renderDepth: number) => string | undefined; + backgroundColor?: (document: Opt, renderDepth: number, layerProvider?: (doc: Doc, assign?: boolean) => boolean) => string | undefined; ScreenToLocalTransform: () => Transform; bringToFront: (doc: Doc, sendToBack?: boolean) => void; + parentActive: (outsideReaction: boolean) => boolean; active: (outsideReaction?: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; LayoutTemplateString?: string; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 6f01e5916..24cd6f21f 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -204,6 +204,7 @@ export class FilterBox extends ViewBoxBaseComponent( render() { const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); const color = StrCast(this.layoutDoc.color, this._foregroundColor); - const backgroundColor = StrCast(this.layoutDoc._backgroundColor, StrCast(this.rootDoc.backgroundColor, this.props.backgroundColor?.(this.rootDoc, this.props.renderDepth))); + const backgroundColor = StrCast(this.layoutDoc._backgroundColor, StrCast(this.rootDoc.backgroundColor, this.props.backgroundColor?.(this.rootDoc, this.props.renderDepth, this.props.layerProvider))); 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/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 88dc3b241..1c1a13061 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -161,7 +161,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent { this.layoutDoc._isBackground = true; this.props.bringToFront?.(this.rootDoc); }, icon: "expand-arrows-alt" }); if (!Doc.UserDoc().noviceMode) { funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" }); funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" }); @@ -411,7 +410,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { dropAction: "alias", bringToFront: emptyFunction, renderDepth: 1, + parentActive: returnFalse, active: returnFalse, whenActiveChanged: emptyFunction, ScreenToLocalTransform: Transform.Identity, diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index ec8c43ab4..7ce9abf27 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -92,7 +92,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent { const alias = Doc.MakeAlias(Cast(this.layoutDoc[this.fieldKey], Doc, null)); alias.isLinkButton = undefined; - alias._isBackground = undefined; + alias.layers = undefined; alias.layoutKey = "layout"; this.props.addDocTab(alias, "add:right"); } diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 64ae1051b..f80eb8f79 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.backgroundColor?.(this.props.Document, this.props.renderDepth, this.props.layerProvider) }} > removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; - active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground) && + active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && this.props.layerProvider?.(this.layoutDoc) !== false) && (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) /** diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index bc69a3954..8ce76a347 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -393,7 +393,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 80e2d3ce2..ab97f9f7e 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -461,7 +461,7 @@ export class WebBox extends ViewBoxAnnotatableComponent {!frozen ? (null) : -
@@ -663,7 +663,7 @@ export class WebBox extends ViewBoxAnnotatableComponent @@ -671,7 +671,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { const target = this._outerRef.current; @@ -693,7 +693,7 @@ export class WebBox extends ViewBoxAnnotatableComponent
FormattedTextBoxComment.Hide()); const minimal = this.props.ignoreAutoHeight; const margins = NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0); -- cgit v1.2.3-70-g09d2