aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/TabDocView.tsx
diff options
context:
space:
mode:
authorNaafiyan Ahmed <naafiyan@gmail.com>2022-07-12 12:08:49 -0400
committerNaafiyan Ahmed <naafiyan@gmail.com>2022-07-12 12:08:49 -0400
commit9ad978eac113cf3559d885c62a9368a68f6333ec (patch)
tree8daa3a5663379b29d8121aaa39e80cfd5e7fd9ed /src/client/views/collections/TabDocView.tsx
parent31041d7a5b2c3699518ebb33ccab016af0acd579 (diff)
parent5628b585fa6356d66cf2e7454be20e3b847ad22e (diff)
merged master
Diffstat (limited to 'src/client/views/collections/TabDocView.tsx')
-rw-r--r--src/client/views/collections/TabDocView.tsx623
1 files changed, 343 insertions, 280 deletions
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 62d07b0e4..b8aaea622 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -1,43 +1,41 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
-import 'golden-layout/src/css/goldenlayout-base.css';
-import 'golden-layout/src/css/goldenlayout-dark-theme.css';
import { clamp } from 'lodash';
-import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
-import { observer } from "mobx-react";
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { observer } from 'mobx-react';
import * as ReactDOM from 'react-dom';
-import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
-import { FieldId } from "../../../fields/RefField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from "../../../Utils";
-import { DocServer } from "../../DocServer";
+import { FieldId } from '../../../fields/RefField';
+import { listSpec } from '../../../fields/Schema';
+import { ScriptField } from '../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
+import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick, Utils } from '../../../Utils';
+import { DocServer } from '../../DocServer';
import { DocUtils } from '../../documents/Documents';
-import { DocumentType } from '../../documents/DocumentTypes';
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
+import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from '../../util/DocumentManager';
-import { DragManager, dropActionType } from "../../util/DragManager";
+import { DragManager, dropActionType } from '../../util/DragManager';
import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch, UndoManager } from "../../util/UndoManager";
+import { undoBatch, UndoManager } from '../../util/UndoManager';
+import { DashboardView } from '../DashboardView';
import { Colors, Shadows } from '../global/globalEnums';
import { LightboxView } from '../LightboxView';
import { MainView } from '../MainView';
-import { DocFocusOptions, DocumentView, DocumentViewProps } from "../nodes/DocumentView";
+import { DocFocusOptions, DocumentView, DocumentViewProps } from '../nodes/DocumentView';
import { DashFieldView } from '../nodes/formattedText/DashFieldView';
import { PinProps, PresBox, PresMovement } from '../nodes/trails';
import { DefaultStyleProvider, StyleProp } from '../StyleProvider';
import { CollectionDockingView } from './CollectionDockingView';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
-import { CollectionView, CollectionViewType } from './CollectionView';
-import "./TabDocView.scss";
-import React = require("react");
-import { listSpec } from '../../../fields/Schema';
-import { ScriptField } from '../../../fields/ScriptField';
-const _global = (window /* browser */ || global /* node */) as any;
+import { CollectionView } from './CollectionView';
+import './TabDocView.scss';
+import React = require('react');
+const _global = (window /* browser */ || global) /* node */ as any;
interface TabDocViewProps {
documentId: FieldId;
@@ -54,9 +52,15 @@ export class TabDocView extends React.Component<TabDocViewProps> {
@observable _document: Doc | undefined;
@observable _view: DocumentView | undefined;
- @computed get layoutDoc() { return this._document && Doc.Layout(this._document); }
- @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); }
- @computed get tabTextColor() { return this._document?.type === DocumentType.PRES ? "black" : StrCast(this._document?._color, StrCast(this._document?.color, DefaultStyleProvider(this._document, undefined, StyleProp.Color))); }
+ @computed get layoutDoc() {
+ return this._document && Doc.Layout(this._document);
+ }
+ @computed get tabColor() {
+ return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor)));
+ }
+ @computed get tabTextColor() {
+ return this._document?.type === DocumentType.PRES ? 'black' : StrCast(this._document?._color, StrCast(this._document?.color, DefaultStyleProvider(this._document, undefined, StyleProp.Color)));
+ }
// @computed get renderBounds() {
// const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0];
// const xbounds = bounds[2] - bounds[0];
@@ -65,74 +69,91 @@ export class TabDocView extends React.Component<TabDocViewProps> {
// return { l: bounds[0] + xbounds / 2 - dim / 2, t: bounds[1] + ybounds / 2 - dim / 2, cx: bounds[0] + xbounds / 2, cy: bounds[1] + ybounds / 2, dim };
// }
- get stack() { return (this.props as any).glContainer.parent.parent; }
- get tab() { return (this.props as any).glContainer.tab; }
- get view() { return this._view; }
+ get stack() {
+ return (this.props as any).glContainer.parent.parent;
+ }
+ get tab() {
+ return (this.props as any).glContainer.tab;
+ }
+ get view() {
+ return this._view;
+ }
_lastTab: any;
_lastView: DocumentView | undefined;
@action
init = (tab: any, doc: Opt<Doc>) => {
if (tab.contentItem === tab.header.parent.getActiveContentItem()) this._activated = true;
- if (tab.DashDoc !== doc && doc && tab.hasOwnProperty("contentItem") && tab.contentItem.config.type !== "stack") {
+ if (tab.DashDoc !== doc && doc && tab.hasOwnProperty('contentItem') && tab.contentItem.config.type !== 'stack') {
tab._disposers = {} as { [name: string]: IReactionDisposer };
tab.contentItem.config.fixed && (tab.contentItem.parent.config.fixed = true);
tab.DashDoc = doc;
const iconType: IconProp = Doc.toIcon(doc);
// setup the title element and set its size according to the # of chars in the title. Show the full title when clicked.
const titleEle = tab.titleElement[0];
- const iconWrap = document.createElement("div");
- const closeWrap = document.createElement("div");
+ const iconWrap = document.createElement('div');
+ const closeWrap = document.createElement('div');
titleEle.size = StrCast(doc.title).length + 3;
titleEle.value = doc.title;
titleEle.onkeydown = (e: KeyboardEvent) => {
e.stopPropagation();
};
- titleEle.onchange = undoBatch(action((e: any) => {
- titleEle.size = e.currentTarget.value.length + 3;
- Doc.GetProto(doc).title = e.currentTarget.value;
- }));
+ titleEle.onchange = undoBatch(
+ action((e: any) => {
+ titleEle.size = e.currentTarget.value.length + 3;
+ Doc.GetProto(doc).title = e.currentTarget.value;
+ })
+ );
if (tab.element[0].children[1].children.length === 1) {
- iconWrap.className = "lm_iconWrap lm_moreInfo";
+ iconWrap.className = 'lm_iconWrap lm_moreInfo';
const dragBtnDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, e => !e.defaultPrevented && DragManager.StartDocumentDrag([iconWrap], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY), returnFalse, action(e => {
- if (this.view) {
- SelectionManager.SelectView(this.view, false);
- let child = this.view.ContentDiv!.children[0];
- while (child.children.length) {
- const next = Array.from(child.children).find(c => c.className?.toString().includes("SVGAnimatedString") || typeof (c.className) === "string");
- if (next?.className?.toString().includes(DocumentView.ROOT_DIV)) break;
- if (next?.className?.toString().includes(DashFieldView.name)) break;
- if (next) child = next;
- else break;
+ setupMoveUpEvents(
+ this,
+ e,
+ e => !e.defaultPrevented && DragManager.StartDocumentDrag([iconWrap], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY),
+ returnFalse,
+ action(e => {
+ if (this.view) {
+ SelectionManager.SelectView(this.view, false);
+ let child = this.view.ContentDiv!.children[0];
+ while (child.children.length) {
+ const next = Array.from(child.children).find(c => c.className?.toString().includes('SVGAnimatedString') || typeof c.className === 'string');
+ if (next?.className?.toString().includes(DocumentView.ROOT_DIV)) break;
+ if (next?.className?.toString().includes(DashFieldView.name)) break;
+ if (next) child = next;
+ else break;
+ }
+ simulateMouseClick(child, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
+ } else {
+ this._activated = true;
+ setTimeout(() => this.view && SelectionManager.SelectView(this.view, false));
}
- simulateMouseClick(child, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
- }
- else { this._activated = true;
- setTimeout(() =>this.view && SelectionManager.SelectView(this.view, false));
- }
- }));
+ })
+ );
};
-
+
const docIcon = <FontAwesomeIcon onPointerDown={dragBtnDown} icon={iconType} />;
- const closeIcon = <FontAwesomeIcon icon={"eye"} />;
+ const closeIcon = <FontAwesomeIcon icon={'eye'} />;
ReactDOM.render(docIcon, iconWrap);
ReactDOM.render(closeIcon, closeWrap);
tab.reactComponents = [iconWrap, closeWrap];
tab.element[0].prepend(iconWrap);
- tab._disposers.layerDisposer = reaction(() => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
+ tab._disposers.layerDisposer = reaction(
+ () => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
({ layer, color }) => {
// console.log("TabDocView: " + this.tabColor);
// console.log("lightOrDark: " + lightOrDark(this.tabColor));
const textColor = lightOrDark(this.tabColor); //not working with StyleProp.Color
titleEle.style.color = textColor;
- titleEle.style.backgroundColor = "transparent";
+ titleEle.style.backgroundColor = 'transparent';
iconWrap.style.color = textColor;
closeWrap.style.color = textColor;
- tab.element[0].style.background = !layer ? color : "dimgrey";
- }, { fireImmediately: true });
+ tab.element[0].style.background = !layer ? color : 'dimgrey';
+ },
+ { fireImmediately: true }
+ );
}
// shifts the focus to this tab when another tab is dragged over it
tab.element[0].onmouseenter = (e: MouseEvent) => {
@@ -142,157 +163,167 @@ export class TabDocView extends React.Component<TabDocViewProps> {
}
};
-
// select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
titleEle.onpointerdown = action((e: any) => {
- if (e.target.className !== "lm_iconWrap") {
+ if (e.target.className !== 'lm_iconWrap') {
if (this.view) SelectionManager.SelectView(this.view, false);
else this._activated = true;
if (Date.now() - titleEle.lastClick < 1000) titleEle.select();
titleEle.lastClick = Date.now();
- (document.activeElement !== titleEle) && titleEle.focus();
+ document.activeElement !== titleEle && titleEle.focus();
}
});
- tab._disposers.selectionDisposer = reaction(() => SelectionManager.Views().some(v => v.topMost && v.props.Document === doc),
- action((selected) => {
+ tab._disposers.selectionDisposer = reaction(
+ () => SelectionManager.Views().some(v => v.topMost && v.props.Document === doc),
+ action(selected => {
if (selected) this._activated = true;
const toggle = tab.element[0].children[1].children[0] as HTMLInputElement;
- selected && tab.contentItem !== tab.header.parent.getActiveContentItem() &&
- UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), "tab switch");
+ selected && tab.contentItem !== tab.header.parent.getActiveContentItem() && UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), 'tab switch');
// toggle.style.fontWeight = selected ? "bold" : "";
// toggle.style.textTransform = selected ? "uppercase" : "";
- }));
-
+ })
+ );
// highlight the tab when the tab document is brushed in any part of the UI
- tab._disposers.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => {
- //titleEle.value = title;
- // titleEle.style.padding = degree ? 0 : 2;
- // titleEle.style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
- }, { fireImmediately: true });
+ tab._disposers.reactionDisposer = reaction(
+ () => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }),
+ ({ title, degree }) => {
+ //titleEle.value = title;
+ // titleEle.style.padding = degree ? 0 : 2;
+ // titleEle.style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
+ },
+ { fireImmediately: true }
+ );
// clean up the tab when it is closed
- tab.closeElement.off('click') //unbind the current click handler
+ tab.closeElement
+ .off('click') //unbind the current click handler
.click(function () {
Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
SelectionManager.DeselectAll();
- UndoManager.RunInBatch(() => tab.contentItem.remove(), "delete tab");
+ UndoManager.RunInBatch(() => tab.contentItem.remove(), 'delete tab');
});
}
- }
+ };
/**
* Adds a document to the presentation view
**/
@action
- public static PinDoc(docs: Doc|Doc[], pinProps?: PinProps) {
- const docList = ((docs instanceof Doc) ? [docs]: docs);
- const batch = UndoManager.StartBatch("pinning doc");
+ public static PinDoc(docs: Doc | Doc[], pinProps?: PinProps) {
+ const docList = docs instanceof Doc ? [docs] : docs;
+ const batch = UndoManager.StartBatch('pinning doc');
// all docs will be added to the ActivePresentation as stored on CurrentUserUtils
- const curPres = CurrentUserUtils.ActivePresentation;
- curPres && docList.forEach(doc => {
- // Edge Case 1: Cannot pin document to itself
- if (doc === curPres) { alert("Cannot pin presentation document to itself"); return; }
- const pinDoc = Doc.MakeAlias(doc);
- pinDoc.presentationTargetDoc = doc;
- pinDoc.title = doc.title + " - Slide";
- pinDoc.data = new List<Doc>(); // the children of the alias' layout are the presentation slide children. the alias' data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
- pinDoc.presMovement = PresMovement.Zoom;
- pinDoc.groupWithUp = false;
- pinDoc.context = curPres;
- // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements. That way the PresBox could configure all of its children at render time
- pinDoc.treeViewRenderAsBulletHeader = true; // forces a tree view to render the document next to the bullet in the header area
- pinDoc.treeViewHeaderWidth = "100%"; // forces the header to grow to be the same size as its largest sibling.
- pinDoc.treeViewChildrenOnRoot = true; // tree view will look for hierarchical children on the root doc, not the data doc.
- pinDoc.treeViewFieldKey = "data"; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
- pinDoc.treeViewExpandedView = "data";// in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
- pinDoc.treeViewGrowsHorizontally = true;// the document expands horizontally when displayed as a tree view header
- pinDoc.treeViewHideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
- const presArray: Doc[] = PresBox.Instance?.sortArray();
- const size: number = PresBox.Instance?._selectedArray.size;
- const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
- const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], null);
- // If pinWithView option set then update scale and x / y props of slide
- if (pinProps?.pinWithView) {
- const viewProps = pinProps.pinWithView;
- pinDoc.presPinView = true;
- pinDoc.presPinViewX = viewProps.bounds.left + viewProps.bounds.width / 2;
- pinDoc.presPinViewY = viewProps.bounds.top + viewProps.bounds.height / 2;
- pinDoc.presPinViewScale = viewProps.scale;
- pinDoc.contentBounds = new List<number>([viewProps.bounds.left, viewProps.bounds.top, viewProps.bounds.left+viewProps.bounds.width, viewProps.bounds.top+viewProps.bounds.height]);
- }
- if (pinProps?.pinDocView) {
- const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(pinDoc.type as any) || pinDoc._viewType === CollectionViewType.Stacking;
- const pannable: boolean = ((pinDoc.type === DocumentType.COL && doc._viewType === CollectionViewType.Freeform) || doc.type === DocumentType.IMG);
- if (scrollable) {
- const scroll = doc._scrollTop;
- pinDoc.presPinView = true;
- pinDoc.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(doc.type as any)) {
- pinDoc.presPinView = true;
- pinDoc.presStartTime = doc._currentTimecode;
- pinDoc.presEndTime = NumCast(doc._currentTimecode) + 0.1;
- } else if (pannable) {
+ const curPres = Doc.ActivePresentation;
+ curPres &&
+ docList.forEach(doc => {
+ // Edge Case 1: Cannot pin document to itself
+ if (doc === curPres) {
+ alert('Cannot pin presentation document to itself');
+ return;
+ }
+ const pinDoc = Doc.MakeAlias(doc);
+ pinDoc.presentationTargetDoc = doc;
+ pinDoc.title = doc.title + ' - Slide';
+ pinDoc.data = new List<Doc>(); // the children of the alias' layout are the presentation slide children. the alias' data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
+ pinDoc.presMovement = PresMovement.Zoom;
+ pinDoc.groupWithUp = false;
+ pinDoc.context = curPres;
+ // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements. That way the PresBox could configure all of its children at render time
+ pinDoc.treeViewRenderAsBulletHeader = true; // forces a tree view to render the document next to the bullet in the header area
+ pinDoc.treeViewHeaderWidth = '100%'; // forces the header to grow to be the same size as its largest sibling.
+ pinDoc.treeViewChildrenOnRoot = true; // tree view will look for hierarchical children on the root doc, not the data doc.
+ pinDoc.treeViewFieldKey = 'data'; // tree view will treat the 'data' field as the field where the hierarchical children are located instead of using the document's layout string field
+ pinDoc.treeViewExpandedView = 'data'; // in case the data doc has an expandedView set, this will mask that field and use the 'data' field when expanding the tree view
+ pinDoc.treeViewGrowsHorizontally = true; // the document expands horizontally when displayed as a tree view header
+ pinDoc.treeViewHideHeaderIfTemplate = true; // this will force the document to render itself as the tree view header
+ const presArray: Doc[] = PresBox.Instance?.sortArray();
+ const size: number = PresBox.Instance?._selectedArray.size;
+ const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
+ const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], null);
+ // If pinWithView option set then update scale and x / y props of slide
+ if (pinProps?.pinWithView) {
+ const viewProps = pinProps.pinWithView;
pinDoc.presPinView = true;
- pinDoc.presPinViewX = pinDoc._panX;
- pinDoc.presPinViewY = pinDoc._panY;
- pinDoc.presPinViewScale = pinDoc._viewScale;
- const pw = NumCast(pinProps.panelWidth);
- const ph = NumCast(pinProps.panelHeight);
- const ps = NumCast(pinDoc._viewScale);
- if (pw && ph && ps) {
- pinDoc.contentBounds = new List<number>([
- NumCast(pinDoc.panX)-pw/2/ps,
- NumCast(pinDoc.panY)-ph/2/ps,
- NumCast(pinDoc.panX)+pw/2/ps,
- NumCast(pinDoc.panY)+ph/2/ps]);
+ pinDoc.presPinViewX = viewProps.bounds.left + viewProps.bounds.width / 2;
+ pinDoc.presPinViewY = viewProps.bounds.top + viewProps.bounds.height / 2;
+ pinDoc.presPinViewScale = viewProps.scale;
+ pinDoc.contentBounds = new List<number>([viewProps.bounds.left, viewProps.bounds.top, viewProps.bounds.left + viewProps.bounds.width, viewProps.bounds.top + viewProps.bounds.height]);
+ }
+ if (pinProps?.pinDocView) {
+ const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(pinDoc.type as any) || pinDoc._viewType === CollectionViewType.Stacking;
+ const pannable: boolean = (pinDoc.type === DocumentType.COL && doc._viewType === CollectionViewType.Freeform) || doc.type === DocumentType.IMG;
+ if (scrollable) {
+ const scroll = doc._scrollTop;
+ pinDoc.presPinView = true;
+ pinDoc.presPinViewScroll = scroll;
+ } else if ([DocumentType.AUDIO, DocumentType.VID].includes(doc.type as any)) {
+ pinDoc.presPinView = true;
+ pinDoc.presStartTime = doc._currentTimecode;
+ pinDoc.presEndTime = NumCast(doc._currentTimecode) + 0.1;
+ } else if (pannable) {
+ pinDoc.presPinView = true;
+ pinDoc.presPinViewX = pinDoc._panX;
+ pinDoc.presPinViewY = pinDoc._panY;
+ pinDoc.presPinViewScale = pinDoc._viewScale;
+ const pw = NumCast(pinProps.panelWidth);
+ const ph = NumCast(pinProps.panelHeight);
+ const ps = NumCast(pinDoc._viewScale);
+ if (pw && ph && ps) {
+ pinDoc.contentBounds = new List<number>([NumCast(pinDoc.panX) - pw / 2 / ps, NumCast(pinDoc.panY) - ph / 2 / ps, NumCast(pinDoc.panX) + pw / 2 / ps, NumCast(pinDoc.panY) + ph / 2 / ps]);
+ }
+ } else if (doc.type === DocumentType.COMPARISON) {
+ const width = doc._clipWidth;
+ pinDoc.presPinClipWidth = width;
+ pinDoc.presPinView = true;
}
- } else if (doc.type === DocumentType.COMPARISON) {
- const width = doc._clipWidth;
- pinDoc.presPinClipWidth = width;
- pinDoc.presPinView = true;
}
- }
- pinDoc.onClick = ScriptField.MakeFunction("navigateToDoc(self.presentationTargetDoc, self)");
- Doc.AddDocToList(curPres, "data", pinDoc, presSelected);
- if (!pinProps?.audioRange && duration !== undefined) {
- pinDoc.mediaStart = "manual";
- pinDoc.mediaStop = "manual";
- pinDoc.presStartTime = NumCast(doc.clipStart);
- pinDoc.presEndTime = NumCast(doc.clipEnd, duration);
- }
- //save position
- if (pinProps?.setPosition || pinDoc.isInkMask) {
- pinDoc.setPosition = true;
- pinDoc.y = doc.y;
- pinDoc.x = doc.x;
- pinDoc.presHideAfter = true;
- pinDoc.presHideBefore = true;
- pinDoc.title = doc.title + " (move)";
- pinDoc.presMovement = PresMovement.None;
- }
- if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
- PresBox.Instance?._selectedArray.clear();
- pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
- });
- if (!Array.from(CollectionDockingView.Instance.tabMap).map(d => d.DashDoc).includes(curPres)) {
- const docs = Cast(CurrentUserUtils.MyOverlayDocs.data, listSpec(Doc), []);
+ pinDoc.onClick = ScriptField.MakeFunction('navigateToDoc(self.presentationTargetDoc, self)');
+ Doc.AddDocToList(curPres, 'data', pinDoc, presSelected);
+ if (!pinProps?.audioRange && duration !== undefined) {
+ pinDoc.mediaStart = 'manual';
+ pinDoc.mediaStop = 'manual';
+ pinDoc.presStartTime = NumCast(doc.clipStart);
+ pinDoc.presEndTime = NumCast(doc.clipEnd, duration);
+ }
+ //save position
+ if (pinProps?.setPosition || pinDoc.isInkMask) {
+ pinDoc.setPosition = true;
+ pinDoc.y = doc.y;
+ pinDoc.x = doc.x;
+ pinDoc.presHideAfter = true;
+ pinDoc.presHideBefore = true;
+ pinDoc.title = doc.title + ' (move)';
+ pinDoc.presMovement = PresMovement.None;
+ }
+ if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
+ PresBox.Instance?._selectedArray.clear();
+ pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
+ });
+ if (
+ !Array.from(CollectionDockingView.Instance.tabMap)
+ .map(d => d.DashDoc)
+ .includes(curPres)
+ ) {
+ const docs = Cast(Doc.MyOverlayDocs.data, listSpec(Doc), []);
if (docs.includes(curPres)) docs.splice(docs.indexOf(curPres), 1);
- CollectionDockingView.AddSplit(curPres, "right");
+ CollectionDockingView.AddSplit(curPres, 'right');
setTimeout(() => DocumentManager.Instance.jumpToDocument(docList.lastElement(), false, undefined, []), 100); // keeps the pinned doc in view since the sidebar shifts things
}
setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
}
componentDidMount() {
- new _global.ResizeObserver(action((entries: any) => {
- for (const entry of entries) {
- this._panelWidth = entry.contentRect.width;
- this._panelHeight = entry.contentRect.height;
- }
- })).observe(this.props.glContainer._element[0]);
- this.props.glContainer.layoutManager.on("activeContentItemChanged", this.onActiveContentItemChanged);
+ new _global.ResizeObserver(
+ action((entries: any) => {
+ for (const entry of entries) {
+ this._panelWidth = entry.contentRect.width;
+ this._panelHeight = entry.contentRect.height;
+ }
+ })
+ ).observe(this.props.glContainer._element[0]);
+ this.props.glContainer.layoutManager.on('activeContentItemChanged', this.onActiveContentItemChanged);
this.props.glContainer.tab?.isActive && this.onActiveContentItemChanged(undefined);
// this._tabReaction = reaction(() => ({ selected: this.active(), title: this.tab?.titleElement[0] }),
// ({ selected, title }) => title && (title.style.backgroundColor = selected ? "white" : ""),
@@ -306,7 +337,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
this._tabReaction?.();
this._view && DocumentManager.Instance.RemoveView(this._view);
- this.props.glContainer.layoutManager.off("activeContentItemChanged", this.onActiveContentItemChanged);
+ this.props.glContainer.layoutManager.off('activeContentItemChanged', this.onActiveContentItemChanged);
}
@action.bound
@@ -326,25 +357,31 @@ export class TabDocView extends React.Component<TabDocViewProps> {
// inPlace - will add the document to any collection along the path from the document to the docking view that has a field isInPlaceContainer. if none is found, inPlace adds a tab to current stack
addDocTab = (doc: Doc, location: string) => {
SelectionManager.DeselectAll();
- const locationFields = doc._viewType === CollectionViewType.Docking ? ["dashboard"] : location.split(":");
- const locationParams = locationFields.length > 1 ? locationFields[1] : "";
+ const locationFields = doc._viewType === CollectionViewType.Docking ? ['dashboard'] : location.split(':');
+ const locationParams = locationFields.length > 1 ? locationFields[1] : '';
switch (locationFields[0]) {
- case "dashboard": return CurrentUserUtils.openDashboard(doc);
- case "close": return CollectionDockingView.CloseSplit(doc, locationParams);
- case "fullScreen": return CollectionDockingView.OpenFullScreen(doc);
- case "replace": return CollectionDockingView.ReplaceTab(doc, locationParams, this.stack);
+ case 'dashboard':
+ return DashboardView.openDashboard(doc);
+ case 'close':
+ return CollectionDockingView.CloseSplit(doc, locationParams);
+ case 'fullScreen':
+ return CollectionDockingView.OpenFullScreen(doc);
+ case 'replace':
+ return CollectionDockingView.ReplaceTab(doc, locationParams, this.stack);
// case "lightbox": {
// // TabDocView.PinDoc(doc, { hidePresBox: true });
// return LightboxView.AddDocTab(doc, location, undefined, this.addDocTab);
// }
- case "lightbox": return LightboxView.AddDocTab(doc, location, undefined, this.addDocTab);
- case "toggle": return CollectionDockingView.ToggleSplit(doc, locationParams, this.stack);
- case "inPlace":
- case "add":
+ case 'lightbox':
+ return LightboxView.AddDocTab(doc, location, undefined, this.addDocTab);
+ case 'toggle':
+ return CollectionDockingView.ToggleSplit(doc, locationParams, this.stack);
+ case 'inPlace':
+ case 'add':
default:
return CollectionDockingView.AddSplit(doc, locationParams, this.stack);
}
- }
+ };
remDocTab = (doc: Doc | Doc[]) => {
if (doc === this._document) {
SelectionManager.DeselectAll();
@@ -352,11 +389,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
return true;
}
return false;
- }
+ };
getCurrentFrame = () => {
return NumCast(Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex].presentationTargetDoc, Doc, null)._currentFrame);
- }
+ };
@action
focusFunc = (doc: Doc, options?: DocFocusOptions) => {
const shrinkwrap = options?.originalTarget === this._document && this.view?.ComponentView?.shrinkWrap;
@@ -364,104 +401,113 @@ export class TabDocView extends React.Component<TabDocViewProps> {
const focusSpeed = 1000;
shrinkwrap();
this._document._viewTransition = `transform ${focusSpeed}ms`;
- setTimeout(action(() => {
- this._document!._viewTransition = undefined;
- options?.afterFocus?.(false);
- }), focusSpeed);
+ setTimeout(
+ action(() => {
+ this._document!._viewTransition = undefined;
+ options?.afterFocus?.(false);
+ }),
+ focusSpeed
+ );
} else {
options?.afterFocus?.(false);
}
if (!this.tab.header.parent._activeContentItem || this.tab.header.parent._activeContentItem !== this.tab.contentItem) {
this.tab.header.parent.setActiveContentItem(this.tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
}
- }
+ };
active = () => this._isActive;
@observable _forceInvalidateScreenToLocal = 0;
ScreenToLocalTransform = () => {
this._forceInvalidateScreenToLocal;
const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont?.children?.[0] as HTMLElement);
return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY);
- }
+ };
PanelWidth = () => this._panelWidth;
PanelHeight = () => this._panelHeight;
miniMapColor = () => this.tabColor;
tabView = () => this._view;
- disableMinimap = () => !this._document || (this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._viewType !== CollectionViewType.Freeform);
+ disableMinimap = () => !this._document || this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._viewType !== CollectionViewType.Freeform;
hideMinimap = () => this.disableMinimap() || BoolCast(this._document?.hideMinimap);
@computed get docView() {
- return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? (null) :
- <><DocumentView key={this._document[Id]} ref={action((r: DocumentView) => {
- this._lastView && DocumentManager.Instance.RemoveView(this._lastView);
- this._view = r;
- this._lastView = this._view;
- })}
- renderDepth={0}
- Document={this._document}
- DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- onBrowseClick={MainView.Instance.exploreMode}
- isContentActive={returnTrue}
- PanelWidth={this.PanelWidth}
- PanelHeight={this.PanelHeight}
- styleProvider={DefaultStyleProvider}
- docFilters={CollectionDockingView.Instance.childDocFilters}
- docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
- searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
- addDocument={undefined}
- removeDocument={this.remDocTab}
- addDocTab={this.addDocTab}
- ScreenToLocalTransform={this.ScreenToLocalTransform}
- dontCenter={"y"}
- rootSelected={returnTrue}
- whenChildContentsActiveChanged={emptyFunction}
- focus={this.focusFunc}
- docViewPath={returnEmptyDoclist}
- bringToFront={emptyFunction}
- pinToPres={TabDocView.PinDoc} />
- <TabMinimapView key="minimap"
- hideMinimap={this.hideMinimap}
- addDocTab={this.addDocTab}
- PanelHeight={this.PanelHeight}
+ return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? null : (
+ <>
+ <DocumentView
+ key={this._document[Id]}
+ ref={action((r: DocumentView) => {
+ this._lastView && DocumentManager.Instance.RemoveView(this._lastView);
+ this._view = r;
+ this._lastView = this._view;
+ })}
+ renderDepth={0}
+ Document={this._document}
+ DataDoc={!Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ onBrowseClick={MainView.Instance.exploreMode}
+ isContentActive={returnTrue}
PanelWidth={this.PanelWidth}
- background={this.miniMapColor}
- document={this._document}
- tabView={this.tabView} />
- <Tooltip key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}>
- <div className="miniMap-hidden"
+ PanelHeight={this.PanelHeight}
+ styleProvider={DefaultStyleProvider}
+ docFilters={CollectionDockingView.Instance.childDocFilters}
+ docRangeFilters={CollectionDockingView.Instance.childDocRangeFilters}
+ searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
+ addDocument={undefined}
+ removeDocument={this.remDocTab}
+ addDocTab={this.addDocTab}
+ ScreenToLocalTransform={this.ScreenToLocalTransform}
+ dontCenter={'y'}
+ rootSelected={returnTrue}
+ whenChildContentsActiveChanged={emptyFunction}
+ focus={this.focusFunc}
+ docViewPath={returnEmptyDoclist}
+ bringToFront={emptyFunction}
+ pinToPres={TabDocView.PinDoc}
+ />
+ <TabMinimapView key="minimap" hideMinimap={this.hideMinimap} addDocTab={this.addDocTab} PanelHeight={this.PanelHeight} PanelWidth={this.PanelWidth} background={this.miniMapColor} document={this._document} tabView={this.tabView} />
+ <Tooltip key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? 'Open minimap' : 'Close minimap'}</div>}>
+ <div
+ className="miniMap-hidden"
style={{
- display: this.disableMinimap() || this._document._viewType !== "freeform" ? "none" : undefined,
+ display: this.disableMinimap() || this._document._viewType !== 'freeform' ? 'none' : undefined,
color: this._document.hideMinimap ? Colors.BLACK : Colors.WHITE,
backgroundColor: this._document.hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
- boxShadow: this._document.hideMinimap ? Shadows.STANDARD_SHADOW : undefined
+ boxShadow: this._document.hideMinimap ? Shadows.STANDARD_SHADOW : undefined,
}}
onPointerDown={e => e.stopPropagation()}
- onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} >
- <FontAwesomeIcon icon={"globe-asia"} size="lg" />
+ onClick={action(e => {
+ e.stopPropagation();
+ this._document!.hideMinimap = !this._document!.hideMinimap;
+ })}>
+ <FontAwesomeIcon icon={'globe-asia'} size="lg" />
</div>
</Tooltip>
- </>;
+ </>
+ );
}
render() {
return (
- <div className="collectionDockingView-content" style={{
- fontFamily: Doc.UserDoc().renderStyle === "comic" ? "Comic Sans MS" : undefined,
- height: "100%", width: "100%"
- }} ref={ref => {
- if (this._mainCont = ref) {
- if (this._lastTab) {
- this._view && DocumentManager.Instance.RemoveView(this._view);
+ <div
+ className="collectionDockingView-content"
+ style={{
+ fontFamily: Doc.UserDoc().renderStyle === 'comic' ? 'Comic Sans MS' : undefined,
+ height: '100%',
+ width: '100%',
+ }}
+ ref={ref => {
+ if ((this._mainCont = ref)) {
+ if (this._lastTab) {
+ this._view && DocumentManager.Instance.RemoveView(this._view);
+ }
+ this._lastTab = this.tab;
+ (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
+ DocServer.GetRefField(this.props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document)));
+ new _global.ResizeObserver(action((entries: any) => this._forceInvalidateScreenToLocal++)).observe(ref);
}
- this._lastTab = this.tab;
- (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
- DocServer.GetRefField(this.props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document)));
- new _global.ResizeObserver(action((entries: any) => this._forceInvalidateScreenToLocal++)).observe(ref);
- }
- }} >
+ }}>
{this.docView}
- </div >
+ </div>
);
}
}
@@ -479,29 +525,38 @@ interface TabMinimapViewProps {
export class TabMinimapView extends React.Component<TabMinimapViewProps> {
static miniStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
if (doc) {
- switch (property.split(":")[0]) {
- default: return DefaultStyleProvider(doc, props, property);
- case StyleProp.PointerEvents: return "none";
+ switch (property.split(':')[0]) {
+ default:
+ return DefaultStyleProvider(doc, props, property);
+ case StyleProp.PointerEvents:
+ return 'none';
case StyleProp.DocContents:
const background = ((type: DocumentType) => {
switch (type) {
- case DocumentType.PDF: return "pink";
- case DocumentType.AUDIO: return "lightgreen";
- case DocumentType.WEB: return "brown";
- case DocumentType.IMG: return "blue";
- case DocumentType.MAP: return "orange";
- case DocumentType.VID: return "purple";
- case DocumentType.RTF: return "yellow";
- case DocumentType.COL: return undefined;
- default: return "gray";
+ case DocumentType.PDF:
+ return 'pink';
+ case DocumentType.AUDIO:
+ return 'lightgreen';
+ case DocumentType.WEB:
+ return 'brown';
+ case DocumentType.IMG:
+ return 'blue';
+ case DocumentType.MAP:
+ return 'orange';
+ case DocumentType.VID:
+ return 'purple';
+ case DocumentType.RTF:
+ return 'yellow';
+ case DocumentType.COL:
+ return undefined;
+ default:
+ return 'gray';
}
})(doc.type as DocumentType);
- return !background ?
- undefined :
- <div style={{ width: doc[WidthSym](), height: doc[HeightSym](), position: "absolute", display: "block", background }} />;
+ return !background ? undefined : <div style={{ width: doc[WidthSym](), height: doc[HeightSym](), position: 'absolute', display: 'block', background }} />;
}
}
- }
+ };
@computed get renderBounds() {
const compView = this.props.tabView()?.ComponentView as CollectionFreeFormView;
const bounds = compView?.freeformData?.(true)?.bounds;
@@ -517,20 +572,27 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
const doc = this.props.document;
const renderBounds = this.renderBounds ?? { l: 0, r: 0, t: 0, b: 0, dim: 1 };
const miniSize = this.returnMiniSize();
- doc && setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
- doc._panX = clamp(NumCast(doc._panX) + delta[0] / miniSize * renderBounds.dim, renderBounds.l, renderBounds.l + renderBounds.dim);
- doc._panY = clamp(NumCast(doc._panY) + delta[1] / miniSize * renderBounds.dim, renderBounds.t, renderBounds.t + renderBounds.dim);
- return false;
- }), emptyFunction, emptyFunction);
- }
+ doc &&
+ setupMoveUpEvents(
+ this,
+ e,
+ action((e: PointerEvent, down: number[], delta: number[]) => {
+ doc._panX = clamp(NumCast(doc._panX) + (delta[0] / miniSize) * renderBounds.dim, renderBounds.l, renderBounds.l + renderBounds.dim);
+ doc._panY = clamp(NumCast(doc._panY) + (delta[1] / miniSize) * renderBounds.dim, renderBounds.t, renderBounds.t + renderBounds.dim);
+ return false;
+ }),
+ emptyFunction,
+ emptyFunction
+ );
+ };
render() {
- if (!this.renderBounds) return (null);
- const miniWidth = this.props.PanelWidth() / NumCast(this.props.document._viewScale, 1) / this.renderBounds.dim * 100;
- const miniHeight = this.props.PanelHeight() / NumCast(this.props.document._viewScale, 1) / this.renderBounds.dim * 100;
- const miniLeft = 50 + (NumCast(this.props.document._panX) - this.renderBounds.cx) / this.renderBounds.dim * 100 - miniWidth / 2;
- const miniTop = 50 + (NumCast(this.props.document._panY) - this.renderBounds.cy) / this.renderBounds.dim * 100 - miniHeight / 2;
+ if (!this.renderBounds) return null;
+ const miniWidth = (this.props.PanelWidth() / NumCast(this.props.document._viewScale, 1) / this.renderBounds.dim) * 100;
+ const miniHeight = (this.props.PanelHeight() / NumCast(this.props.document._viewScale, 1) / this.renderBounds.dim) * 100;
+ const miniLeft = 50 + ((NumCast(this.props.document._panX) - this.renderBounds.cx) / this.renderBounds.dim) * 100 - miniWidth / 2;
+ const miniTop = 50 + ((NumCast(this.props.document._panY) - this.renderBounds.cy) / this.renderBounds.dim) * 100 - miniHeight / 2;
const miniSize = this.returnMiniSize();
- return this.props.hideMinimap() ? (null) :
+ return this.props.hideMinimap() ? null : (
<div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
<CollectionFreeFormView
Document={this.props.document}
@@ -567,9 +629,10 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs}
fitContentsToBox={returnTrue}
/>
- <div className="miniOverlay" onPointerDown={this.miniDown} >
- <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% `, }} />
+ <div className="miniOverlay" onPointerDown={this.miniDown}>
+ <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
</div>
- </div>;
+ </div>
+ );
}
-} \ No newline at end of file
+}