diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2019-06-28 03:00:30 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2019-06-28 03:00:30 -0400 |
commit | dc4b658639beb21e73fc2411abd147ff6716ba3d (patch) | |
tree | 90cb2951006a3a4ceb613dcaa4ec3c8851d4869a /src | |
parent | 2ca24a234817495c3330b93b504b13c0c6db91f3 (diff) |
added expansion of templates on demand
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 7 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 5 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/FieldView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 44 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 13 |
7 files changed, 63 insertions, 17 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index db10007f4..fdfff86db 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -85,11 +85,18 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let metaKey = text.slice(1, text.length); let metaKeyProp = `fieldKey={"${metaKey}"}`; + let layoutProto = Doc.GetProto(field.props.Document); let template = Doc.MakeAlias(field.props.Document); template.proto = collection; template.title = metaKey; template.nativeWidth = Cast(field.nativeWidth, "number"); template.nativeHeight = Cast(field.nativeHeight, "number"); + template.width = NumCast(field.props.Document.width); + template.height = NumCast(field.props.Document.height); + template.panX = NumCast(field.props.Document.panX); + template.panY = NumCast(field.props.Document.panY); + template.x = NumCast(field.props.Document.x); + template.y = NumCast(field.props.Document.y); template.embed = true; template.isTemplate = true; template.templates = new List<string>([Templates.TitleBar(metaKey)]); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 5c80fbd38..ccd0e92af 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -233,7 +233,7 @@ class TreeView extends React.Component<TreeViewProps> { onWorkspaceContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped()) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Open as Workspace", event: undoBatch(() => MainView.Instance.openWorkspace(this.resolvedDataDoc)) }); - ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, kvp, "onRight"); }, icon: "layer-group" }); + ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" }); if (NumCast(this.props.document.viewType) !== CollectionViewType.Docking) { ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.resolvedDataDoc, "inTab"), icon: "folder" }); ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.resolvedDataDoc, "onRight"), icon: "caret-square-right" }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 15185ecb0..128525a48 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -28,6 +28,7 @@ import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); + export const panZoomSchema = createSchema({ panX: "number", panY: "number", @@ -334,11 +335,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return 1; } - getDocumentViewProps(layoutDoc: Doc): DocumentViewProps { let datadoc = BoolCast(this.props.Document.isTemplate) || this.props.DataDoc === this.props.Document ? undefined : this.props.DataDoc; if (Cast(layoutDoc.layout, Doc) instanceof Doc) { // if this document is using a template to render, then set the dataDoc for the template to be this document datadoc = layoutDoc; + } else if (datadoc && datadoc !== layoutDoc) { // if this view has a dataDocument and it's not the same as the view document + // then map the view document to an instance of itself (ie, expand the template). This allows the view override the template's properties and be referenceable as document. + layoutDoc = Doc.expandTemplateLayout(layoutDoc, datadoc); } return { DataDoc: datadoc, diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4ac43ef4d..2ee694225 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -393,7 +393,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); }; - fieldsClicked = (): void => { let kvp = Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }); this.props.addDocTab(kvp, kvp, "onRight"); }; + fieldsClicked = (): void => { let kvp = Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.dataDoc, "onRight"); }; makeBtnClicked = (): void => { let doc = Doc.GetProto(this.props.Document); doc.isButton = !BoolCast(doc.isButton, false); diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 55f61ddff..7c8509722 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -18,6 +18,8 @@ import { ImageBox } from "./ImageBox"; import { PDFBox } from "./PDFBox"; import { VideoBox } from "./VideoBox"; import { Id } from "../../../new_fields/FieldSymbols"; +import { BoolCast, Cast } from "../../../new_fields/Types"; +import { DarpaDatasetDoc } from "../../northstar/model/idea/idea"; // @@ -28,6 +30,7 @@ import { Id } from "../../../new_fields/FieldSymbols"; export interface FieldViewProps { fieldKey: string; fieldExt: string; + leaveNativeSize?: boolean; ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>; Document: Doc; DataDoc?: Doc; @@ -72,7 +75,7 @@ export class FieldView extends React.Component<FieldViewProps> { return <FormattedTextBox {...this.props} />; } else if (field instanceof ImageField) { - return <ImageBox {...this.props} />; + return <ImageBox {...this.props} leaveNativeSize={true} />; } else if (field instanceof IconField) { return <IconBox {...this.props} />; @@ -86,7 +89,7 @@ export class FieldView extends React.Component<FieldViewProps> { return <p>{field.date.toLocaleString()}</p>; } else if (field instanceof Doc) { - return <p><b>{field.title + " + " + field[Id]}</b></p>; + return <p><b>{field.title + " : id= " + field[Id]}</b></p>; // let returnHundred = () => 100; // return ( // <DocumentContentsView Document={field} diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5c00d9d44..378b13b0d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -20,6 +20,8 @@ import { positionSchema } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); +import { RouteStore } from '../../../server/RouteStore'; +var requestImageSize = require('../../util/request-image-size'); var path = require('path'); @@ -27,7 +29,7 @@ library.add(faImage); export const pageSchema = createSchema({ - curPage: "number" + curPage: "number", }); type ImageDocument = makeInterface<[typeof pageSchema, typeof positionSchema]>; @@ -41,7 +43,6 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD private _downX: number = 0; private _downY: number = 0; private _lastTap: number = 0; - @observable private _photoIndex: number = 0; @observable private _isOpen: boolean = false; private dropDisposer?: DragManager.DragDropDisposer; @@ -115,20 +116,21 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD e.stopPropagation(); } + @action lightbox = (images: string[]) => { if (this._isOpen) { return (<Lightbox - mainSrc={images[this._photoIndex]} - nextSrc={images[(this._photoIndex + 1) % images.length]} - prevSrc={images[(this._photoIndex + images.length - 1) % images.length]} + mainSrc={images[this.Document.curPage || 0]} + nextSrc={images[((this.Document.curPage || 0) + 1) % images.length]} + prevSrc={images[((this.Document.curPage || 0) + images.length - 1) % images.length]} onCloseRequest={action(() => this._isOpen = false )} onMovePrevRequest={action(() => - this._photoIndex = (this._photoIndex + images.length - 1) % images.length + this.Document.curPage = ((this.Document.curPage || 0) + images.length - 1) % images.length )} onMoveNextRequest={action(() => - this._photoIndex = (this._photoIndex + 1) % images.length + this.Document.curPage = ((this.Document.curPage || 0) + 1) % images.length )} />); } @@ -160,7 +162,6 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD @action onDotDown(index: number) { - this._photoIndex = index; this.Document.curPage = index; } @@ -170,7 +171,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD let left = (nativeWidth - paths.length * dist) / 2; return paths.map((p, i) => <div className="imageBox-placer" key={i} > - <div className="imageBox-dot" style={{ background: (i === this._photoIndex ? "black" : "gray"), transform: `translate(${i * dist + left}px, 0px)` }} onPointerDown={(e: React.PointerEvent) => { e.stopPropagation(); this.onDotDown(i); }} /> + <div className="imageBox-dot" style={{ background: (i === this.Document.curPage ? "black" : "gray"), transform: `translate(${i * dist + left}px, 0px)` }} onPointerDown={(e: React.PointerEvent) => { e.stopPropagation(); this.onDotDown(i); }} /> </div> ); } @@ -199,6 +200,22 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD } } _curSuffix = "_m"; + + resize(srcpath: string, layoutdoc: Doc) { + requestImageSize(window.origin + RouteStore.corsProxy + "/" + srcpath) + .then((size: any) => { + let aspect = size.height / size.width; + if (layoutdoc[HeightSym]() / layoutdoc[WidthSym]() != aspect) { + setTimeout(action(() => { + layoutdoc.height = layoutdoc[WidthSym]() * aspect; + layoutdoc.nativeHeight = size.height; + layoutdoc.nativeWidth = size.width; + }), 0); + } + }) + .catch((err: any) => console.log(err)); + } + render() { // let transform = this.props.ScreenToLocalTransform().inverse(); let pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50; @@ -212,6 +229,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD let paths: string[] = ["http://www.cs.brown.edu/~bcz/noImage.png"]; // this._curSuffix = ""; // if (w > 20) { + Doc.UpdateDocumentExtensionForField(this.extensionDoc, this.props.fieldKey); let alts = DocListCast(this.extensionDoc.Alternates); let altpaths: string[] = alts.filter(doc => doc.data instanceof ImageField).map(doc => this.choosePath((doc.data as ImageField).url)); let field = this.dataDoc[this.props.fieldKey]; @@ -225,8 +243,10 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD let rotation = NumCast(this.dataDoc.rotation, 0); let aspect = (rotation % 180) ? this.dataDoc[HeightSym]() / this.dataDoc[WidthSym]() : 1; let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0; - Doc.UpdateDocumentExtensionForField(this.extensionDoc, this.props.fieldKey); - let srcpath = paths[Math.min(paths.length, this._photoIndex)]; + let srcpath = paths[Math.min(paths.length, this.Document.curPage || 0)]; + + if (!this.props.Document.ignoreAspect && !this.props.leaveNativeSize) this.resize(srcpath, this.props.Document); + return ( <div id={id} className={`imageBox-cont${interactive}`} style={{ background: "transparent" }} onPointerDown={this.onPointerDown} @@ -235,7 +255,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD key={this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys src={srcpath} style={{ transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})` }} - // style={{ objectFit: (this._photoIndex === 0 ? undefined : "contain") }} + // style={{ objectFit: (this.Document.curPage === 0 ? undefined : "contain") }} width={nativeWidth} ref={this._imgRef} onError={this.onError} /> diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index b0184dd4e..d552ddd2d 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -280,6 +280,19 @@ export namespace Doc { return new Doc; } + export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc: Doc) { + let expandedTemplateLayout = templateLayoutDoc["_expanded_" + dataDoc[Id]]; + if (expandedTemplateLayout instanceof Doc) { + return expandedTemplateLayout; + } + if (expandedTemplateLayout === undefined) + setTimeout(() => { + templateLayoutDoc["_expanded_" + dataDoc[Id]] = Doc.MakeDelegate(templateLayoutDoc); + (templateLayoutDoc["_expanded_" + dataDoc[Id]] as Doc).title = templateLayoutDoc.title + " applied to " + dataDoc.title; + }, 0); + return templateLayoutDoc; + } + export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc { const copy = new Doc; Object.keys(doc).forEach(key => { |