From 542d272921666ad6ffbef8a028d8204e5c357791 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 21 Aug 2019 11:51:55 -0400 Subject: added pinning tree items to presentation. fixed float doc opacity when = 0 --- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index ee596c841..7631ecc6c 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -83,7 +83,7 @@ export class CollectionFreeFormDocumentView extends DocComponent Date: Thu, 29 Aug 2019 14:50:22 -0400 Subject: changed linkFollowBox creation approach. fixed target contexts to add link default. --- src/client/views/MainView.tsx | 8 +- src/client/views/OverlayView.tsx | 108 +++++++++++---------- src/client/views/linking/LinkFollowBox.tsx | 20 ++-- src/client/views/linking/LinkMenuItem.tsx | 18 ++-- .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/FormattedTextBoxComment.tsx | 8 +- .../authentication/models/current_user_utils.ts | 3 + 7 files changed, 78 insertions(+), 88 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 1fc8d1397..b64986084 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -438,13 +438,7 @@ export class MainView extends React.Component { if (LinkFollowBox.Instance) { let dvs = DocumentManager.Instance.getDocumentViews(LinkFollowBox.Instance.props.Document); // if it already exisits, close it - if (dvs.length > 0 && shouldClose) LinkFollowBox.Instance.close(); - // open it if not - else Doc.AddDocToList(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc, "data", LinkFollowBox.Instance.props.Document); - } - else { - let doc = Docs.Create.LinkFollowBoxDocument({ x: this.flyoutWidth, y: 20, width: 500, height: 370, title: "Link Follower" }); - Doc.AddDocToList(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc, "data", doc); + LinkFollowBox.Instance.props.Document.isMinimized = (dvs.length > 0 && shouldClose); } } diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index a1afe651c..54ab8696e 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import { observer } from "mobx-react"; -import { observable, action } from "mobx"; +import { observable, action, trace, computed } from "mobx"; import { Utils, emptyFunction, returnOne, returnTrue, returnEmptyString, returnZero, returnFalse } from "../../Utils"; import './OverlayView.scss'; @@ -140,61 +140,65 @@ export class OverlayView extends React.Component { return remove; } + @computed get overlayDocs() { + return CurrentUserUtils.UserDocument.overlays instanceof Doc && DocListCast(CurrentUserUtils.UserDocument.overlays.data).map(d => { + let offsetx = 0, offsety = 0; + let onPointerMove = action((e: PointerEvent) => { + if (e.buttons === 1) { + d.x = e.clientX + offsetx; + d.y = e.clientY + offsety; + e.stopPropagation(); + e.preventDefault(); + } + }); + let onPointerUp = action((e: PointerEvent) => { + document.removeEventListener("pointermove", onPointerMove); + document.removeEventListener("pointerup", onPointerUp); + e.stopPropagation(); + e.preventDefault(); + }); + + let onPointerDown = (e: React.PointerEvent) => { + offsetx = NumCast(d.x) - e.clientX; + offsety = NumCast(d.y) - e.clientY; + e.stopPropagation(); + e.preventDefault(); + document.addEventListener("pointermove", onPointerMove); + document.addEventListener("pointerup", onPointerUp); + }; + return
+ +
; + }) + } + render() { return (
{this._elements} - {CurrentUserUtils.UserDocument.overlays instanceof Doc && DocListCast(CurrentUserUtils.UserDocument.overlays.data).map(d => { - let offsetx = 0, offsety = 0; - let onPointerMove = action((e: PointerEvent) => { - if (e.buttons === 1) { - d.x = e.clientX + offsetx; - d.y = e.clientY + offsety; - e.stopPropagation(); - e.preventDefault(); - } - }); - let onPointerUp = action((e: PointerEvent) => { - document.removeEventListener("pointermove", onPointerMove); - document.removeEventListener("pointerup", onPointerUp); - e.stopPropagation(); - e.preventDefault(); - }); - - let onPointerDown = (e: React.PointerEvent) => { - offsetx = NumCast(d.x) - e.clientX; - offsety = NumCast(d.y) - e.clientY; - e.stopPropagation(); - e.preventDefault(); - document.addEventListener("pointermove", onPointerMove); - document.addEventListener("pointerup", onPointerUp); - } - return
- -
- })} + {this.overlayDocs}
); } diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx index 07f07f72a..74663f9af 100644 --- a/src/client/views/linking/LinkFollowBox.tsx +++ b/src/client/views/linking/LinkFollowBox.tsx @@ -1,4 +1,4 @@ -import { observable, computed, action, trace, ObservableMap, runInAction, reaction, IReactionDisposer } from "mobx"; +import { observable, computed, action, runInAction, reaction, IReactionDisposer } from "mobx"; import React = require("react"); import { observer } from "mobx-react"; import { FieldViewProps, FieldView } from "../nodes/FieldView"; @@ -15,8 +15,6 @@ import { SearchUtil } from "../../util/SearchUtil"; import { Id } from "../../../new_fields/FieldSymbols"; import { listSpec } from "../../../new_fields/Schema"; import { DocServer } from "../../DocServer"; -import { RefField } from "../../../new_fields/RefField"; -import { Docs } from "../../documents/Documents"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; @@ -126,9 +124,11 @@ export class LinkFollowBox extends React.Component { const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs))); allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); docs.forEach(doc => map.delete(doc)); - runInAction(() => { + runInAction(async () => { this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: dest })); this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target })); + let tcontext = LinkFollowBox.linkDoc && (await Cast(LinkFollowBox.linkDoc.targetContext, Doc)) as Doc; + runInAction(() => tcontext && this._docs.splice(0, 0, { col: tcontext, target: dest })); }); } } @@ -268,7 +268,7 @@ export class LinkFollowBox extends React.Component { let fullScreenAlias = Doc.MakeAlias(LinkFollowBox.destinationDoc); // THIS IS EMPTY FUNCTION this.props.addDocTab(fullScreenAlias, undefined, "inTab"); - console.log(this.props.addDocTab) + console.log(this.props.addDocTab); this.highlightDoc(); SelectionManager.DeselectAll(); @@ -348,7 +348,7 @@ export class LinkFollowBox extends React.Component { } else if (this.selectedMode === FollowModes.OPENTAB) { if (notOpenInContext) this.openLinkTab(); - else this.selectedContext && this.openLinkColTab({ context: this.selectedContext, shouldZoom: shouldZoom }) + else this.selectedContext && this.openLinkColTab({ context: this.selectedContext, shouldZoom: shouldZoom }); } else if (this.selectedMode === FollowModes.PAN) { this.jumpToLink({ shouldZoom: shouldZoom }); @@ -555,19 +555,13 @@ export class LinkFollowBox extends React.Component { return null; } - async close() { - let res = await DocListCastAsync((CurrentUserUtils.UserDocument.overlays as Doc).data); - if (res) res.splice(res.indexOf(LinkFollowBox.Instance!.props.Document), 1); - LinkFollowBox.Instance = undefined; - } - render() { return (
{LinkFollowBox.linkDoc ? "Link Title: " + StrCast(LinkFollowBox.linkDoc.title) : "No Link Selected"} -
+
this.props.Document.isMinimized = true} className="closeDocument">
{LinkFollowBox.linkDoc ? LinkFollowBox.sourceDoc && LinkFollowBox.destinationDoc ? "Source: " + StrCast(LinkFollowBox.sourceDoc.title) + ", Destination: " + StrCast(LinkFollowBox.destinationDoc.title) diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 6c10d4fb6..780f161d3 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -97,24 +97,20 @@ export class LinkMenuItem extends React.Component { @action.bound async followDefault() { - if (LinkFollowBox.Instance === undefined) { - let doc = await Docs.Create.LinkFollowBoxDocument({ x: MainView.Instance.flyoutWidth, y: 20, width: 500, height: 370, title: "Link Follower" }); - await Doc.AddDocToList(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc, "data", doc); - } else { - LinkFollowBox.Instance!.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc); - LinkFollowBox.Instance!.defaultLinkBehavior(); + if (LinkFollowBox.Instance !== undefined) { + LinkFollowBox.Instance.props.Document.isMinimized = false; + LinkFollowBox.Instance.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc); + LinkFollowBox.Instance.defaultLinkBehavior(); } } @action.bound async openLinkFollower() { - if (LinkFollowBox.Instance === undefined) { - let doc = await Docs.Create.LinkFollowBoxDocument({ x: MainView.Instance.flyoutWidth, y: 20, width: 500, height: 370, title: "Link Follower" }); - await Doc.AddDocToList(Cast(CurrentUserUtils.UserDocument.overlays, Doc) as Doc, "data", doc); - } else { + if (LinkFollowBox.Instance !== undefined) { + LinkFollowBox.Instance.props.Document.isMinimized = false; MainView.Instance.toggleLinkFollowBox(false); + LinkFollowBox.Instance.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc); } - LinkFollowBox.Instance!.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc); } render() { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 7631ecc6c..c9c394960 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -8,7 +8,6 @@ import { DocumentView, DocumentViewProps, positionSchema } from "./DocumentView" import "./DocumentView.scss"; import React = require("react"); import { Doc } from "../../../new_fields/Doc"; -import { returnEmptyString } from "../../../Utils"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { x?: number; diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx index 9123f8aed..0287d93a9 100644 --- a/src/client/views/nodes/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/FormattedTextBoxComment.tsx @@ -1,12 +1,12 @@ -import { Plugin, EditorState } from "prosemirror-state" -import './FormattedTextBoxComment.scss' +import { Plugin, EditorState } from "prosemirror-state"; +import './FormattedTextBoxComment.scss'; import { ResolvedPos, Mark } from "prosemirror-model"; import { EditorView } from "prosemirror-view"; import { Doc } from "../../../new_fields/Doc"; export let selectionSizePlugin = new Plugin({ view(editorView) { return new SelectionSizeTooltip(editorView); } -}) +}); export function findOtherUserMark(marks: Mark[]): Mark | undefined { return marks.find(m => m.attrs.userid && m.attrs.userid !== Doc.CurrentUserEmail); } @@ -106,5 +106,5 @@ export class SelectionSizeTooltip { } } - destroy() { SelectionSizeTooltip.tooltip.style.display = "none" } + destroy() { SelectionSizeTooltip.tooltip.style.display = "none"; } } diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 83e45d3ce..9866e22eb 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -79,6 +79,9 @@ export class CurrentUserUtils { Doc.GetProto(overlays).backgroundColor = "#aca3a6"; doc.overlays = overlays; } + if (doc.linkFollowBox === undefined) { + PromiseValue(Cast(doc.overlays, Doc)).then(overlays => overlays && Doc.AddDocToList(overlays, "data", doc.linkFollowBox = Docs.Create.LinkFollowBoxDocument({ x: 250, y: 20, width: 500, height: 370, title: "Link Follower" }))); + } StrCast(doc.title).indexOf("@") !== -1 && (doc.title = StrCast(doc.title).split("@")[0] + "'s Library"); doc.width = 100; doc.preventTreeViewOpen = true; -- cgit v1.2.3-70-g09d2 From 0fea8592b5bd790334d0557c3ef30eb03973c601 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 6 Sep 2019 23:19:21 -0400 Subject: changed sub-menu pop up location. added rotation jitter --- src/client/views/ContextMenuItem.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 14 ++++++++++---- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 4 +++- 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 90f7be33f..1a0839060 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -89,7 +89,7 @@ export class ContextMenuItem extends React.Component +
{this._items.map(prop => )}
; return ( diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4f6055260..2df2a3464 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -152,6 +152,7 @@ export namespace PivotView { y={pos.y} width={pos.width} height={pos.height} + jitterRotation={NumCast(target.props.Document.jitterRotation)} {...target.getChildDocumentViewProps(doc)} />, bounds: { @@ -797,6 +798,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (pair.layout && !(pair.data instanceof Promise)) { prev.push({ ele: , bounds: { x: pos.x || 0, y: pos.y || 0, z: pos.z, width: NumCast(pos.width), height: NumCast(pos.height) } @@ -912,10 +914,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }); layoutItems.push({ description: "Arrange contents in grid", event: this.arrangeContents, icon: "table" }); layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" }); - layoutItems.push({ description: "1: Note", event: () => this.createText("Note", "yellow"), icon: "eye" }); - layoutItems.push({ description: "2: Idea", event: () => this.createText("Idea", "pink"), icon: "eye" }); - layoutItems.push({ description: "3: Topic", event: () => this.createText("Topic", "lightBlue"), icon: "eye" }); - layoutItems.push({ description: "4: Person", event: () => this.createText("Person", "lightGreen"), icon: "eye" }); + layoutItems.push({ description: "Jitter Rotation", event: action(() => this.props.Document.jitterRotation = 10), icon: "paint-brush" }); + + let noteItems: ContextMenuProps[] = []; + noteItems.push({ description: "1: Note", event: () => this.createText("Note", "yellow"), icon: "eye" }); + noteItems.push({ description: "2: Idea", event: () => this.createText("Idea", "pink"), icon: "eye" }); + noteItems.push({ description: "3: Topic", event: () => this.createText("Topic", "lightBlue"), icon: "eye" }); + noteItems.push({ description: "4: Person", event: () => this.createText("Person", "lightGreen"), icon: "eye" }); + layoutItems.push({ description: "Add Note ...", subitems: noteItems, icon: "eye" }) ContextMenu.Instance.addItem({ description: "Freeform Options ...", subitems: layoutItems, icon: "eye" }); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index c9c394960..f07584b4f 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -8,12 +8,14 @@ import { DocumentView, DocumentViewProps, positionSchema } from "./DocumentView" import "./DocumentView.scss"; import React = require("react"); import { Doc } from "../../../new_fields/Doc"; +import { random } from "animejs"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { x?: number; y?: number; width?: number; height?: number; + jitterRotation: number; } const schema = createSchema({ @@ -27,7 +29,7 @@ const FreeformDocument = makeInterface(schema, positionSchema); @observer export class CollectionFreeFormDocumentView extends DocComponent(FreeformDocument) { - @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) scale(${this.zoom}) `; } + @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${random(-1, 1) * this.props.jitterRotation}deg) scale(${this.zoom}) `; } @computed get X() { return this.props.x !== undefined ? this.props.x : this.Document.x || 0; } @computed get Y() { return this.props.y !== undefined ? this.props.y : this.Document.y || 0; } @computed get width(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.props.width !== undefined ? this.props.width : this.Document.width || 0; } -- cgit v1.2.3-70-g09d2 From 3865ccd688015d92c8c551bf78ee2a9b6ece5500 Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 9 Sep 2019 15:40:49 -0400 Subject: added local overlay for free form views. added start of minimap. --- src/client/views/OverlayView.tsx | 4 +++- .../collectionFreeForm/CollectionFreeFormView.tsx | 16 ++++++++++++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 23 ++++++++++++++++++---- src/client/views/nodes/DocumentView.tsx | 2 -- src/server/index.ts | 2 +- 5 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index fe06e4440..da4b71e5c 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -197,7 +197,9 @@ export class OverlayView extends React.Component { render() { return (
- {this._elements} +
+ {this._elements} +
{this.overlayDocs}
); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2df2a3464..2ec2b0671 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -3,7 +3,7 @@ import { faEye } from "@fortawesome/free-regular-svg-icons"; import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons"; import { action, computed, IReactionDisposer, observable, reaction, trace } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCastAsync, Field, FieldResult, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc"; +import { Doc, DocListCastAsync, Field, FieldResult, HeightSym, Opt, WidthSym, DocListCast } from "../../../../new_fields/Doc"; import { Id } from "../../../../new_fields/FieldSymbols"; import { InkField, StrokeData } from "../../../../new_fields/InkField"; import { createSchema, makeInterface } from "../../../../new_fields/Schema"; @@ -225,8 +225,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return bounds; } + @computed get actualContentBounds() { + return this.fitToBox && !this.isAnnotationOverlay ? this.ComputeContentBounds(this.elements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!)) : undefined; + } + @computed get contentBounds() { - let bounds = this.fitToBox && !this.isAnnotationOverlay ? this.ComputeContentBounds(this.elements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!)) : undefined; + let bounds = this.actualContentBounds; let res = { panX: bounds ? (bounds.x + bounds.r) / 2 : this.Document.panX || 0, panY: bounds ? (bounds.y + bounds.b) / 2 : this.Document.panY || 0, @@ -775,7 +779,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { const initScript = this.Document.arrangeInit; const script = this.Document.arrangeScript; let state: any = undefined; - const docs = this.childDocs; + let docs = this.childDocs; + let overlayDocs = DocListCast(this.props.Document.localOverlays); + overlayDocs && docs.push(...overlayDocs); let elements: ViewDefResult[] = []; if (initScript) { const initResult = initScript.script.run({ docs, collection: this.Document }); @@ -967,6 +973,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } render() { + this.props.Document.fitX = this.actualContentBounds && this.actualContentBounds.x; + this.props.Document.fitY = this.actualContentBounds && this.actualContentBounds.y; + this.props.Document.fitW = this.actualContentBounds && (this.actualContentBounds.r - this.actualContentBounds.x); + this.props.Document.fitH = this.actualContentBounds && (this.actualContentBounds.b - this.actualContentBounds.y); const easing = () => this.props.Document.panTransformType === "Ease"; Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey); return ( diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index f07584b4f..c059ff50d 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,7 +1,7 @@ import { computed } from "mobx"; import { observer } from "mobx-react"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; -import { BoolCast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types"; +import { BoolCast, FieldValue, NumCast, StrCast, Cast } from "../../../new_fields/Types"; import { Transform } from "../../util/Transform"; import { DocComponent } from "../DocComponent"; import { DocumentView, DocumentViewProps, positionSchema } from "./DocumentView"; @@ -77,6 +77,21 @@ export class CollectionFreeFormDocumentView extends DocComponent this.clusterColor; render() { + let txf = this.transform; + let w = this.width; + let h = this.height; + let renderScript = this.Document.renderScript; + if (renderScript) { + let someView = Cast(this.Document.someView, Doc); + let minimap = Cast(this.Document.minimap, Doc); + if (someView instanceof Doc && minimap instanceof Doc) { + let x = (NumCast(someView.panX) - NumCast(someView.width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap.width) - NumCast(minimap.width) / 2; + let y = (NumCast(someView.panY) - NumCast(someView.height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap.height) - NumCast(minimap.height) / 2; + w = NumCast(someView.width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width); + h = NumCast(someView.height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height); + txf = `translate(${x}px,${y}px)`; + } + } const hasPosition = this.props.x !== undefined || this.props.y !== undefined; return (
(Docu }); } let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith(" { console.log("reading " + page); - let viewport = page.getViewport({scale: 1}); + let viewport = page.getViewport(1 as any); let canvasAndContext = factory.create(viewport.width, viewport.height); let renderContext = { canvasContext: canvasAndContext.context, -- cgit v1.2.3-70-g09d2 From 9608245db4ba8cca6054a0641f2eb2bd2032eba6 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 10 Sep 2019 15:55:51 -0400 Subject: fixed up some stuff with portals and added a ButtonBox menu item for running scripts over a collection --- src/client/views/ContextMenuItem.tsx | 2 +- src/client/views/InkingControl.tsx | 2 +- src/client/views/ScriptBox.tsx | 15 +++++++++++++-- src/client/views/collections/CollectionBaseView.tsx | 4 ++++ src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 11 +++++++---- src/client/views/nodes/DocumentView.tsx | 12 +++++++++--- src/new_fields/Doc.ts | 3 ++- 7 files changed, 37 insertions(+), 12 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 1a0839060..0366a6a30 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -89,7 +89,7 @@ export class ContextMenuItem extends React.Component +
{this._items.map(prop => )}
; return ( diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index 519792308..aa573f16b 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -64,7 +64,7 @@ export class InkingControl extends React.Component { closest = i; } } - cp[closest] = "rgb(" + color.rgb.r + "," + color.rgb.g + "," + color.rgb.b + ")"; + cp[closest] = "rgba(" + color.rgb.r + "," + color.rgb.g + "," + color.rgb.b + "," + color.rgb.a + ")"; view.props.ContainingCollectionView.props.Document.colorPalette = new List(cp); targetDoc.backgroundColor = cp[closest]; } else diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index 2b862a81e..7afba5e01 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -66,13 +66,24 @@ export class ScriptBox extends React.Component {
); } - public static EditClickScript(doc: Doc, fieldKey: string) { + public static EditClickScript(doc: Doc, fieldKey: string, prewrapper?: string, postwrapper?: string) { let overlayDisposer: () => void = emptyFunction; const script = ScriptCast(doc[fieldKey]); let originalText: string | undefined = undefined; - if (script) originalText = script.script.originalScript; + if (script) { + originalText = script.script.originalScript; + if (prewrapper && originalText.startsWith(prewrapper)) { + originalText = originalText.substr(prewrapper.length); + } + if (postwrapper && originalText.endsWith(postwrapper)) { + originalText = originalText.substr(0, originalText.length - postwrapper.length); + } + } // tslint:disable-next-line: no-unnecessary-callback-wrapper let scriptingBox = overlayDisposer()} onSave={(text, onError) => { + if (prewrapper) { + text = prewrapper + text + (postwrapper ? postwrapper : ""); + } const script = CompileScript(text, { params: { this: Doc.name }, typecheck: false, diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index b6ed6aaa0..bd8d56851 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -12,6 +12,7 @@ import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; import './CollectionBaseView.scss'; import { DateField } from '../../../new_fields/DateField'; +import { DocumentType } from '../../documents/DocumentTypes'; export enum CollectionViewType { Invalid, @@ -103,6 +104,9 @@ export class CollectionBaseView extends React.Component { if (this.props.fieldExt) { // bcz: fieldExt !== undefined means this is an overlay layer Doc.GetProto(doc).annotationOn = this.props.Document; } + if (doc.type === DocumentType.BUTTON) { + doc.collectionContext = this.props.Document; // used by docList() function in Doc.ts so that buttons can iterate over the documents in their collection + } allowDuplicates = true; let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index c059ff50d..9692dd8a9 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -99,10 +99,13 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu makes.push({ description: this.props.Document.isBackground ? "Remove Background" : "Into Background", event: this.makeBackground, icon: this.props.Document.lockedPosition ? "unlock" : "lock" }); makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Into Button", event: this.makeBtnClicked, icon: "concierge-bell" }); makes.push({ description: "OnClick script", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onClick") }); + makes.push({ description: "OnClick foreach doc", icon: "edit", event: () => ScriptBox.EditClickScript(this.props.Document, "onClick", "docList(this.collectionContext.data).map(d => {", "});\n") }); makes.push({ description: "Into Portal", event: () => { - let portal = Docs.Create.FreeformDocument([], { width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".portal" }); - DocUtils.MakeLink(this.props.Document, portal, undefined, this.props.Document.title + ".portal"); - this.makeBtnClicked(); + if (!DocListCast(this.props.Document.links).find(doc => { + if (Cast(doc.anchor2, Doc) instanceof Doc && (Cast(doc.anchor2, Doc) as Doc)!.title === this.props.Document.title + ".portal") return true; + return false; + })) { + let portal = Docs.Create.FreeformDocument([], { width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".portal" }); + DocUtils.MakeLink(this.props.Document, portal, undefined, this.props.Document.title + ".portal"); + Doc.GetProto(this.props.Document).isButton = true; + } }, icon: "window-restore" }); makes.push({ description: this.props.Document.ignoreClick ? "Selectable" : "Unselectable", event: () => this.props.Document.ignoreClick = !this.props.Document.ignoreClick, icon: this.props.Document.ignoreClick ? "unlock" : "lock" }); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index e3d7cc9ed..ccb8f4aa2 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -685,4 +685,5 @@ export namespace Doc { Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(doc.title).replace(/\([0-9]*\)/, "") + `(${n})`; }); Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); }); Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); }); -Scripting.addGlobal(function aliasDocs(field: any) { return new List(field.map((d: any) => Doc.MakeAlias(d))); }); \ No newline at end of file +Scripting.addGlobal(function aliasDocs(field: any) { return new List(field.map((d: any) => Doc.MakeAlias(d))); }); +Scripting.addGlobal(function docList(field: any) { return DocListCast(field); }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From edec708b4396cd3b21ea22296812d5014b1359db Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 10 Sep 2019 22:18:46 -0400 Subject: got rid of zoomBasis remnants. cleaned up (just a little bit) renderScript stuff in colelctionfreeformdocumentview --- src/client/views/DocumentDecorations.tsx | 3 +- .../views/collections/ParentDocumentSelector.tsx | 4 +- .../CollectionFreeFormLinkView.tsx | 8 ++-- .../CollectionFreeFormLinksView.tsx | 4 +- src/client/views/linking/LinkFollowBox.tsx | 12 +++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 50 +++++++++++----------- src/client/views/search/SearchBox.tsx | 1 - src/client/views/search/SearchItem.tsx | 4 +- src/scraping/buxton/scraper.py | 1 - 9 files changed, 41 insertions(+), 46 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 94aab8b2f..773ab8b9f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -397,8 +397,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } moveIconDoc(iconDoc: Doc) { let selView = SelectionManager.SelectedDocuments()[0]; - let zoom = NumCast(selView.props.Document.zoomBasis, 1); - let where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()).scale(1 / zoom). + let where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()). transformPoint(this._minimizedX - 12, this._minimizedY - 12); iconDoc.x = where[0] + NumCast(selView.props.Document.x); iconDoc.y = where[1] + NumCast(selView.props.Document.y); diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 17111af58..d8475a467 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -38,8 +38,8 @@ export class SelectorContextMenu extends React.Component { return () => { col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; - const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; + const newPanX = NumCast(target.x) + NumCast(target.width) / 2; + const newPanY = NumCast(target.y) + NumCast(target.height) / 2; col.panX = newPanX; col.panY = newPanY; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 6af87b138..790c6694b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -39,10 +39,10 @@ export class CollectionFreeFormLinkView extends React.Component)[]) => field.findIndex(brush => { diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx index d5ed01f53..f8807641b 100644 --- a/src/client/views/linking/LinkFollowBox.tsx +++ b/src/client/views/linking/LinkFollowBox.tsx @@ -180,8 +180,8 @@ export class LinkFollowBox extends React.Component { openColFullScreen = (options: { context: Doc }) => { if (LinkFollowBox.destinationDoc) { if (NumCast(options.context.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / NumCast(LinkFollowBox.destinationDoc.zoomBasis, 1) / 2; - const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / NumCast(LinkFollowBox.destinationDoc.zoomBasis, 1) / 2; + const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / 2; + const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / 2; options.context.panX = newPanX; options.context.panY = newPanY; } @@ -209,8 +209,8 @@ export class LinkFollowBox extends React.Component { if (LinkFollowBox.destinationDoc) { options.context = Doc.IsPrototype(options.context) ? Doc.MakeDelegate(options.context) : options.context; if (NumCast(options.context.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / NumCast(LinkFollowBox.destinationDoc.zoomBasis, 1) / 2; - const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / NumCast(LinkFollowBox.destinationDoc.zoomBasis, 1) / 2; + const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / 2; + const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / 2; options.context.panX = newPanX; options.context.panY = newPanY; } @@ -286,8 +286,8 @@ export class LinkFollowBox extends React.Component { if (LinkFollowBox.destinationDoc) { options.context = Doc.IsPrototype(options.context) ? Doc.MakeDelegate(options.context) : options.context; if (NumCast(options.context.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / NumCast(LinkFollowBox.destinationDoc.zoomBasis, 1) / 2; - const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / NumCast(LinkFollowBox.destinationDoc.zoomBasis, 1) / 2; + const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / 2; + const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / 2; options.context.panX = newPanX; options.context.panY = newPanY; } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 9692dd8a9..eb7ab64f8 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -19,7 +19,6 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { } const schema = createSchema({ - zoomBasis: "number", zIndex: "number", }); @@ -29,22 +28,36 @@ const FreeformDocument = makeInterface(schema, positionSchema); @observer export class CollectionFreeFormDocumentView extends DocComponent(FreeformDocument) { - @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${random(-1, 1) * this.props.jitterRotation}deg) scale(${this.zoom}) `; } - @computed get X() { return this.props.x !== undefined ? this.props.x : this.Document.x || 0; } - @computed get Y() { return this.props.y !== undefined ? this.props.y : this.Document.y || 0; } - @computed get width(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.props.width !== undefined ? this.props.width : this.Document.width || 0; } - @computed get height(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.props.height !== undefined ? this.props.height : this.Document.height || 0; } - @computed get zoom(): number { return 1 / FieldValue(this.Document.zoomBasis, 1); } + @computed get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${random(-1, 1) * this.props.jitterRotation}deg)`; } + @computed get X() { return this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.Document.x || 0; } + @computed get Y() { return this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.Document.y || 0; } + @computed get width(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.renderScriptDim ? this.renderScriptDim.width : this.props.width !== undefined ? this.props.width : this.Document.width || 0; } + @computed get height(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.Document.height || 0; } @computed get nativeWidth(): number { return FieldValue(this.Document.nativeWidth, 0); } @computed get nativeHeight(): number { return FieldValue(this.Document.nativeHeight, 0); } @computed get scaleToOverridingWidth() { return this.width / NumCast(this.props.Document.width, this.width); } + @computed get renderScriptDim() { + if (this.Document.renderScript) { + let someView = Cast(this.Document.someView, Doc); + let minimap = Cast(this.Document.minimap, Doc); + if (someView instanceof Doc && minimap instanceof Doc) { + let x = (NumCast(someView.panX) - NumCast(someView.width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap.width) - NumCast(minimap.width) / 2; + let y = (NumCast(someView.panY) - NumCast(someView.height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap.height) - NumCast(minimap.height) / 2; + let w = NumCast(someView.width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width); + let h = NumCast(someView.height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height); + return { x: x, y: y, width: w, height: h }; + } + } + return undefined; + } + contentScaling = () => this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? this.width / this.nativeWidth : 1; panelWidth = () => this.props.PanelWidth(); panelHeight = () => this.props.PanelHeight(); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.zoom / this.scaleToOverridingWidth) + .scale(1 / this.contentScaling()).scale(1 / this.scaleToOverridingWidth) animateBetweenIcon = (icon: number[], stime: number, maximizing: boolean) => { this.props.bringToFront(this.props.Document); @@ -77,21 +90,6 @@ export class CollectionFreeFormDocumentView extends DocComponent this.clusterColor; render() { - let txf = this.transform; - let w = this.width; - let h = this.height; - let renderScript = this.Document.renderScript; - if (renderScript) { - let someView = Cast(this.Document.someView, Doc); - let minimap = Cast(this.Document.minimap, Doc); - if (someView instanceof Doc && minimap instanceof Doc) { - let x = (NumCast(someView.panX) - NumCast(someView.width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap.width) - NumCast(minimap.width) / 2; - let y = (NumCast(someView.panY) - NumCast(someView.height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap.height) - NumCast(minimap.height) / 2; - w = NumCast(someView.width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width); - h = NumCast(someView.height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height); - txf = `translate(${x}px,${y}px)`; - } - } const hasPosition = this.props.x !== undefined || this.props.y !== undefined; return (
1000) { x = 0; diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 30e0454f3..c56d093fa 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -71,8 +71,8 @@ export class SelectorContextMenu extends React.Component { return () => { col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) { - const newPanX = NumCast(target.x) + NumCast(target.width) / NumCast(target.zoomBasis, 1) / 2; - const newPanY = NumCast(target.y) + NumCast(target.height) / NumCast(target.zoomBasis, 1) / 2; + const newPanX = NumCast(target.x) + NumCast(target.width) / 2; + const newPanY = NumCast(target.y) + NumCast(target.height) / 2; col.panX = newPanX; col.panY = newPanY; } diff --git a/src/scraping/buxton/scraper.py b/src/scraping/buxton/scraper.py index 807216ef1..a9256073b 100644 --- a/src/scraping/buxton/scraper.py +++ b/src/scraping/buxton/scraper.py @@ -88,7 +88,6 @@ def write_collection(parse_results, display_fields, storage_key, viewType=2): "height": 600, "panX": 0, "panY": 0, - "zoomBasis": 1, "zIndex": 2, "libraryBrush": False, "viewType": viewType -- cgit v1.2.3-70-g09d2 From 186d7aed7b99b1373e99b51cfe0c88c8167c8290 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 11 Sep 2019 22:52:07 -0400 Subject: fixed some template issues specifically for self-templates. --- src/client/views/DocumentDecorations.tsx | 22 +++++++++++++------- .../views/collections/CollectionBaseView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 24 ++++++++++++++-------- src/client/views/nodes/DocumentView.tsx | 6 +++--- src/client/views/nodes/FormattedTextBox.tsx | 3 +-- src/new_fields/Doc.ts | 5 ++--- 6 files changed, 37 insertions(+), 25 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index fe409d9a6..814d718be 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -30,6 +30,7 @@ import { MetadataEntryMenu } from './MetadataEntryMenu'; import { ImageBox } from './nodes/ImageBox'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils'; +import { ObjectField } from '../../new_fields/ObjectField'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -145,13 +146,20 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let fieldTemplateView = SelectionManager.SelectedDocuments()[0]; SelectionManager.DeselectAll(); let fieldTemplate = fieldTemplateView.props.Document; - let docTemplate = fieldTemplateView.props.ContainingCollectionView!.props.Document; - let metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length); - let proto = Doc.GetProto(docTemplate); - Doc.MakeTemplate(fieldTemplate, metaKey, proto); - if (text.startsWith(">>")) { - proto.detailedLayout = proto.layout; - proto.miniLayout = ImageBox.LayoutString(metaKey); + let containerView = fieldTemplateView.props.ContainingCollectionView; + if (containerView) { + let docTemplate = containerView.props.Document; + let metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length); + let proto = Doc.GetProto(docTemplate); + if (metaKey !== containerView.props.fieldKey && containerView.props.DataDoc) { + const fd = fieldTemplate.data; + fd instanceof ObjectField && (Doc.GetProto(containerView.props.DataDoc)[metaKey] = ObjectField.MakeCopy(fd)); + } + Doc.MakeTemplate(fieldTemplate, metaKey, proto); + if (text.startsWith(">>")) { + proto.detailedLayout = proto.layout; + proto.miniLayout = ImageBox.LayoutString(metaKey); + } } } else { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 5829f0626..b7036b3ff 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -127,7 +127,7 @@ export class CollectionBaseView extends React.Component { let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; let value = Cast(targetDataDoc[targetField], listSpec(Doc), []); - let index = value.reduce((p, v, i) => (v instanceof Doc && v[Id] === doc[Id]) ? i : p, -1); + let index = value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1); PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => annotationOn === this.dataDoc.Document && (doc.annotationOn = undefined)); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index eb7ab64f8..07dd1cae7 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -74,10 +74,10 @@ export class CollectionFreeFormDocumentView extends DocComponent { - let br = StrCast(this.props.Document.layout instanceof Doc ? this.props.Document.layout.borderRounding : this.props.Document.borderRounding); + let br = StrCast(this.layoutDoc.layout instanceof Doc ? this.layoutDoc.layout.borderRounding : this.props.Document.borderRounding); if (br.endsWith("%")) { let percent = Number(br.substr(0, br.length - 1)) / 100; - let nativeDim = Math.min(NumCast(this.props.Document.nativeWidth), NumCast(this.props.Document.nativeHeight)); + let nativeDim = Math.min(NumCast(this.layoutDoc.nativeWidth), NumCast(this.layoutDoc.nativeHeight)); let minDim = percent * (nativeDim ? nativeDim : Math.min(this.props.PanelWidth(), this.props.PanelHeight())); return minDim; } @@ -89,6 +89,12 @@ export class CollectionFreeFormDocumentView extends DocComponent this.clusterColor; + get layoutDoc() { + // if this document's layout field contains a document (ie, a rendering template), then we will use that + // to determine the render JSX string, otherwise the layout field should directly contain a JSX layout string. + return this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document; + } + render() { const hasPosition = this.props.x !== undefined || this.props.y !== undefined; return ( @@ -98,15 +104,15 @@ export class CollectionFreeFormDocumentView extends DocComponent(Docu let docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: StrCast(this.Document.title) + "layout", width: NumCast(this.props.Document.width) + 20, height: Math.max(100, NumCast(this.props.Document.height) + 45) }); let metaKey = "data"; let proto = Doc.GetProto(docTemplate); - Doc.MakeTemplate(fieldTemplate, metaKey, proto, true); + Doc.MakeTemplate(fieldTemplate, metaKey, proto); - Doc.ApplyTemplateTo(docTemplate, this.props.Document, undefined, true); + Doc.ApplyTemplateTo(docTemplate, this.props.Document, undefined, false); } @undoBatch @@ -634,7 +634,7 @@ export class DocumentView extends DocComponent(Docu let makes: ContextMenuProps[] = existingMake && "subitems" in existingMake ? existingMake.subitems : []; makes.push({ description: this.props.Document.isBackground ? "Remove Background" : "Into Background", event: this.makeBackground, icon: this.props.Document.lockedPosition ? "unlock" : "lock" }); makes.push({ description: "Custom Document View", event: this.makeCustomViewClicked, icon: "concierge-bell" }); - makes.push({ description: "Metadata Field View", event: () => this.props.ContainingCollectionView && Doc.MakeTemplate(this.props.Document, StrCast(this.props.Document.title), this.props.ContainingCollectionView.props.Document, true), icon: "concierge-bell" }) + makes.push({ description: "Metadata Field View", event: () => this.props.ContainingCollectionView && Doc.MakeTemplate(this.props.Document, StrCast(this.props.Document.title), this.props.ContainingCollectionView.props.Document), icon: "concierge-bell" }) makes.push({ description: "Into Portal", event: this.makeIntoPortal, icon: "window-restore" }); makes.push({ description: this.layoutDoc.ignoreClick ? "Selectable" : "Unselectable", event: () => this.layoutDoc.ignoreClick = !this.layoutDoc.ignoreClick, icon: this.layoutDoc.ignoreClick ? "unlock" : "lock" }); !existingMake && cm.addItem({ description: "Make...", subitems: makes, icon: "hand-point-right" }); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 194026a08..0ea36cdc2 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -289,8 +289,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } else if (de.data instanceof DragManager.DocumentDragData) { const draggedDoc = de.data.draggedDocuments.length && de.data.draggedDocuments[0]; if (draggedDoc && draggedDoc.type === DocumentType.TEXT && StrCast(draggedDoc.layout) !== "") { - if (this.props.DataDoc) this.props.DataDoc.layout = draggedDoc; - else this.props.Document.layout = draggedDoc; + this.props.Document.layout = draggedDoc; draggedDoc.isTemplate = true; e.stopPropagation(); } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index d4b784cac..e94b9f1eb 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -459,7 +459,7 @@ export namespace Doc { } if (expandedTemplateLayout === undefined) { setTimeout(() => dataDoc[expandedLayoutFieldKey] === undefined && - (dataDoc[expandedLayoutFieldKey] = !BoolCast(templateLayoutDoc.suppressTemplateInstance) ? Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]") : templateLayoutDoc), 0); + (dataDoc[expandedLayoutFieldKey] = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]")), 0); } return undefined; // use the templateLayout when it's not a template or the expandedTemplate is pending. } @@ -558,7 +558,7 @@ export namespace Doc { } } - export function MakeTemplate(fieldTemplate: Doc, metaKey: string, templateDataDoc: Doc, suppressTemplateFlag?: boolean) { + export function MakeTemplate(fieldTemplate: Doc, metaKey: string, templateDataDoc: Doc) { // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??) let backgroundLayout = StrCast(fieldTemplate.backgroundLayout); let fieldLayoutDoc = fieldTemplate; @@ -576,7 +576,6 @@ export namespace Doc { fieldTemplate.templateField = metaKey; fieldTemplate.title = metaKey; fieldTemplate.isTemplate = true; - fieldTemplate.suppressTemplateInstance = suppressTemplateFlag; fieldTemplate.layout = layoutDelegate !== fieldTemplate ? layoutDelegate : layout; fieldTemplate.backgroundLayout = backgroundLayout; /* move certain layout properties from the original data doc to the template layout to avoid -- cgit v1.2.3-70-g09d2 From 47ca25c49d7d9f1fee22b256f86e296dac42b47b Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 12 Sep 2019 21:42:07 -0400 Subject: cleaned up rulerProvider a bit and added menu item to turn it on. --- src/client/views/DocumentDecorations.tsx | 13 +++++---- src/client/views/InkingControl.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 31 +++++++--------------- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 3 +++ src/client/views/nodes/DocumentView.tsx | 12 ++++++--- src/client/views/nodes/FormattedTextBox.tsx | 4 +-- 7 files changed, 31 insertions(+), 36 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 6451fdf5e..4ab2ade8e 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -424,23 +424,22 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.addEventListener("pointermove", this.onRadiusMove); document.addEventListener("pointerup", this.onRadiusUp); } - if (!this._isMoving) { - SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)). - map(d => d.borderRounding = "0%"); - } } onRadiusMove = (e: PointerEvent): void => { this._isMoving = true; let dist = Math.sqrt((e.clientX - this._radiusDown[0]) * (e.clientX - this._radiusDown[0]) + (e.clientY - this._radiusDown[1]) * (e.clientY - this._radiusDown[1])); - SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)). - map(d => d.borderRounding = `${Math.min(100, dist)}%`); + dist = dist < 3 ? 0 : dist; + let usingRule = false; SelectionManager.SelectedDocuments().map(dv => { let cv = dv.props.ContainingCollectionView; let ruleProvider = cv && (Cast(cv.props.Document.ruleProvider, Doc) as Doc); let heading = NumCast(dv.props.Document.heading); - cv && ((ruleProvider ? ruleProvider : cv.props.Document)["ruleRounding_" + heading] = StrCast(dv.props.Document.borderRounding)); + ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`); + usingRule = usingRule || (ruleProvider && heading ? true : false); }) + !usingRule && SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)). + map(d => d.borderRounding = `${Math.min(100, dist)}%`); e.stopPropagation(); e.preventDefault(); } diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index aa573f16b..867735c0b 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -73,7 +73,7 @@ export class InkingControl extends React.Component { let cv = view.props.ContainingCollectionView; let ruleProvider = cv && (Cast(cv.props.Document.ruleProvider, Doc) as Doc); let parback = cv && StrCast(cv.props.Document.backgroundColor); - cv && parback && ((ruleProvider ? ruleProvider : cv.props.Document)["ruleColor_" + NumCast(view.props.Document.heading)] = Utils.toRGBAstr(color.rgb)); + cv && parback && (Doc.GetProto(ruleProvider ? ruleProvider : cv.props.Document)["ruleColor_" + NumCast(view.props.Document.heading)] = Utils.toRGBAstr(color.rgb)); // if (parback && cv && parback.indexOf("rgb") !== -1) { // let parcol = Utils.fromRGBAstr(parback); // let hsl = Utils.RGBToHSL(parcol.r, parcol.g, parcol.b); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 24f2a60a9..9a8ae3535 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -262,27 +262,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (heading === 0) { let sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 : DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date < DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? -1 : 0); - heading = NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading); + heading = !sorted.length ? 1 : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading); } newBox.heading = heading; - PromiseValue(Cast(this.props.Document.ruleProvider, Doc)).then(ruleProvider => { - if (!ruleProvider) ruleProvider = this.props.Document; - // saturation shift - // let col = NumCast(ruleProvider["ruleColor_" + NumCast(newBox.heading)]); - // let back = Utils.fromRGBAstr(StrCast(this.props.Document.backgroundColor)); - // let hsl = Utils.RGBToHSL(back.r, back.g, back.b); - // let newcol = { h: hsl.h, s: hsl.s + col, l: hsl.l }; - // col && (Doc.GetProto(newBox).backgroundColor = Utils.toRGBAstr(Utils.HSLtoRGB(newcol.h, newcol.s, newcol.l))); - // OR transparency set - let col = StrCast(ruleProvider["ruleColor_" + NumCast(newBox.heading)]); - (newBox.backgroundColor === newBox.defaultBackgroundColor) && col && (Doc.GetProto(newBox).backgroundColor = col); - - let round = StrCast(ruleProvider["ruleRounding_" + NumCast(newBox.heading)]); - round && (Doc.GetProto(newBox).borderRounding = round); - newBox.ruleProvider = ruleProvider; - this.addDocument(newBox, false); - }); + if (Cast(this.props.Document.ruleProvider, Doc) as Doc) { + newBox.ruleProvider = Doc.GetProto(Cast(this.props.Document.ruleProvider, Doc) as Doc); + } + this.addDocument(newBox, false); } private addDocument = (newBox: Doc, allowDuplicates: boolean) => { this.props.addDocument(newBox, false); @@ -898,7 +885,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { onContextMenu = (e: React.MouseEvent) => { let layoutItems: ContextMenuProps[] = []; - if (this.childDocs.some(d => d.isTemplate)) { + if (this.childDocs.some(d => BoolCast(d.isTemplate))) { layoutItems.push({ description: "Template Layout Instance", event: () => this.props.addDocTab && this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight"), icon: "project-diagram" }); } layoutItems.push({ description: "reset view", event: () => { this.props.Document.panX = this.props.Document.panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" }); @@ -913,9 +900,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }, icon: !this.props.Document.useClusters ? "braille" : "braille" }); - this.props.Document.useClusters && layoutItems.push({ - description: `${this.props.Document.clusterOverridesDefaultBackground ? "Use Default Backgrounds" : "Clusters Override Defaults"}`, - event: async () => this.props.Document.clusterOverridesDefaultBackground = !this.props.Document.clusterOverridesDefaultBackground, + layoutItems.push({ + description: `${this.props.Document.isRuleProvider ? "Stop Auto Format" : "Auto Format"}`, + event: () => this.props.Document.isRuleProvider = !this.props.Document.isRuleProvider, icon: !this.props.Document.useClusters ? "chalkboard" : "chalkboard" }); layoutItems.push({ description: "Arrange contents in grid", event: this.arrangeContents, icon: "table" }); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index fe48a3485..4308497a1 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -356,7 +356,7 @@ export class MarqueeView extends React.Component this.props.addLiveTextDocument(summary); } else { - newCollection.ruleProvider = this.props.container.props.Document; + newCollection.ruleProvider = this.props.container.props.Document.isRuleProvider ? this.props.container.props.Document : this.props.container.props.Document.ruleProvider; this.props.addDocument(newCollection, false); this.props.selectDocuments([newCollection]); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 07dd1cae7..082e5c5e3 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -74,7 +74,10 @@ export class CollectionFreeFormDocumentView extends DocComponent { + let ruleProvider = this.props.Document.ruleProvider as Doc; + let ruleRounding = ruleProvider ? StrCast(Doc.GetProto(ruleProvider)["ruleRounding_" + NumCast(this.props.Document.heading)]) : undefined; let br = StrCast(this.layoutDoc.layout instanceof Doc ? this.layoutDoc.layout.borderRounding : this.props.Document.borderRounding); + br = !br && ruleRounding ? ruleRounding : br; if (br.endsWith("%")) { let percent = Number(br.substr(0, br.length - 1)) / 100; let nativeDim = Math.min(NumCast(this.layoutDoc.nativeWidth), NumCast(this.layoutDoc.nativeHeight)); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3f0b62511..7b9ed12a7 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -793,9 +793,15 @@ export class DocumentView extends DocComponent(Docu render() { - let backgroundColor = this.layoutDoc.isBackground || (this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document.clusterOverridesDefaultBackground && this.layoutDoc.backgroundColor === this.layoutDoc.defaultBackgroundColor) ? + let ruleProvider = this.props.Document.ruleProvider as Doc; + let ruleColor = ruleProvider ? StrCast(Doc.GetProto(ruleProvider)["ruleColor_" + NumCast(this.props.Document.heading)]) : undefined; + let ruleRounding = ruleProvider ? StrCast(Doc.GetProto(ruleProvider)["ruleRounding_" + NumCast(this.props.Document.heading)]) : undefined; + let colorSet = this.layoutDoc.backgroundColor !== this.layoutDoc.defaultBackgroundColor; + let clusterCol = this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document.clusterOverridesDefaultBackground; + + let backgroundColor = this.layoutDoc.isBackground || (clusterCol && !colorSet) ? this.props.backgroundColor(this.layoutDoc) || StrCast(this.layoutDoc.backgroundColor) : - StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.layoutDoc); + ruleColor && !colorSet ? ruleColor : StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.layoutDoc); let foregroundColor = StrCast(this.layoutDoc.color); var nativeWidth = this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? `${this.nativeWidth}px` : "100%"; var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%"; @@ -811,7 +817,7 @@ export class DocumentView extends DocComponent(Docu } let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith(" diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 444b91b28..658e2a04d 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -284,8 +284,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe e.stopPropagation(); } else if (de.data instanceof DragManager.DocumentDragData) { const draggedDoc = de.data.draggedDocuments.length && de.data.draggedDocuments[0]; - if (draggedDoc && draggedDoc.type === DocumentType.TEXT && StrCast(draggedDoc.layout) !== "") { - this.props.Document.layout = draggedDoc; + if (draggedDoc && draggedDoc.type === DocumentType.TEXT) { + this.props.Document.layout = draggedDoc.layout instanceof Doc ? draggedDoc.layout : draggedDoc; draggedDoc.isTemplate = true; e.stopPropagation(); } -- cgit v1.2.3-70-g09d2 From 233893698083cbcfcf39ddad8b57049aeb1ba842 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 13 Sep 2019 14:18:55 -0400 Subject: refactored how ruleProvider's work. overloaded custom template for creating metadata fields --- src/client/util/RichTextRules.ts | 8 +++---- src/client/util/TooltipTextMenu.tsx | 4 ++-- src/client/views/DocumentDecorations.tsx | 11 ++------- src/client/views/InkingControl.tsx | 5 ++-- src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/MainView.tsx | 2 ++ src/client/views/TemplateMenu.tsx | 16 ++++++------- .../views/collections/CollectionDockingView.tsx | 1 + .../views/collections/CollectionSchemaView.tsx | 1 + src/client/views/collections/CollectionSubView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 27 +++++++++++----------- .../collections/collectionFreeForm/MarqueeView.tsx | 2 -- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 13 +++++++---- src/client/views/nodes/FieldView.tsx | 1 + src/client/views/nodes/FormattedTextBox.tsx | 2 +- .../views/presentationview/PresentationElement.tsx | 1 + src/client/views/search/SearchItem.tsx | 1 + src/new_fields/Doc.ts | 2 +- 19 files changed, 51 insertions(+), 51 deletions(-) (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx') diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index c0c62463a..c727eec73 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -61,7 +61,7 @@ export const inpRules = { new RegExp(/^#([0-9]+)\s$/), (state, match, start, end) => { let size = Number(match[1]); - let ruleProvider = Cast(FormattedTextBox.InputBoxOverlay!.props.Document.ruleProvider, Doc) as Doc; + let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = Number(match[1]); @@ -74,7 +74,7 @@ export const inpRules = { (state, match, start, end) => { let node = (state.doc.resolve(start) as any).nodeAfter; let sm = state.storedMarks || undefined; - let ruleProvider = Cast(FormattedTextBox.InputBoxOverlay!.props.Document.ruleProvider, Doc) as Doc; + let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleAlign_" + heading] = "center"; @@ -88,7 +88,7 @@ export const inpRules = { (state, match, start, end) => { let node = (state.doc.resolve(start) as any).nodeAfter; let sm = state.storedMarks || undefined; - let ruleProvider = Cast(FormattedTextBox.InputBoxOverlay!.props.Document.ruleProvider, Doc) as Doc; + let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleAlign_" + heading] = "left"; @@ -100,7 +100,7 @@ export const inpRules = { (state, match, start, end) => { let node = (state.doc.resolve(start) as any).nodeAfter; let sm = state.storedMarks || undefined; - let ruleProvider = Cast(FormattedTextBox.InputBoxOverlay!.props.Document.ruleProvider, Doc) as Doc; + let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleAlign_" + heading] = "right"; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index c376b6f86..84d045e6f 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -496,7 +496,7 @@ export class TooltipTextMenu { if (markType.name[0] === 'p') { let size = this.fontSizeToNum.get(markType); if (size) { this.updateFontSizeDropdown(String(size) + " pt"); } - let ruleProvider = Cast(this.editorProps.Document.ruleProvider, Doc) as Doc; + let ruleProvider = this.editorProps.ruleProvider; let heading = NumCast(this.editorProps.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleSize_" + heading] = size; @@ -505,7 +505,7 @@ export class TooltipTextMenu { else { let fontName = this.fontStylesToName.get(markType); if (fontName) { this.updateFontStyleDropdown(fontName); } - let ruleProvider = Cast(this.editorProps.Document.ruleProvider, Doc) as Doc; + let ruleProvider = this.editorProps.ruleProvider; let heading = NumCast(this.editorProps.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleFont_" + heading] = fontName; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 6d63e8f73..ebdf2a749 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -365,14 +365,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> Math.abs(e.pageY - this._downY) < Utils.DRAG_THRESHOLD) { let docViews = SelectionManager.ViewsSortedVertically(); let topDocView = docViews[0]; - let ind = topDocView.templates.indexOf(Templates.Bullet.Layout); - if (ind !== -1) { - topDocView.templates.splice(ind, 1); - topDocView.props.Document.subBulletDocs = undefined; - } else { - topDocView.addTemplate(Templates.Bullet); - topDocView.props.Document.subBulletDocs = new List(docViews.filter(v => v !== topDocView).map(v => v.props.Document.proto!)); - } + topDocView.props.Document.subBulletDocs = new List(docViews.filter(v => v !== topDocView).map(v => v.props.Document.proto!)); } } this._removeIcon = false; @@ -439,7 +432,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let usingRule = false; SelectionManager.SelectedDocuments().map(dv => { let cv = dv.props.ContainingCollectionView; - let ruleProvider = cv && (Cast(cv.props.Document.ruleProvider, Doc) as Doc); + let ruleProvider = cv && cv.props.ruleProvider; let heading = NumCast(dv.props.Document.heading); ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`); usingRule = usingRule || (ruleProvider && heading ? true : false); diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index 867735c0b..86d0fc0be 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -71,9 +71,8 @@ export class InkingControl extends React.Component { targetDoc.backgroundColor = this._selectedColor; if (view.props.Document.heading) { let cv = view.props.ContainingCollectionView; - let ruleProvider = cv && (Cast(cv.props.Document.ruleProvider, Doc) as Doc); - let parback = cv && StrCast(cv.props.Document.backgroundColor); - cv && parback && (Doc.GetProto(ruleProvider ? ruleProvider : cv.props.Document)["ruleColor_" + NumCast(view.props.Document.heading)] = Utils.toRGBAstr(color.rgb)); + let ruleProvider = cv && (Cast(cv.props.ruleProvider, Doc) as Doc); + cv && (Doc.GetProto(ruleProvider ? ruleProvider : cv.props.Document)["ruleColor_" + NumCast(view.props.Document.heading)] = Utils.toRGBAstr(color.rgb)); // if (parback && cv && parback.indexOf("rgb") !== -1) { // let parcol = Utils.fromRGBAstr(parback); // let hsl = Utils.RGBToHSL(parcol.r, parcol.g, parcol.b); diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index c3a2cb214..71fb2707d 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -72,7 +72,6 @@ export class MainOverlayTextBox extends React.Component if (this._textTargetDiv) { this._textTargetDiv.style.color = this._textColor; } - this._textAutoHeight = autoHeight; this.TextFieldKey = textFieldKey!; let txf = tx ? tx : () => Transform.Identity(); this._textXf = txf; @@ -143,6 +142,7 @@ export class MainOverlayTextBox extends React.Component Document={FormattedTextBox.InputBoxOverlay.props.Document} DataDoc={FormattedTextBox.InputBoxOverlay.props.DataDoc} onClick={undefined} + ruleProvider={this._textBox ? this._textBox.props.ruleProvider : undefined} ChromeHeight={this.ChromeHeight} isSelected={returnTrue} select={emptyFunction} renderDepth={0} ContainingCollectionView={undefined} whenActiveChanged={emptyFunction} active={returnTrue} ContentScaling={returnOne} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index b64986084..2cec1c052 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -322,6 +322,7 @@ export class MainView extends React.Component { addDocTab={emptyFunction} pinToPres={emptyFunction} onClick={undefined} + ruleProvider={undefined} removeDocument={undefined} ScreenToLocalTransform={Transform.Identity} ContentScaling={returnOne} @@ -385,6 +386,7 @@ export class MainView extends React.Component { addDocTab={this.addDocTabFunc} pinToPres={emptyFunction} removeDocument={undefined} + ruleProvider={undefined} onClick={undefined} ScreenToLocalTransform={Transform.Identity} ContentScaling={returnOne} diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 0ef1a137d..060191e29 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -51,16 +51,16 @@ export class TemplateMenu extends React.Component { @observable private _hidden: boolean = true; dragRef = React.createRef(); - constructor(props: TemplateMenuProps) { - super(props); - } - toggleCustom = (e: React.MouseEvent): void => { this.props.docs.map(dv => { - if (dv.Document.type !== DocumentType.COL && dv.Document.type !== DocumentType.TEMPLATE) { - dv.makeCustomViewClicked(); - } else if (dv.Document.nativeLayout) { - dv.makeNativeViewClicked(); + if (dv.props.ContainingCollectionView && dv.props.ContainingCollectionView.props.DataDoc) { + Doc.MakeMetadataFieldTemplate(dv.props.Document, dv.props.ContainingCollectionView.props.DataDoc) + } else { + if (dv.Document.type !== DocumentType.COL && dv.Document.type !== DocumentType.TEMPLATE) { + dv.makeCustomViewClicked(); + } else if (dv.Document.nativeLayout) { + dv.makeNativeViewClicked(); + } } }); } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index fb8b0c41b..166fa0811 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -631,6 +631,7 @@ export class DockedFrameRenderer extends React.Component { bringToFront={emptyFunction} addDocument={undefined} removeDocument={undefined} + ruleProvider={undefined} ContentScaling={this.contentScaling} PanelWidth={this.panelWidth} PanelHeight={this.panelHeight} diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 9d83aa6c1..dca1d7c1d 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -995,6 +995,7 @@ export class CollectionSchemaPreview extends React.Component(schemaCtor: (doc: Doc) => T) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9a8ae3535..4a3e5039a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -257,18 +257,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY()); private addLiveTextBox = (newBox: Doc) => { FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed - let heading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0); - heading = heading === 0 || this.childDocs.length === 0 ? 1 : heading === 1 ? 2 : 0; + let maxHeading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0); + let heading = maxHeading === 0 || this.childDocs.length === 0 ? 1 : maxHeading === 1 ? 2 : 0; if (heading === 0) { let sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 : DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date < DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? -1 : 0); - heading = !sorted.length ? 1 : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading); - } - newBox.heading = heading; - - if (Cast(this.props.Document.ruleProvider, Doc) as Doc) { - newBox.ruleProvider = Doc.GetProto(Cast(this.props.Document.ruleProvider, Doc) as Doc); + heading = !sorted.length ? Math.max(1, maxHeading) : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading); } + !this.props.Document.isRuleProvider && (newBox.heading = heading); this.addDocument(newBox, false); } private addDocument = (newBox: Doc, allowDuplicates: boolean) => { @@ -698,6 +694,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { addDocument: this.props.addDocument, removeDocument: this.props.removeDocument, moveDocument: this.props.moveDocument, + ruleProvider: this.props.Document.isRuleProvider && childLayout.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider, onClick: this.props.onClick, ScreenToLocalTransform: childLayout.z ? this.getTransformOverlay : this.getTransform, renderDepth: this.props.renderDepth + 1, @@ -723,6 +720,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { addDocument: this.props.addDocument, removeDocument: this.props.removeDocument, moveDocument: this.props.moveDocument, + ruleProvider: this.props.ruleProvider, onClick: this.props.onClick, ScreenToLocalTransform: this.getTransform, renderDepth: this.props.renderDepth, @@ -817,6 +815,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (pair.layout && !(pair.data instanceof Promise)) { prev.push({ ele: , @@ -873,6 +872,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }, "arrange contents"); } + autoFormat = () => { + this.props.Document.isRuleProvider = !this.props.Document.isRuleProvider; + this.childDocs.map(child => child.heading = undefined); + } + analyzeStrokes = async () => { let data = Cast(this.fieldExtensionDoc[this.inkKey], InkField); if (!data) { @@ -900,11 +904,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }, icon: !this.props.Document.useClusters ? "braille" : "braille" }); - layoutItems.push({ - description: `${this.props.Document.isRuleProvider ? "Stop Auto Format" : "Auto Format"}`, - event: () => this.props.Document.isRuleProvider = !this.props.Document.isRuleProvider, - icon: !this.props.Document.useClusters ? "chalkboard" : "chalkboard" - }); + layoutItems.push({ description: `${this.props.Document.isRuleProvider ? "Stop Auto Format" : "Auto Format"}`, event: this.autoFormat, icon: !this.props.Document.isRuleProvider ? "chalkboard" : "chalkboard" }); layoutItems.push({ description: "Arrange contents in grid", event: this.arrangeContents, icon: "table" }); layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" }); layoutItems.push({ description: "Jitter Rotation", event: action(() => this.props.Document.jitterRotation = 10), icon: "paint-brush" }); @@ -1034,7 +1034,6 @@ class CollectionFreeFormOverlayView extends React.Component boolean }> { @computed get backgroundView() { - let props = this.props; return (); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 4308497a1..e46e8cb88 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -329,7 +329,6 @@ export class MarqueeView extends React.Component selected = [newCollection]; newCollection.x = bounds.left + bounds.width; summary.proto!.subBulletDocs = new List(selected); - summary.templates = new List([Templates.Bullet.Layout]); let container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, chromeStatus: "disabled", title: "-summary-" }); container.viewType = CollectionViewType.Stacking; container.autoHeight = true; @@ -356,7 +355,6 @@ export class MarqueeView extends React.Component this.props.addLiveTextDocument(summary); } else { - newCollection.ruleProvider = this.props.container.props.Document.isRuleProvider ? this.props.container.props.Document : this.props.container.props.Document.ruleProvider; this.props.addDocument(newCollection, false); this.props.selectDocuments([newCollection]); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 082e5c5e3..4872a7aa1 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -74,7 +74,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { - let ruleProvider = this.props.Document.ruleProvider as Doc; + let ruleProvider = this.props.ruleProvider; let ruleRounding = ruleProvider ? StrCast(Doc.GetProto(ruleProvider)["ruleRounding_" + NumCast(this.props.Document.heading)]) : undefined; let br = StrCast(this.layoutDoc.layout instanceof Doc ? this.layoutDoc.layout.borderRounding : this.props.Document.borderRounding); br = !br && ruleRounding ? ruleRounding : br; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0816cb813..cc04c5a9f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,6 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import * as fa from '@fortawesome/free-solid-svg-icons'; -import { action, computed, IReactionDisposer, reaction, runInAction, trace, observable } from "mobx"; +import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as rp from "request-promise"; import { Doc, DocListCast, DocListCastAsync, HeightSym, Opt, WidthSym } from "../../../new_fields/Doc"; @@ -9,12 +9,13 @@ import { List } from "../../../new_fields/List"; import { ObjectField } from "../../../new_fields/ObjectField"; import { createSchema, listSpec, makeInterface } from "../../../new_fields/Schema"; import { ScriptField } from '../../../new_fields/ScriptField'; -import { BoolCast, Cast, FieldValue, NumCast, StrCast, PromiseValue } from "../../../new_fields/Types"; +import { BoolCast, Cast, FieldValue, NumCast, PromiseValue, StrCast } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { RouteStore } from '../../../server/RouteStore'; import { emptyFunction, returnTrue, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { Docs, DocUtils } from "../../documents/Documents"; +import { DocumentType } from '../../documents/DocumentTypes'; import { ClientUtils } from '../../util/ClientUtils'; import { DictationManager } from '../../util/DictationManager'; import { DocumentManager } from "../../util/DocumentManager"; @@ -35,12 +36,10 @@ import { MainView } from '../MainView'; import { OverlayView } from '../OverlayView'; import { ScriptBox } from '../ScriptBox'; import { ScriptingRepl } from '../ScriptingRepl'; -import { Template } from "./../Templates"; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import { FormattedTextBox } from './FormattedTextBox'; import React = require("react"); -import { DocumentType } from '../../documents/DocumentTypes'; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? library.add(fa.faTrash); @@ -89,6 +88,7 @@ export interface DocumentViewProps { renderDepth: number; showOverlays?: (doc: Doc) => { title?: string, caption?: string }; ContentScaling: () => number; + ruleProvider: Doc | undefined; PanelWidth: () => number; PanelHeight: () => number; focus: (doc: Doc, willZoom: boolean, scale?: number) => void; @@ -470,6 +470,9 @@ export class DocumentView extends DocComponent(Docu this.props.Document.type === DocumentType.VID ? Docs.Create.VideoDocument("http://www.cs.brown.edu", options) : Docs.Create.ImageDocument("http://www.cs.brown.edu", options); + fieldTemplate.backgroundColor = StrCast(this.props.Document.backgroundColor); + fieldTemplate.heading = 1; + let docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: StrCast(this.Document.title) + "layout", width: NumCast(this.props.Document.width) + 20, height: Math.max(100, NumCast(this.props.Document.height) + 45) }); let proto = Doc.GetProto(docTemplate); Doc.MakeMetadataFieldTemplate(fieldTemplate, proto); @@ -800,7 +803,7 @@ export class DocumentView extends DocComponent(Docu render() { - let ruleProvider = this.props.Document.ruleProvider as Doc; + let ruleProvider = this.props.ruleProvider; let ruleColor = ruleProvider ? StrCast(Doc.GetProto(ruleProvider)["ruleColor_" + NumCast(this.props.Document.heading)]) : undefined; let ruleRounding = ruleProvider ? StrCast(Doc.GetProto(ruleProvider)["ruleRounding_" + NumCast(this.props.Document.heading)]) : undefined; let colorSet = this.layoutDoc.backgroundColor !== this.layoutDoc.defaultBackgroundColor; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index d9774303b..943d181d6 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -30,6 +30,7 @@ export interface FieldViewProps { leaveNativeSize?: boolean; fitToBox?: boolean; ContainingCollectionView: Opt; + ruleProvider: Doc | undefined; Document: Doc; DataDoc?: Doc; onClick?: ScriptField; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index d39291743..a0dc054cf 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -458,7 +458,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this._rulesReactionDisposer = reaction(() => { - let ruleProvider = Cast(this.props.Document.ruleProvider, Doc); + let ruleProvider = this.props.ruleProvider; let heading = NumCast(this.props.Document.heading); if (ruleProvider instanceof Doc) { return { diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 80aa25f48..7be44faf6 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -351,6 +351,7 @@ export default class PresentationElement extends React.Component { Document={this.props.doc} addDocument={returnFalse} removeDocument={returnFalse} + ruleProvider={undefined} ScreenToLocalTransform={Transform.Identity} addDocTab={returnFalse} pinToPres={returnFalse} diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 1a3d689bb..5b22a62a1 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -560,7 +560,7 @@ export namespace Doc { export function MakeMetadataFieldTemplate(fieldTemplate: Doc, templateDataDoc: Doc) { // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??) - let metadataFieldName = StrCast(fieldTemplate.title); + let metadataFieldName = StrCast(fieldTemplate.title).replace(/^-/, ""); let backgroundLayout = StrCast(fieldTemplate.backgroundLayout); let fieldLayoutDoc = fieldTemplate; if (fieldTemplate.layout instanceof Doc) { -- cgit v1.2.3-70-g09d2