diff options
author | Fawn <fangrui_tong@brown.edu> | 2019-04-22 00:05:35 -0400 |
---|---|---|
committer | Fawn <fangrui_tong@brown.edu> | 2019-04-22 00:05:35 -0400 |
commit | e794b4b38e8ab2f4e7a79f223f9488cc845c724f (patch) | |
tree | 1d336bd0784463ac13f6505a884d6cbea09c41be /src | |
parent | 7ceac5f7f4cc8172bde90c2d495da3779901ef84 (diff) |
mutiple templates can be used
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 6 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 14 | ||||
-rw-r--r-- | src/client/views/TemplateMenu.tsx | 18 | ||||
-rw-r--r-- | src/client/views/Templates.tsx | 61 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 43 | ||||
-rw-r--r-- | src/fields/KeyStore.ts | 2 | ||||
-rw-r--r-- | src/fields/TemplateField.ts | 22 | ||||
-rw-r--r-- | src/server/Message.ts | 2 | ||||
-rw-r--r-- | src/server/ServerUtil.ts | 3 |
9 files changed, 106 insertions, 65 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index eba53273f..c93e65edb 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -50,7 +50,7 @@ export interface DocumentOptions { scale?: number; baseLayout?: string; layout?: string; - template?: Template; + templates?: Array<Template>; layoutKeys?: Key[]; viewType?: number; backgroundColor?: string; @@ -101,7 +101,7 @@ export namespace Documents { if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); } if (options.baseLayout !== undefined) { doc.SetText(KeyStore.BaseLayout, options.baseLayout); } if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); } - if (options.template !== undefined) { doc.Set(KeyStore.Template, new TemplateField(options.template)); } + if (options.templates !== undefined) { doc.Set(KeyStore.Templates, new TemplateField(options.templates)); } if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); } if (options.copyDraggedItems !== undefined) { doc.SetBoolean(KeyStore.CopyDraggedItems, options.copyDraggedItems); } return doc; @@ -118,7 +118,7 @@ export namespace Documents { } function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document { - return assignOptions(new Document(protoId), { ...options, title: title, layout: layout , baseLayout: layout}); + return assignOptions(new Document(protoId), { ...options, title: title, layout: layout, baseLayout: layout }); } function SetInstanceOptions<T, U extends Field & { Data: T }>(doc: Document, options: DocumentOptions, value: [T, { new(): U }] | Document, id?: string) { var deleg = doc.MakeDelegate(id); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 2a40d7347..2b22d9e19 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -17,7 +17,6 @@ import { LinkMenu } from "./nodes/LinkMenu"; import { TemplateMenu } from "./TemplateMenu"; import React = require("react"); import { Template, Templates } from "./Templates"; -import { TemplateField } from "../../fields/TemplateField"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -394,11 +393,16 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let templates: Map<Template, boolean> = new Map(); let doc = SelectionManager.SelectedDocuments()[0]; - Array.from(Object.values(Templates)).map(template => { - templates.set(template, doc.template.Name === template.Name); + Array.from(Object.values(Templates.TemplateList)).map(template => { + let docTemps = doc.templates; + let checked = false; + docTemps.forEach(temp => { + if (template.Name === temp.Name) { + checked = true; + } + }); + templates.set(template, checked); }); - // let docSrc = doc.props.Document.GetT(KeyStore.Prototype, TemplateField); - // console.log(docSrc); return (<div className="documentDecorations"> <div className="documentDecorations-background" style={{ diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 1e83463c8..8eb2fc6c6 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -38,15 +38,13 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> { @action toggleTemplate = (event: React.ChangeEvent<HTMLInputElement>, template: Template): void => { - this.props.doc.changeTemplate(template); - this._templates.forEach((checked, temp) => { - this._templates.set(temp, false); - }); - this._templates.set(template, true); - - // const docs = view.props.ContainingCollectionView; - // const docs = view.props.Document.GetList<Document>(view.props.fieldKey, []); - + if (event.target.checked) { + this.props.doc.addTemplate(template); + this._templates.set(template, true); + } else { + this.props.doc.removeTemplate(template); + this._templates.set(template, false); + } } @action @@ -67,7 +65,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> { return ( <div className="templating-menu" > - <div className="templating-button" onClick={() => this.toggleTemplateActivity()}>T</div> + <div className="templating-button" onClick={() => this.toggleTemplateActivity()}>+</div> <ul id="template-list" style={{ display: this._hidden ? "none" : "block" }}> {templateMenu} </ul> diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx index 3afdc711c..616bc2566 100644 --- a/src/client/views/Templates.tsx +++ b/src/client/views/Templates.tsx @@ -1,57 +1,66 @@ -import { observer } from "mobx-react"; -import { observable } from "mobx"; -import { action, computed } from "mobx"; import React = require("react"); -import { StringLiteral } from "babel-types"; + +export enum TemplatePosition { + InnerTop, + InnerBottom, + InnerRight, + InnerLeft, + OutterTop, + OutterBottom, + OutterRight, + OutterLeft, +} export class Template { - constructor(name: string, layout: string) { + constructor(name: string, position: TemplatePosition, layout: string) { this._name = name; + this._position = position; this._layout = layout; } private _name: string; + private _position: TemplatePosition; private _layout: string; get Name(): string { return this._name; } + get Position(): TemplatePosition { + return this._position; + } + get Layout(): string { return this._layout; } - } export namespace Templates { - export const BasicLayout = new Template("Basic layout", "{layout}"); + // export const BasicLayout = new Template("Basic layout", "{layout}"); - export const OuterCaption = new Template("Outer caption", + export const OuterCaption = new Template("Outer caption", TemplatePosition.OutterBottom, `<div><div style="margin:auto; height:calc(100%); width:100%;">{layout}</div><div style="height:(100% + 50px); width:100%; position:absolute"><FormattedTextBox doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={CaptionKey} isSelected={isSelected} select={select} selectOnLoad={SelectOnLoad} isTopMost={isTopMost}/></div></div>` ); - export const InnerCaption = new Template("Inner caption", - `<div> - <div style="margin:auto; height:calc(100% - 50px); width:100%;"> - {layout} - </div> - <div style="height:50px; width:100%; position:absolute"> - <FormattedTextBox doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={CaptionKey} isSelected={isSelected} select={select} selectOnLoad={SelectOnLoad} isTopMost={isTopMost}/> - </div> - </div>` + export const InnerCaption = new Template("Inner caption", TemplatePosition.InnerBottom, + `<div><div style="margin:auto; height:calc(100% - 50px); width:100%;">{layout}</div><div style="height:50px; width:100%; position:absolute"><FormattedTextBox doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={CaptionKey} isSelected={isSelected} select={select} selectOnLoad={SelectOnLoad} isTopMost={isTopMost}/></div></div>` ); - export const Title = new Template("Title", - `<div> - <div style="margin:auto; height:calc(100% - 50px); width:100%;"> - {layout} - </div> - <div style="height:50px; width:100%; position:absolute; background-color: rgba(0, 0, 0, .6); color: white; padding:12px"> - {Title} - </div> - </div>` + export const SideCaption = new Template("Side caption", TemplatePosition.OutterRight, + `<div><div style="margin:auto; height:100%; width:100%;">{layout}</div><div style="height:100%; width:300px; position:absolute; top: 0; right: -300px;"><FormattedTextBox doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={CaptionKey} isSelected={isSelected} select={select} selectOnLoad={SelectOnLoad} isTopMost={isTopMost}/></div> </div>` ); + export const Title = new Template("Title", TemplatePosition.InnerTop, + `<div><div style="margin:auto; height:calc(100% - 50px); width:100%;">{layout}</div><div style="height:50px; width:100%; position:absolute; top: 0; background-color: rgba(0, 0, 0, .6); color: white; padding:12px">{Title}</div></div>` + ); + + export const TemplateList: Template[] = [Title, OuterCaption, InnerCaption, SideCaption]; + + export function sortTemplates(a: Template, b: Template) { + if (a.Position < b.Position) { return -1; } + if (a.Position > b.Position) { return 1; } + return 0; + } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 440269e36..e851bc9c5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -99,13 +99,11 @@ export class DocumentView extends React.Component<DocumentViewProps> { @computed get layout(): string { return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); } @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); } @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); } - @computed get template(): Template { - let field = this.props.Document.GetT(KeyStore.Template, TemplateField); - return !field || field === FieldWaiting ? Templates.BasicLayout : field.Data; - } - set template(template: Template) { - this.props.Document.SetData(KeyStore.Template, template, TemplateField); + @computed get templates(): Array<Template> { + let field = this.props.Document.GetT(KeyStore.Templates, TemplateField); + return !field || field === FieldWaiting ? [] : field.Data; } + set templates(templates: Array<Template>) { this.props.Document.SetData(KeyStore.Templates, templates, TemplateField); } screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect(); onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; @@ -310,14 +308,39 @@ export class DocumentView extends React.Component<DocumentViewProps> { } updateLayout = (): void => { - let temp = this.template.Layout; - let layout = temp.replace("{layout}", this.base); + let base = this.base; + let layout = this.base; + + this.templates.forEach(template => { + let temp = template.Layout; + layout = temp.replace("{layout}", base); + base = layout; + }); + this.props.Document.SetText(KeyStore.Layout, layout); } @action - changeTemplate = (template: Template) => { - this.template = template; + addTemplate = (template: Template) => { + let templates = this.templates; + templates.push(template); + templates = templates.splice(0, templates.length).sort(Templates.sortTemplates); + this.templates = templates; + this.updateLayout(); + } + + @action + removeTemplate = (template: Template) => { + let templates = this.templates; + for (let i = 0; i < templates.length; i++) { + let temp = templates[i]; + if (temp.Name === template.Name) { + templates.splice(i, 1); + break; + } + } + templates = templates.splice(0, templates.length).sort(Templates.sortTemplates); + this.templates = templates; this.updateLayout(); } diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 1602c3776..5bd402890 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -21,7 +21,7 @@ export namespace KeyStore { export const ViewType = new Key("ViewType"); export const BaseLayout = new Key("BaseLayout"); export const Layout = new Key("Layout"); - export const Template = new Key("Template"); + export const Templates = new Key("Templates"); export const BackgroundColor = new Key("BackgroundColor"); export const BackgroundLayout = new Key("BackgroundLayout"); export const OverlayLayout = new Key("OverlayLayout"); diff --git a/src/fields/TemplateField.ts b/src/fields/TemplateField.ts index bc1e67d7b..72ae13c2e 100644 --- a/src/fields/TemplateField.ts +++ b/src/fields/TemplateField.ts @@ -1,11 +1,11 @@ import { BasicField } from "./BasicField"; import { Types } from "../server/Message"; import { FieldId } from "./Field"; -import { Template, Templates } from "../client/views/Templates"; +import { Template, TemplatePosition } from "../client/views/Templates"; -export class TemplateField extends BasicField<Template> { - constructor(data: Template = Templates.BasicLayout, id?: FieldId, save: boolean = true) { +export class TemplateField extends BasicField<Array<Template>> { + constructor(data: Array<Template> = [], id?: FieldId, save: boolean = true) { super(data, save, id); } @@ -18,18 +18,26 @@ export class TemplateField extends BasicField<Template> { } ToJson() { + let templates: Array<{ name: string, position: TemplatePosition, layout: string }> = []; + this.Data.forEach(template => { + templates.push({ name: template.Name, layout: template.Layout, position: template.Position }); + }); return { - type: Types.Template, - data: this.Data, + type: Types.Templates, + data: templates, id: this.Id, }; } UpdateFromServer(data: any) { - this.data = new Template(data.Name, data.layout); + this.data = new Array(data); } static FromJson(id: string, data: any): TemplateField { - return new TemplateField(new Template(data._name, data._layout), id, false); + let templates: Array<Template> = []; + data.forEach((template: { name: string, position: number, layout: string }) => { + templates.push(new Template(template.name, template.position, template.layout)); + }); + return new TemplateField(templates, id, false); } }
\ No newline at end of file diff --git a/src/server/Message.ts b/src/server/Message.ts index 4a8812956..00a30b329 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -15,7 +15,7 @@ export class Message<T> { export enum Types { Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, - Html, Video, Audio, Ink, PDF, Tuple, HistogramOp, Boolean, Script, Template + Html, Video, Audio, Ink, PDF, Tuple, HistogramOp, Boolean, Script, Templates } export interface Transferable { diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index a2256bca7..a10bdd5e6 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -18,7 +18,6 @@ import { NumberField } from "./../fields/NumberField"; import { RichTextField } from "./../fields/RichTextField"; import { TextField } from "./../fields/TextField"; import { Transferable, Types } from "./Message"; -import { Template } from "../client/views/Templates"; import { TemplateField } from "../fields/TemplateField"; export class ServerUtils { @@ -52,7 +51,7 @@ export class ServerUtils { case Types.Video: return new VideoField(new URL(json.data), json.id, false); case Types.Tuple: return new TupleField(json.data, json.id, false); case Types.Ink: return InkField.FromJson(json.id, json.data); - case Types.Template: return TemplateField.FromJson(json.id, json.data); + case Types.Templates: return TemplateField.FromJson(json.id, json.data); case Types.Document: return Document.FromJson(json.data, json.id, false); default: throw Error( |