diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 55 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 14 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 12 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 18 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 41 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 8 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 2 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 10 |
8 files changed, 101 insertions, 59 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index fdfff86db..76c2d71e8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -26,6 +26,7 @@ import { Template, Templates } from "./Templates"; import React = require("react"); import { RichTextField } from '../../new_fields/RichTextField'; import { LinkManager } from '../util/LinkManager'; +import { ObjectField } from '../../new_fields/ObjectField'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -77,39 +78,31 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this._fieldKey = text.slice(1, text.length); this._title = this.selectionTitle; } else if (text.startsWith(">")) { - let field = SelectionManager.SelectedDocuments()[0]; - let collection = field.props.ContainingCollectionView!.props.Document; - - let collectionKey = field.props.ContainingCollectionView!.props.fieldKey; - let collectionKeyProp = `fieldKey={"${collectionKey}"}`; + let fieldTemplateView = SelectionManager.SelectedDocuments()[0]; + SelectionManager.DeselectAll(); + let fieldTemplate = fieldTemplateView.props.Document; + let docTemplate = fieldTemplateView.props.ContainingCollectionView!.props.Document; 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)]); - if (field.props.Document.backgroundLayout) { - let metaAnoKeyProp = `fieldKey={"${metaKey}"} fieldExt={"annotations"}`; - let collectionAnoKeyProp = `fieldKey={"annotations"}`; - template.layout = StrCast(field.props.Document.layout).replace(collectionAnoKeyProp, metaAnoKeyProp); - template.backgroundLayout = StrCast(field.props.Document.backgroundLayout).replace(collectionKeyProp, metaKeyProp); - } else { - template.layout = StrCast(field.props.Document.layout).replace(collectionKeyProp, metaKeyProp); + + // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??) + let backgroundLayout = StrCast(fieldTemplate.backgroundLayout); + let layout = StrCast(fieldTemplate.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`); + if (backgroundLayout) { + layout = StrCast(fieldTemplate.layout).replace(/fieldKey={"annotations"}/, `fieldKey={"${metaKey}"} fieldExt={"annotations"}`); + backgroundLayout = backgroundLayout.replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`); } - Doc.AddDocToList(collection, collectionKey, template); - SelectionManager.SelectedDocuments().map(dv => dv.props.removeDocument && dv.props.removeDocument(dv.props.Document)); + let nw = Cast(fieldTemplate.nativeWidth, "number"); + let nh = Cast(fieldTemplate.nativeHeight, "number"); + + fieldTemplate.title = metaKey; + fieldTemplate.layout = layout; + fieldTemplate.backgroundLayout = backgroundLayout; + fieldTemplate.nativeWidth = nw; + fieldTemplate.nativeHeight = nh; + fieldTemplate.embed = true; + fieldTemplate.isTemplate = true; + fieldTemplate.templates = new List<string>([Templates.TitleBar(metaKey)]); + fieldTemplate.proto = Doc.GetProto(docTemplate); } else { if (SelectionManager.SelectedDocuments().length > 0) { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 98bf513bb..5562676e9 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -349,12 +349,22 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />; } + @computed get previewPanel() { + // let layoutDoc = this.previewDocument; + // let resolvedDataDoc = (layoutDoc !== this.props.DataDoc) ? this.props.DataDoc : undefined; + // if (layoutDoc && !(Cast(layoutDoc.layout, Doc) instanceof Doc) && + // resolvedDataDoc && resolvedDataDoc !== layoutDoc) { + // // ... so change the layout to be an expanded view of the template layout. This allows the view override the template's properties and be referenceable as its own document. + // layoutDoc = Doc.expandTemplateLayout(layoutDoc, resolvedDataDoc); + // } + + let layoutDoc = this.previewDocument ? Doc.expandTemplateLayout(this.previewDocument, this.props.DataDoc) : undefined; return <div ref={this.createTarget}> <CollectionSchemaPreview - Document={this.previewDocument} - DataDocument={BoolCast(this.props.Document.isTemplate) ? this.previewDocument : this.props.DataDoc} + Document={layoutDoc} + DataDocument={this.previewDocument !== this.props.DataDoc ? this.props.DataDoc : undefined} childDocs={this.childDocs} renderDepth={this.props.renderDepth} width={this.previewWidth} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 6c4ea18a1..088a9bae8 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -4,12 +4,13 @@ import { action, computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; -import { BoolCast, NumCast } from "../../../new_fields/Types"; +import { BoolCast, NumCast, Cast } from "../../../new_fields/Types"; import { emptyFunction, Utils } from "../../../Utils"; import { ContextMenu } from "../ContextMenu"; import { CollectionSchemaPreview } from "./CollectionSchemaView"; import "./CollectionStackingView.scss"; import { CollectionSubView } from "./CollectionSubView"; +import { resolve } from "bluebird"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -66,17 +67,18 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { get singleColumnChildren() { let children = this.childDocs.filter(d => !d.isMinimized); return children.map((d, i) => { + let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc); let dref = React.createRef<HTMLDivElement>(); - let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]()); + let dxf = () => this.getDocTransform(layoutDoc, dref.current!).scale(this.columnWidth / d[WidthSym]()); let width = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth; - let height = () => this.singleColDocHeight(d); + let height = () => this.singleColDocHeight(layoutDoc); return <div className="collectionStackingView-columnDoc" key={d[Id]} ref={dref} style={{ width: width(), height: height() }} > <CollectionSchemaPreview - Document={d} - DataDocument={this.props.Document.layout instanceof Doc ? this.props.Document : this.props.DataDoc} + Document={layoutDoc} + DataDocument={d != this.props.DataDoc ? this.props.DataDoc : undefined} renderDepth={this.props.renderDepth} width={width} height={height} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ccd0e92af..9e0130281 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -183,16 +183,20 @@ class TreeView extends React.Component<TreeViewProps> { let keys = Array.from(Object.keys(this.resolvedDataDoc)); if (this.resolvedDataDoc.proto instanceof Doc) { keys.push(...Array.from(Object.keys(this.resolvedDataDoc.proto))); - while (keys.indexOf("proto") !== -1) keys.splice(keys.indexOf("proto"), 1); } - let keyList: string[] = keys.reduce((l, key) => Cast(this.resolvedDataDoc[key], listSpec(Doc)) ? [...l, key] : l, [] as string[]); + let keyList: string[] = keys.reduce((l, key) => { + let listspec = DocListCast(this.resolvedDataDoc[key]); + if (listspec && listspec.length) + return [...l, key]; + return l; + }, [] as string[]); keys.map(key => Cast(this.resolvedDataDoc[key], Doc) instanceof Doc && keyList.push(key)); if (LinkManager.Instance.getAllRelatedLinks(this.props.document).length > 0) keyList.push("links"); if (keyList.indexOf(this.fieldKey) !== -1) { keyList.splice(keyList.indexOf(this.fieldKey), 1); } keyList.splice(0, 0, this.fieldKey); - return keyList; + return keyList.filter((item, index) => keyList.indexOf(item) >= index); } /** * Renders the EditableView title element for placement into the tree. @@ -322,14 +326,14 @@ class TreeView extends React.Component<TreeViewProps> { this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth)} </ul >; } else { - console.log("PW = " + this.props.panelWidth()); - contentElement = <div ref={this._dref} style={{ display: "inline-block", height: this.props.panelHeight() }} key={this.props.document[Id]}> + let layoutDoc = Doc.expandTemplateLayout(this.props.document, this.props.dataDoc); + contentElement = <div ref={this._dref} style={{ display: "inline-block", height: layoutDoc[HeightSym]() }} key={this.props.document[Id]}> <CollectionSchemaPreview - Document={this.props.document} + Document={layoutDoc} DataDocument={this.resolvedDataDoc} renderDepth={this.props.renderDepth} width={docWidth} - height={this.props.panelHeight} + height={layoutDoc[HeightSym]} getTransform={this.docTransform} CollectionView={undefined} addDocument={emptyFunction as any} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 128525a48..bbec33ba3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -335,16 +335,12 @@ 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); - } + + getChildDocumentViewProps(childDocLayout: Doc): DocumentViewProps { + let resolvedDataDoc = this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined; + let layoutDoc = Doc.expandTemplateLayout(childDocLayout, resolvedDataDoc); return { - DataDoc: datadoc, + DataDoc: resolvedDataDoc !== layoutDoc && resolvedDataDoc ? resolvedDataDoc : layoutDoc, Document: layoutDoc, addDocument: this.props.addDocument, removeDocument: this.props.removeDocument, @@ -365,6 +361,29 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { getScale: this.getScale }; } + getDocumentViewProps(layoutDoc: Doc): DocumentViewProps { + return { + DataDoc: this.props.DataDoc, + Document: this.props.Document, + addDocument: this.props.addDocument, + removeDocument: this.props.removeDocument, + moveDocument: this.props.moveDocument, + ScreenToLocalTransform: this.getTransform, + renderDepth: this.props.renderDepth + 1, + selectOnLoad: layoutDoc[Id] === this._selectOnLoaded, + PanelWidth: layoutDoc[WidthSym], + PanelHeight: layoutDoc[HeightSym], + ContentScaling: returnOne, + ContainingCollectionView: this.props.CollectionView, + focus: this.focusDocument, + parentActive: this.props.active, + whenActiveChanged: this.props.whenActiveChanged, + bringToFront: this.bringToFront, + addDocTab: this.props.addDocTab, + zoomToScale: this.zoomToScale, + getScale: this.getScale + }; + } @computed.struct get views() { @@ -375,7 +394,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (Math.round(page) === Math.round(curPage) || page === -1) { let minim = BoolCast(doc.isMinimized, false); if (minim === undefined || !minim) { - prev.push(<CollectionFreeFormDocumentView key={doc[Id]} {...this.getDocumentViewProps(doc)} />); + prev.push(<CollectionFreeFormDocumentView key={doc[Id]} {...this.getChildDocumentViewProps(doc)} />); } } return prev; @@ -419,7 +438,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } private childViews = () => [ - <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} DataDoc={this.props.DataDoc} />, + <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} />, ...this.views ] render() { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 2a45aeb43..ba6808737 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -211,7 +211,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe const field = this.dataDoc ? Cast(this.dataDoc[this.props.fieldKey], RichTextField) : undefined; return field ? field.Data : `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`; }, - field => this._editorView && !this._applyingChange && + field => this._editorView && !this._applyingChange && this.props.Document[this.props.fieldKey] instanceof RichTextField && this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field))) ); this.setupEditor(config, this.dataDoc, this.props.fieldKey); @@ -247,6 +247,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this.props.selectOnLoad) { if (!this.props.isOverlay) this.props.select(false); else this._editorView!.focus(); + this.tryUpdateHeight(); } } @@ -382,6 +383,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (!this._undoTyping) { this._undoTyping = UndoManager.StartBatch("undoTyping"); } + this.tryUpdateHeight(); + } + + @action + tryUpdateHeight() { if (this.props.isOverlay && this.props.Document.autoHeight) { let xf = this._ref.current!.getBoundingClientRect(); let scrBounds = this.props.ScreenToLocalTransform().transformBounds(0, 0, xf.width, xf.height); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 378b13b0d..06bf65f73 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -205,7 +205,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD requestImageSize(window.origin + RouteStore.corsProxy + "/" + srcpath) .then((size: any) => { let aspect = size.height / size.width; - if (layoutdoc[HeightSym]() / layoutdoc[WidthSym]() != aspect) { + if (Math.abs(layoutdoc[HeightSym]() / layoutdoc[WidthSym]() - aspect) > 0.01) { setTimeout(action(() => { layoutdoc.height = layoutdoc[WidthSym]() * aspect; layoutdoc.nativeHeight = size.height; diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index d552ddd2d..27dcfba08 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -280,7 +280,15 @@ export namespace Doc { return new Doc; } - export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc: Doc) { + export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc?: Doc) { + let resolvedDataDoc = (templateLayoutDoc !== dataDoc) ? dataDoc : undefined; + if (!dataDoc || !(templateLayoutDoc && !(Cast(templateLayoutDoc.layout, Doc) instanceof Doc) && resolvedDataDoc && resolvedDataDoc !== templateLayoutDoc)) { + return templateLayoutDoc; + } + // if we have a data doc that doesn't match the layout, then we're rendering a template. + // ... which means we change the layout to be an expanded view of the template layout. + // This allows the view override the template's properties and be referenceable as its own document. + let expandedTemplateLayout = templateLayoutDoc["_expanded_" + dataDoc[Id]]; if (expandedTemplateLayout instanceof Doc) { return expandedTemplateLayout; |