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/nodes/CollectionFreeFormDocumentView.tsx | 4 +++- 1 file changed, 3 insertions(+), 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 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