aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.scss4
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx170
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx39
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx4
-rw-r--r--src/client/views/nodes/LinkBox.tsx4
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx11
7 files changed, 156 insertions, 78 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.scss b/src/client/views/nodes/CollectionFreeFormDocumentView.scss
index f99011b8f..7f0a39550 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.scss
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.scss
@@ -1,9 +1,9 @@
.collectionFreeFormDocumentView-container {
- transform-origin: left top;
+ transform-origin: 50% 50%;
position: absolute;
background-color: transparent;
touch-action: manipulation;
top: 0;
left: 0;
- //pointer-events: none;
+ pointer-events: none;
}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 09dfa4f99..a05d6c904 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,4 +1,4 @@
-import { action, computed, observable } from 'mobx';
+import { action, computed, observable, trace } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, Opt } from '../../../fields/Doc';
import { List } from '../../../fields/List';
@@ -6,10 +6,9 @@ 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 { numberRange, OmitKeys } from '../../../Utils';
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 { StyleProp } from '../StyleProvider';
@@ -17,18 +16,102 @@ 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; rotation?: number; color?: string; backgroundColor?: string; opacity?: number; highlight?: boolean; z: number; transition?: string };
- sizeProvider: (doc: Doc, replica: string) => { width: number; height: number };
- renderCutoffProvider: (doc: Doc) => boolean;
+export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentViewProps {
+ x: number;
+ y: number;
+ z: number;
+ width: number;
+ height: number;
zIndex?: number;
+ rotation?: number;
+ color?: string;
+ backgroundColor?: string;
+ opacity?: number;
+ highlight?: boolean;
+ transition?: string;
dataTransition?: string;
- replica: string;
+ RenderCutoffProvider: (doc: Doc) => boolean;
+ CollectionFreeFormView: CollectionFreeFormView;
+}
+@observer
+export class CollectionFreeFormDocumentViewWrapper extends DocComponent<CollectionFreeFormDocumentViewWrapperProps>() implements CollectionFreeFormDocumentViewProps {
+ @observable X = this.props.x;
+ @observable Y = this.props.y;
+ @observable Z = this.props.z;
+ @observable ZIndex = this.props.zIndex;
+ @observable Rotation = this.props.rotation;
+ @observable Opacity = this.props.opacity;
+ @observable BackgroundColor = this.props.backgroundColor;
+ @observable Color = this.props.color;
+ @observable Highlight = this.props.highlight;
+ @observable Width = this.props.width;
+ @observable Height = this.props.height;
+ @observable Transition = this.props.transition;
+ @observable DataTransition = this.props.dataTransition;
+ CollectionFreeFormView = this.props.CollectionFreeFormView; // needed for type checking
+ RenderCutoffProvider = this.props.RenderCutoffProvider; // needed for type checking
+
+ @computed get WrapperKeys() {
+ return Object.keys(this).filter(key => key.startsWith('w_')).map(key => key.replace('w_', ''))
+ .map(key => ({upper:key, lower:key[0].toLowerCase() + key.substring(1)})); // prettier-ignore
+ }
+
+ // wrapper functions around prop fields that have been converted to observables to keep 'props' from ever changing.
+ // this way, downstream code only invalidates when it uses a specific prop, not when any prop changes
+ w_X = () => this.X; // prettier-ignore
+ w_Y = () => this.Y; // prettier-ignore
+ w_Z = () => this.Z; // prettier-ignore
+ w_ZIndex = () => this.ZIndex ?? NumCast(this.props.Document.zIndex); // prettier-ignore
+ w_Rot = () => this.Rotation ?? NumCast(this.props.Document._rotation); // prettier-ignore
+ w_Opacity = () => this.Opacity; // prettier-ignore
+ w_BackgroundColor = () => this.BackgroundColor ?? Cast(this.props.Document._backgroundColor, 'string', null); // prettier-ignore
+ w_Color = () => this.Color ?? Cast(this.props.Document._color, 'string', null); // prettier-ignore
+ w_Highlight = () => this.Highlight; // prettier-ignore
+ w_Width = () => this.Width; // prettier-ignore
+ w_Height = () => this.Height; // prettier-ignore
+ w_Transition = () => this.Transition; // prettier-ignore
+ w_DataTransition = () => this.DataTransition; // prettier-ignore
+
+ PanelWidth = () => this.Width || this.props.PanelWidth?.(); // prettier-ignore
+ PanelHeight = () => this.Height || this.props.PanelHeight?.(); // prettier-ignore
+ @action
+ componentDidUpdate() {
+ this.WrapperKeys.forEach(keys => ((this as any)[keys.upper] = (this.props as any)[keys.lower]));
+ }
+ render() {
+ const layoutProps = this.WrapperKeys.reduce((val, keys) => [(val['w_' + keys.upper] = (this as any)['w_' + keys.upper]), val][1], {} as { [key: string]: Function });
+ return (
+ <CollectionFreeFormDocumentView
+ {...OmitKeys(this.props, this.WrapperKeys.map(keys => keys.lower) ).omit} // prettier-ignore
+ {...layoutProps}
+ PanelWidth={this.PanelWidth}
+ PanelHeight={this.PanelHeight}
+ />
+ );
+ }
+}
+export interface CollectionFreeFormDocumentViewProps {
+ w_X: () => number;
+ w_Y: () => number;
+ w_Z: () => number;
+ w_ZIndex?: () => number;
+ w_Rotation?: () => number;
+ w_Color: () => string;
+ w_BackgroundColor: () => string;
+ w_Opacity: () => number | undefined;
+ w_Highlight: () => boolean | undefined;
+ w_Transition: () => string | undefined;
+ w_Width: () => number;
+ w_Height: () => number;
+ w_DataTransition: () => string | undefined;
+ PanelWidth: () => number;
+ PanelHeight: () => number;
+ RenderCutoffProvider: (doc: Doc) => boolean;
CollectionFreeFormView: CollectionFreeFormView;
}
@observer
-export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps>() {
+export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps & DocumentViewProps>() {
get displayName() { // this makes mobx trace() statements more descriptive
return 'CollectionFreeFormDocumentView(' + this.rootDoc.title + ')';
} // prettier-ignore
@@ -48,26 +131,19 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
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
- get X() { return this.dataProvider.x; } // prettier-ignore
- get Y() { return this.dataProvider.y; } // prettier-ignore
- get ZInd() { return this.dataProvider.zIndex ?? NumCast(this.Document.zIndex); } // prettier-ignore
- get Rot() { return this.dataProvider.rotation ?? NumCast(this.Document._rotation); } // prettier-ignore
- get Opacity() { return this.dataProvider.opacity; } // prettier-ignore
- get BackgroundColor() { return this.dataProvider.backgroundColor ?? Cast(this.Document._backgroundColor, 'string', null); } // prettier-ignore
- get Color() { return this.dataProvider.color ?? Cast(this.Document._color, 'string', null); } // prettier-ignore
-
@observable _animPos: number[] | undefined = undefined;
@observable _contentView: DocumentView | undefined | null;
- @computed get dataProvider() { return this.props.dataProvider(this.props.Document, this.props.replica); } // prettier-ignore
- @computed get sizeProvider() { return this.props.sizeProvider(this.props.Document, this.props.replica); } // prettier-ignore
+ get CollectionFreeFormView() {
+ return this.props.CollectionFreeFormView;
+ }
styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
if (doc === this.layoutDoc) {
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;
+ case StyleProp.Opacity: return this.props.w_Opacity(); // only change the opacity for this specific document, not its children
+ case StyleProp.BackgroundColor: return this.props.w_BackgroundColor();
+ case StyleProp.Color: return this.props.w_Color();
} // prettier-ignore
}
return this.props.styleProvider?.(doc, props, property);
@@ -146,16 +222,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
};
- dragEnding = () => this.props.CollectionFreeFormView?.dragEnding();
- dragStarting = () => this.props.CollectionFreeFormView?.dragStarting(false, true);
-
nudge = (x: number, y: number) => {
- this.props.Document.x = NumCast(this.props.Document.x) + x;
- this.props.Document.y = NumCast(this.props.Document.y) + y;
+ this.props.Document.x = this.props.w_X() + x;
+ this.props.Document.y = this.props.w_Y() + y;
};
- panelWidth = () => this.sizeProvider?.width || this.props.PanelWidth?.();
- panelHeight = () => this.sizeProvider?.height || this.props.PanelHeight?.();
- screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y);
+ screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(-this.props.w_X(), -this.props.w_Y());
returnThis = () => this;
/// this indicates whether the doc view is activated because of its relationshop to a group
@@ -164,38 +235,35 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
// 'inactive' - this is a group child but it is not active
// undefined - this is not activated by a group
isGroupActive = () => {
- if (this.props.CollectionFreeFormView.isAnyChildContentActive()) return undefined;
+ if (this.CollectionFreeFormView.isAnyChildContentActive()) return undefined;
const isGroup = this.rootDoc._isGroup && (!this.rootDoc.backgroundColor || this.rootDoc.backgroundColor === 'transparent');
return isGroup ? (this.props.isDocumentActive?.() ? 'group' : this.props.isGroupActive?.() ? 'child' : 'inactive') : this.props.isGroupActive?.() ? 'child' : undefined;
};
render() {
TraceMobx();
- const divProps: DocumentViewProps = {
- ...this.props,
- CollectionFreeFormDocumentView: this.returnThis,
- styleProvider: this.styleProvider,
- ScreenToLocalTransform: this.screenToLocalTransform,
- PanelWidth: this.panelWidth,
- PanelHeight: this.panelHeight,
- isGroupActive: this.isGroupActive,
- };
+ const passOnProps = OmitKeys(this.props, Object.keys(this.props).filter(key => key.startsWith('w_'))).omit; // prettier-ignore
return (
<div
className="collectionFreeFormDocumentView-container"
style={{
- width: this.panelWidth(),
- height: this.panelHeight(),
- transform: `translate(${this.X}px, ${this.Y}px) rotate(${NumCast(this.Rot, this.Rot)}deg)`,
- 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.sizeProvider?.width ? undefined : 'none',
- pointerEvents: 'none',
+ width: this.props.PanelWidth(),
+ height: this.props.PanelHeight(),
+ transform: `translate(${this.props.w_X()}px, ${this.props.w_Y()}px) rotate(${NumCast(this.props.w_Rotation?.())}deg)`,
+ transition: this.props.w_Transition?.() ?? (this.props.w_DataTransition?.() || this.props.w_Transition?.()),
+ zIndex: this.props.w_ZIndex?.(),
+ display: this.props.w_Width?.() ? undefined : 'none',
}}>
- {this.props.renderCutoffProvider(this.props.Document) ? (
- <div style={{ position: 'absolute', width: this.panelWidth(), height: this.panelHeight(), background: 'lightGreen' }} />
+ {this.props.RenderCutoffProvider(this.props.Document) ? (
+ <div style={{ position: 'absolute', width: this.props.PanelWidth(), height: this.props.PanelHeight(), background: 'lightGreen' }} />
) : (
- <DocumentView {...divProps} ref={action((r: DocumentView | null) => (this._contentView = r))} />
+ <DocumentView
+ ref={action((r: DocumentView | null) => (this._contentView = r))}
+ {...passOnProps}
+ CollectionFreeFormDocumentView={this.returnThis}
+ styleProvider={this.styleProvider}
+ ScreenToLocalTransform={this.screenToLocalTransform}
+ isGroupActive={this.isGroupActive}
+ />
)}
</div>
);
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e1de2fa76..c4703a47c 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -98,7 +98,7 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
};
render() {
const style: { [key: string]: any } = {};
- const divKeys = OmitKeys(this.props, ['children', 'htmltag', 'RootDoc', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit;
+ const divKeys = OmitKeys(this.props, ['children', 'dragStarting', 'dragEnding', 'htmltag', 'RootDoc', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit;
const replacer = (match: any, expr: string, offset: any, string: any) => {
// bcz: this executes a script to convert a propery expression string: { script } into a value
return (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ self: this.props.RootDoc, this: this.props.Document, scale: this.props.scaling }).result as string) || '';
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4dba5cbd3..005ec6019 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -64,6 +64,14 @@ declare class MediaRecorder {
constructor(e: any);
}
+export enum OpenWhereMod {
+ none = '',
+ left = 'left',
+ right = 'right',
+ top = 'top',
+ bottom = 'bottom',
+ keyvalue = 'keyValue',
+}
export enum OpenWhere {
lightbox = 'lightbox',
add = 'add',
@@ -79,14 +87,7 @@ export enum OpenWhere {
inParent = 'inParent',
inParentFromScreen = 'inParentFromScreen',
overlay = 'overlay',
-}
-export enum OpenWhereMod {
- none = '',
- left = 'left',
- right = 'right',
- top = 'top',
- bottom = 'bottom',
- rightKeyValue = 'rightKeyValue',
+ addRightKeyvalue = 'add:right:keyValue',
}
export interface DocFocusOptions {
@@ -134,6 +135,7 @@ export interface DocComponentView {
setFocus?: () => void; // sets input focus to the componentView
setData?: (data: Field | Promise<RefField | undefined>) => boolean;
componentUI?: (boundsLeft: number, boundsTop: number) => JSX.Element | null;
+ dragStarting?: (snapToDraggedDoc: boolean, showGroupDragTarget: boolean, visited: Set<Doc>) => void;
incrementalRendering?: () => void;
layout_fitWidth?: () => boolean; // whether the component always fits width (eg, KeyValueBox)
overridePointerEvents?: () => 'all' | 'none' | undefined; // if the conmponent overrides the pointer events for the document (e.g, KeyValueBox always allows pointer events)
@@ -166,7 +168,6 @@ export interface DocumentViewSharedProps {
childHideDecorationTitle?: () => boolean;
childHideResizeHandles?: () => boolean;
childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
- dataTransition?: string; // specifies animation transition - used by collectionPile and potentially other layout engines when changing the size of documents so that the change won't be abrupt
styleProvider: Opt<StyleProviderFunc>;
setTitleFocus?: () => void;
focus: DocFocusFunc;
@@ -235,6 +236,8 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
onPointerUp?: () => ScriptField;
onBrowseClick?: () => ScriptField | undefined;
onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined;
+ dragStarting?: () => void;
+ dragEnding?: () => void;
}
// these props are only available in DocumentViewIntenral
@@ -321,7 +324,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
@observable _pointerEvents: 'none' | 'all' | 'visiblePainted' | undefined;
@computed get pointerEvents(): 'none' | 'all' | 'visiblePainted' | undefined {
- TraceMobx();
return this._pointerEvents;
}
@computed get finalLayoutKey() {
@@ -334,7 +336,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return this.props.NativeHeight();
}
@computed get disableClickScriptFunc() {
- TraceMobx();
const onScriptDisable = this.props.onClickScriptDisable ?? this._componentView?.onClickScriptDisable?.() ?? this.layoutDoc.onClickScriptDisable;
// prettier-ignore
return (
@@ -359,7 +360,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
componentWillUnmount() {
this.cleanupHandlers(true);
}
- @observable _mounted = false;
+ @observable _mounted = false; // turn off all pointer events if component isn't yet mounted (enables nested Docs in alternate UI textboxes that appear on hover which otherwise would grab focus from the text box, reverting to the original UI )
@action
componentDidMount() {
this._mounted = true;
@@ -669,7 +670,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
de.complete.linkDocument = DocUtils.MakeLink(linkdrag.linkSourceDoc, dropDoc, {}, undefined, [de.x, de.y - 50]);
if (de.complete.linkDocument) {
de.complete.linkDocument.layout_isSvg = true;
- this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView.addDocument(de.complete.linkDocument);
+ this.props.DocumentView().CollectionFreeFormView?.addDocument(de.complete.linkDocument);
}
}
e.stopPropagation();
@@ -766,6 +767,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (this.props.renderDepth === 0) {
appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => LightboxView.Instance.SetLightboxDoc(this.rootDoc), icon: 'external-link-alt' });
}
+ this.rootDoc.type === DocumentType.PRES && appearanceItems.push({ description: 'Pin', event: () => this.props.pinToPres(this.rootDoc, {}), icon: 'eye' });
!Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template ', event: () => this.props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' });
!appearance && appearanceItems.length && cm.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'compass' });
@@ -841,7 +843,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
constantItems.push({ description: 'Close', event: this.deleteClicked, icon: 'times' });
}
}
- constantItems.push({ description: 'Show Metadata', event: () => this.props.addDocTab(this.props.Document, (OpenWhere.addRight.toString() + 'KeyValue') as OpenWhere), icon: 'table-columns' });
+ constantItems.push({ description: 'Show Metadata', event: () => this.props.addDocTab(this.props.Document, OpenWhere.addRightKeyvalue), icon: 'table-columns' });
cm.addItem({ description: 'General...', noexpand: false, subitems: constantItems, icon: 'question' });
const help = cm.findByDescription('Help...');
@@ -1519,6 +1521,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.props.dontCenter?.includes('y') ? 0 : this.Yshift;
}
+ @computed get CollectionFreeFormView() {
+ return this.CollectionFreeFormDocumentView?.CollectionFreeFormView;
+ }
+ @computed get CollectionFreeFormDocumentView() {
+ return this.props.CollectionFreeFormDocumentView?.();
+ }
+
public toggleNativeDimensions = () => this.docView && this.rootDoc.type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.NativeDimScaling, this.props.PanelWidth(), this.props.PanelHeight());
public getBounds = () => {
if (!this.docView?.ContentDiv || this.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
@@ -1667,7 +1676,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
className="contentFittingDocumentView-previewDoc"
ref={this.ContentRef}
style={{
- transition: this.props.dataTransition,
+ transition: 'inherit', // this.props.dataTransition,
transform: `translate(${this.centeringX}px, ${this.centeringY}px)`,
width: xshift ?? `${(100 * (this.props.PanelWidth() - this.Xshift * 2)) / this.props.PanelWidth()}%`,
height: this.props.forceAutoHeight
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index f22cb195f..6f99b7c28 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -7,7 +7,7 @@ import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { EditableView } from '../EditableView';
import { DefaultStyleProvider } from '../StyleProvider';
-import { OpenWhere } from './DocumentView';
+import { OpenWhere, OpenWhereMod } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { KeyValueBox } from './KeyValueBox';
import './KeyValueBox.scss';
@@ -50,7 +50,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
if (value instanceof Doc) {
e.stopPropagation();
e.preventDefault();
- ContextMenu.Instance.addItem({ description: 'Open Fields', event: () => this.props.addDocTab(value, ((OpenWhere.addRight as string) + 'KeyValue') as OpenWhere), icon: 'layer-group' });
+ ContextMenu.Instance.addItem({ description: 'Open Fields', event: () => this.props.addDocTab(value, OpenWhere.addRightKeyvalue), icon: 'layer-group' });
ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
}
};
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 034eb4011..416cb11cc 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -32,7 +32,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
return DocumentManager.Instance.getDocumentView(anchor_2, this.props.docViewPath()[this.props.docViewPath().length - 2]); // this.props.docViewPath().lastElement());
}
screenBounds = () => {
- if (this.layoutDoc._layout_isSvg && this.anchor1 && this.anchor2 && this.anchor1.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView) {
+ if (this.layoutDoc._layout_isSvg && this.anchor1 && this.anchor2 && this.anchor1.CollectionFreeFormView) {
const a_invXf = this.anchor1.props.ScreenToLocalTransform().inverse();
const b_invXf = this.anchor2.props.ScreenToLocalTransform().inverse();
const a_scrBds = { tl: a_invXf.transformPoint(0, 0), br: a_invXf.transformPoint(NumCast(this.anchor1.rootDoc._width), NumCast(this.anchor1.rootDoc._height)) };
@@ -57,7 +57,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.props.setContentView?.(this);
this.disposer = reaction(
() => {
- if (this.layoutDoc._layout_isSvg && (this.anchor1 || this.anchor2)?.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView) {
+ if (this.layoutDoc._layout_isSvg && (this.anchor1 || this.anchor2)?.CollectionFreeFormView) {
const a = (this.anchor1 ?? this.anchor2)!;
const b = (this.anchor2 ?? this.anchor1)!;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index c4ef07123..180fa9f5d 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -27,7 +27,6 @@ import { CollectionDockingView } from '../../collections/CollectionDockingView';
import { CollectionFreeFormView, computeTimelineLayout, MarqueeViewBounds } from '../../collections/collectionFreeForm';
import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline';
import { CollectionView } from '../../collections/CollectionView';
-import { TabDocView } from '../../collections/TabDocView';
import { TreeView } from '../../collections/TreeView';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
@@ -439,7 +438,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const acontext = activeItem.config_activeFrame !== undefined ? DocCast(DocCast(activeItem.presentation_targetDoc).embedContainer) : DocCast(activeItem.presentation_targetDoc);
const context = DocCast(acontext)?.annotationOn ? DocCast(DocCast(acontext).annotationOn) : acontext;
if (context) {
- const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
+ const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.CollectionFreeFormView;
if (ffview?.childDocs) {
PresBox.Instance._keyTimer = CollectionFreeFormView.gotoKeyframe(PresBox.Instance._keyTimer, ffview.childDocs, transTime);
ffview.rootDoc._currentFrame = NumCast(activeFrame);
@@ -768,6 +767,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
PresBox.NavigateToTarget(targetDoc, activeItem, resetSelection);
};
+ public static PanelName = 'PRESBOX';
+
static NavigateToTarget(targetDoc: Doc, activeItem: Doc, finished?: () => void) {
if (activeItem.presentation_movement === PresMovement.None && targetDoc.type === DocumentType.SCRIPTING) {
(DocumentManager.Instance.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.();
@@ -782,7 +783,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
zoomTime: activeItem.presentation_movement === PresMovement.Jump ? 0 : Math.min(Math.max(effect ? 750 : 500, (effect ? 0.2 : 1) * presTime), presTime),
effect: activeItem,
noSelect: true,
- openLocation: OpenWhere.addLeft,
+ openLocation: targetDoc.type === DocumentType.PRES ? ((OpenWhere.replace + ':' + PresBox.PanelName) as OpenWhere) : OpenWhere.addLeft,
anchorDoc: activeItem,
easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any,
zoomTextSelections: BoolCast(activeItem.presentation_zoomText),
@@ -1068,7 +1069,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
audio.config_clipStart = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */));
audio.config_clipEnd = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */));
audio.presentation_duration = audio.config_clipStart - audio.config_clipEnd;
- TabDocView.PinDoc(audio, { audioRange: true });
+ this.props.pinToPres(audio, { audioRange: true });
setTimeout(() => this.removeDocument(doc), 0);
return false;
}
@@ -2223,7 +2224,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const config_data = Cast(this.rootDoc.data, listSpec(Doc));
if (data && config_data) {
data.push(doc);
- TabDocView.PinDoc(doc, {});
+ this.props.pinToPres(doc, {});
this.gotoDocument(this.childDocs.length, this.activeItem);
} else {
this.props.addDocTab(doc, OpenWhere.addRight);