diff options
author | eeng5 <eleanor.eng5@gmail.com> | 2019-11-19 17:47:13 -0500 |
---|---|---|
committer | eeng5 <eleanor.eng5@gmail.com> | 2019-11-19 17:47:13 -0500 |
commit | 7d89d10a3d43755c267fd48e18701d457ae7aa1c (patch) | |
tree | 059312d4d2dfeaa96b5e272abc7608b0d68b96b4 /src/client/views/DocComponent.tsx | |
parent | ab285371f6fb2a4f1e64888bafbc84b602f23416 (diff) | |
parent | 667d196a2cbc8e237de5be9a6f7ec4ecca9d2bb5 (diff) |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into server_refactor
Diffstat (limited to 'src/client/views/DocComponent.tsx')
-rw-r--r-- | src/client/views/DocComponent.tsx | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 2c5992259..286a77f81 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -1,63 +1,91 @@ import * as React from 'react'; import { Doc } from '../../new_fields/Doc'; -import { computed, action } from 'mobx'; +import { Touchable } from './Touchable'; +import { computed, action, observable } from 'mobx'; import { Cast } from '../../new_fields/Types'; import { listSpec } from '../../new_fields/Schema'; +import { InkingControl } from './InkingControl'; +import { InkTool } from '../../new_fields/InkField'; +import { PositionDocument } from '../../new_fields/documentSchemas'; -export function DocComponent<P extends { Document: Doc }, T>(schemaCtor: (doc: Doc) => T) { + +/// DocComponent returns a generic React base class used by views that don't have any data extensions (e.g.,CollectionFreeFormDocumentView, DocumentView, ButtonBox) +interface DocComponentProps { + Document: Doc; +} +export function DocComponent<P extends DocComponentProps, T>(schemaCtor: (doc: Doc) => T) { + class Component extends Touchable<P> { + //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then + @computed get Document(): T { return schemaCtor(this.props.Document); } + @computed get layoutDoc() { return PositionDocument(Doc.Layout(this.props.Document)); } + } + return Component; +} + +/// DocStaticProps return a base class for React document views that have data extensions but aren't annotatable (e.g. AudioBox, FormattedTextBox) +interface DocExtendableProps { + Document: Doc; + DataDoc?: Doc; + fieldKey: string; + isSelected: () => boolean; + renderDepth: number; +} +export function DocExtendableComponent<P extends DocExtendableProps, T>(schemaCtor: (doc: Doc) => T) { class Component extends React.Component<P> { //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then - @computed - get Document(): T { - return schemaCtor(this.props.Document); - } + @computed get Document(): T { return schemaCtor(this.props.Document); } + @computed get layoutDoc() { return Doc.Layout(this.props.Document); } + @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; } + @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } + active = () => !this.props.Document.isBackground && (this.props.Document.forceActive || this.props.isSelected() || this.props.renderDepth === 0);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools } return Component; } + +/// DocAnnotatbleComponent return a base class for React views of document fields that are annotatable *and* interactive when selected (e.g., pdf, image) interface DocAnnotatableProps { Document: Doc; DataDoc?: Doc; fieldKey: string; - fieldExt: string; whenActiveChanged: (isActive: boolean) => void; isSelected: () => boolean; renderDepth: number; } export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schemaCtor: (doc: Doc) => T) { class Component extends React.Component<P> { + @observable _isChildActive = false; //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then - @computed - get Document(): T { - return schemaCtor(this.props.Document); - } - _isChildActive = false; + @computed get Document(): T { return schemaCtor(this.props.Document); } + @computed get layoutDoc() { return Doc.Layout(this.props.Document); } + @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; } + @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } + @computed get annotationsKey() { return "annotations"; } + @action.bound removeDocument(doc: Doc): boolean { Doc.GetProto(doc).annotationOn = undefined; - let value = Cast(this.extensionDoc[this.props.fieldExt], listSpec(Doc), []); + let value = this.extensionDoc && Cast(this.extensionDoc[this.annotationsKey], listSpec(Doc), []); let index = value ? Doc.IndexOf(doc, value.map(d => d as Doc), true) : -1; - return index !== -1 && value.splice(index, 1) ? true : false; + return index !== -1 && value && value.splice(index, 1) ? true : false; } - - @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; } - - @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } - // if the moved document is already in this overlay collection nothing needs to be done. // otherwise, if the document can be removed from where it was, it will then be added to this document's overlay collection. @action.bound moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean { return Doc.AreProtosEqual(this.props.Document, targetCollection) ? true : this.removeDocument(doc) ? addDocument(doc) : false; } - @action.bound addDocument(doc: Doc): boolean { Doc.GetProto(doc).annotationOn = this.props.Document; - return Doc.AddDocToList(this.extensionDoc, this.props.fieldExt, doc); + return this.extensionDoc && Doc.AddDocToList(this.extensionDoc, this.annotationsKey, doc) ? true : false; } - whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); - active = () => this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; + + whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); + active = () => ((InkingControl.Instance.selectedTool === InkTool.None && !this.props.Document.isBackground) && + (this.props.Document.forceActive || this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0) ? true : false) + annotationsActive = () => (InkingControl.Instance.selectedTool !== InkTool.None || + (this.props.Document.forceActive || this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0) ? true : false) } return Component; }
\ No newline at end of file |