diff options
Diffstat (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')
-rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 83 |
1 files changed, 36 insertions, 47 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index f8ef87fb1..6710cee63 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,30 +1,28 @@ import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import { Doc, Opt } from '../../../fields/Doc'; -import { InkField } from '../../../fields/InkField'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; import { ComputedField } from '../../../fields/ScriptField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; import { numberRange } from '../../../Utils'; -import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { DocComponent } from '../DocComponent'; +import { InkingStroke } from '../InkingStroke'; import { StyleProp } from '../StyleProvider'; import './CollectionFreeFormDocumentView.scss'; import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView'; import React = require('react'); export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { - dataProvider?: (doc: Doc, replica: string) => { x: number; y: number; zIndex?: number; color?: string; backgroundColor?: string; opacity?: number; highlight?: boolean; z: number; transition?: string } | undefined; + dataProvider?: (doc: Doc, replica: string) => { x: number; y: number; zIndex?: number; rotation?: number; color?: string; backgroundColor?: string; opacity?: number; highlight?: boolean; z: number; transition?: string } | undefined; sizeProvider?: (doc: Doc, replica: string) => { width: number; height: number } | undefined; renderCutoffProvider: (doc: Doc) => boolean; zIndex?: number; - rotation: number; dataTransition?: string; replica: string; CollectionFreeFormView: CollectionFreeFormView; @@ -38,13 +36,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF { key: 'x' }, { key: 'y' }, { key: '_rotation', val: 0 }, - { key: '_scrollTop' }, + { key: '_layout_scrollTop' }, { key: 'opacity', val: 1 }, - { key: 'viewScale', val: 1 }, - { key: 'panX' }, - { key: 'panY' }, + { key: '_currentFrame' }, + { key: 'freeform_scale', val: 1 }, + { key: 'freeform_scale', val: 1 }, + { key: 'freeform_panX' }, + { key: 'freeform_panY' }, ]; // fields that are configured to be animatable using animation frames - public static animStringFields = ['backgroundColor', 'color']; // fields that are configured to be animatable using animation frames + public static animStringFields = ['backgroundColor', 'color', 'fillColor']; // fields that are configured to be animatable using animation frames public static animDataFields = (doc: Doc) => (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames @observable _animPos: number[] | undefined = undefined; @observable _contentView: DocumentView | undefined | null; @@ -54,7 +54,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF } get transform() { - return `translate(${this.X}px, ${this.Y}px) rotate(${NumCast(this.Document.rotation, this.props.rotation)}deg)`; + return `translate(${this.X}px, ${this.Y}px) rotate(${NumCast(this.Rot, this.Rot)}deg)`; } get X() { return this.dataProvider?.x ?? NumCast(this.Document.x); @@ -65,6 +65,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF get ZInd() { return this.dataProvider?.zIndex ?? NumCast(this.Document.zIndex); } + get Rot() { + return this.dataProvider?.rotation ?? NumCast(this.Document._rotation); + } get Opacity() { return this.dataProvider?.opacity; } @@ -82,13 +85,14 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF } styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => { - if (doc === this.layoutDoc) + if (doc === this.layoutDoc) { // prettier-ignore switch (property) { case StyleProp.Opacity: return this.Opacity; // only change the opacity for this specific document, not its children case StyleProp.BackgroundColor: return this.BackgroundColor; case StyleProp.Color: return this.Color; } + } return this.props.styleProvider?.(doc, props, property); }; @@ -106,39 +110,22 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF }, {} as { [val: string]: Opt<string> }); } - public static setValues(time: number, d: Doc, vals: { [val: string]: Opt<number> }) { + public static setStringValues(time: number, d: Doc, vals: { [val: string]: Opt<string> }) { const timecode = Math.round(time); Object.keys(vals).forEach(val => { - const findexed = Cast(d[`${val}-indexed`], listSpec('number'), []).slice(); - findexed[timecode] = vals[val] as any as number; - d[`${val}-indexed`] = new List<number>(findexed); + const findexed = Cast(d[`${val}-indexed`], listSpec('string'), []).slice(); + findexed[timecode] = vals[val] as any as string; + d[`${val}-indexed`] = new List<string>(findexed); }); } - public static updateKeyframe(timer: NodeJS.Timeout | undefined, docs: Doc[], time: number, targetDoc?: Doc) { - if (timer) clearTimeout(timer); - const newTimer = DocumentView.SetViewTransition(docs, 'all', 1000, undefined, true); + public static setValues(time: number, d: Doc, vals: { [val: string]: Opt<number> }) { const timecode = Math.round(time); - docs.forEach(doc => { - CollectionFreeFormDocumentView.animFields.forEach(val => { - const findexed = Cast(doc[`${val.key}-indexed`], listSpec('number'), null); - findexed?.length <= timecode + 1 && findexed.push(undefined as any as number); - }); - CollectionFreeFormDocumentView.animStringFields.forEach(val => { - const findexed = Cast(doc[`${val}-indexed`], listSpec('string'), null); - findexed?.length <= timecode + 1 && findexed.push(undefined as any as string); - }); - CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => { - const findexed = Cast(doc[`${val}-indexed`], listSpec(InkField), null); - findexed?.length <= timecode + 1 && findexed.push(undefined as any); - }); + Object.keys(vals).forEach(val => { + const findexed = Cast(d[`${val}-indexed`], listSpec('number'), []).slice(); + findexed[timecode] = vals[val] as any as number; + d[`${val}-indexed`] = new List<number>(findexed); }); - return newTimer; - } - - public static gotoKeyframe(timer: NodeJS.Timeout | undefined, docs: Doc[], duration = 1000) { - if (timer) clearTimeout(timer); - return DocumentView.SetViewTransition(docs, 'all', duration, undefined, true); } public static setupZoom(doc: Doc, targDoc: Doc) { @@ -165,17 +152,18 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF } CollectionFreeFormDocumentView.animFields.forEach(val => (doc[val.key] = ComputedField.MakeInterpolatedNumber(val.key, 'activeFrame', doc, currTimecode, val.val))); CollectionFreeFormDocumentView.animStringFields.forEach(val => (doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode))); - CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => (Doc.GetProto(doc)[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', Doc.GetProto(doc), currTimecode))); - const targetDoc = doc.type === DocumentType.RTF ? Doc.GetProto(doc) : doc; // data fields, like rtf 'text' exist on the data doc, so - doc !== targetDoc && (targetDoc.context = doc.context); // the computed fields don't see the layout doc -- need to copy the context to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!) - targetDoc.activeFrame = ComputedField.MakeFunction('self.context?._currentFrame||0'); + CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => (doc[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', doc, currTimecode))); + const targetDoc = doc; // data fields, like rtf 'text' exist on the data doc, so + //doc !== targetDoc && (targetDoc.embedContainer = doc.embedContainer); // the computed fields don't see the layout doc -- need to copy the embedContainer to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!) + targetDoc.activeFrame = ComputedField.MakeFunction('self.embedContainer?._currentFrame||0'); targetDoc.dataTransition = 'inherit'; }); } @action public float = () => { - const { Document: topDoc, ContainingCollectionView: container } = this.props; - const screenXf = container?.screenToLocalTransform(); + const topDoc = this.rootDoc; + const containerDocView = this.props.docViewPath().lastElement(); + const screenXf = containerDocView?.screenToLocalTransform(); if (screenXf) { SelectionManager.DeselectAll(); if (topDoc.z) { @@ -192,7 +180,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF topDoc.x = fpt[0]; topDoc.y = fpt[1]; } - setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0); + setTimeout(() => SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, containerDocView), false), 0); } }; @@ -203,7 +191,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF panelWidth = () => this.sizeProvider?.width || this.props.PanelWidth?.(); panelHeight = () => this.sizeProvider?.height || this.props.PanelHeight?.(); screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y); - focusDoc = (doc: Doc) => this.props.focus(doc, {}); returnThis = () => this; render() { TraceMobx(); @@ -215,9 +202,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF PanelWidth: this.panelWidth, PanelHeight: this.panelHeight, }; + const isInk = StrCast(this.layoutDoc.layout).includes(InkingStroke.name) && !this.props.LayoutTemplateString && !this.layoutDoc._stroke_isInkMask; return ( <div - className={'collectionFreeFormDocumentView-container'} + className="collectionFreeFormDocumentView-container" style={{ width: this.panelWidth(), height: this.panelHeight(), @@ -225,7 +213,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF transformOrigin: '50% 50%', transition: this.dataProvider?.transition ?? (this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition)), zIndex: this.ZInd, - display: this.ZInd === -99 ? 'none' : undefined, + display: this.sizeProvider?.width ? undefined : 'none', + pointerEvents: isInk ? 'none' : undefined, }}> {this.props.renderCutoffProvider(this.props.Document) ? ( <div style={{ position: 'absolute', width: this.panelWidth(), height: this.panelHeight(), background: 'lightGreen' }} /> |