aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/DocumentDecorations.tsx5
-rw-r--r--src/client/views/TagsView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx3
-rw-r--r--src/client/views/collections/TabDocView.tsx175
4 files changed, 77 insertions, 108 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4b0198021..5e7908725 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -646,7 +646,6 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
render() {
const { b, r, x, y } = this.Bounds;
const seldocview = DocumentView.Selected().lastElement();
- const doc = DocumentView.SelectedDocs().lastElement();
if (SnappingManager.IsDragging || r - x < 1 || x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(r) || isNaN(b) || isNaN(x) || isNaN(y)) {
setTimeout(
action(() => {
@@ -838,7 +837,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
<div
className="link-button-container"
style={{
- top: DocumentView.Selected().length > 1 ? 0 : `${doc._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
+ top: DocumentView.Selected().length > 1 ? 0 : `${seldocview.Document._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
}}>
<DocumentButtonBar views={() => DocumentView.Selected()} />
@@ -847,7 +846,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
<div
className="documentDecorations-tagsView"
style={{
- top: `${doc._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
+ top: `${seldocview.Document._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
}}>
{DocumentView.Selected().length > 1 ? <TagsView Views={DocumentView.Selected()} /> : null}
diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx
index 0b303f6f5..be2c28185 100644
--- a/src/client/views/TagsView.tsx
+++ b/src/client/views/TagsView.tsx
@@ -336,7 +336,7 @@ export class TagsView extends ObservableReactComponent<TagViewProps> {
);
this._panelHeightDirty;
- return !this.View.Document._layout_showTags && this._props.Views.length === 1 ? null : (
+ return this.View.ComponentView?.isUnstyledView?.() || (!this.View.Document._layout_showTags && this._props.Views.length === 1) ? null : (
<div
className="tagsView-container"
ref={r => r && new ResizeObserver(action(() => this._props.Views.length === 1 && (this.View.TagPanelHeight = Math.max(0, (r?.getBoundingClientRect().height ?? 0) - this.InsetDist)))).observe(r)}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index e0aa79c7b..028133a6e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -31,6 +31,7 @@ import { ScriptingRepl } from '../ScriptingRepl';
import { UndoStack } from '../UndoStack';
import './CollectionDockingView.scss';
import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
+import { TabHTMLElement } from './TabDocView';
@observer
export class CollectionDockingView extends CollectionSubView() {
@@ -544,7 +545,7 @@ export class CollectionDockingView extends CollectionSubView() {
tabCreated = (tab: { contentItem: { element: HTMLElement[] } }) => {
this.tabMap.add(tab);
// InitTab is added to the tab's HTMLElement in TabDocView
- const tabdocviewContent = tab.contentItem.element[0]?.firstChild?.firstChild as unknown as { InitTab?: (tab: object) => void };
+ const tabdocviewContent = tab.contentItem.element[0]?.firstChild?.firstChild as unknown as TabHTMLElement;
tabdocviewContent?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
};
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 31b6be927..def1ea731 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -57,6 +57,7 @@ interface TabMiniThumbProps {
miniLeft: () => number;
}
+export type TabHTMLElement = HTMLDivElement & { InitTab?: (tab: object) => void };
@observer
class TabMiniThumb extends React.Component<TabMiniThumbProps> {
render() {
@@ -193,8 +194,9 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
.filter(tv => tv._document)
.map(tv => tv._document!);
}
- _mainCont: HTMLDivElement | null = null;
+ _mainCont: TabHTMLElement | null = null;
_tabReaction: IReactionDisposer | undefined;
+ _lastSelection = 0; // time when view was last selected - used to re-select views that get invalidated when selected
/**
* Adds a document to the presentation view
@@ -273,19 +275,24 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
}
+ // Flag indicating that when a tab is activated, it should not select it's document.
+ // this is used by the link properties menu when it wants to display the link target without selecting the target (which would make the link property window go away since it would no longer be selected)
+ public static DontSelectOnActivate = 'dontSelectOnActivate';
+
+ public static IsSelected = (doc?: Doc) => {
+ return DocumentView.getViews(doc).some(dv => dv?.IsSelected);
+ };
+
static Activate = (tabDoc: Doc) => {
const tab = Array.from(CollectionDockingView.Instance?.tabMap ?? []).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue);
tab?.header.parent.setActiveContentItem(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)
return tab !== undefined;
};
- // static ActivateTabView(doc: Doc) {
- // const tabView = Array.from(TabDocView._allTabs).find(view => view._document === doc);
- // if (!tabView?._activated && tabView?._document) {
- // TabDocView.Activate(tabView?._document);
- // return tabView;
- // }
- // return undefined;
- // }
+
+ get stack() { return this._props.glContainer.parent.parent; } // prettier-ignore
+ get tab() { return this._props.glContainer.tab; } // prettier-ignore
+ get view() { return this._view; } // prettier-ignore
+
constructor(props: TabDocViewProps) {
super(props);
makeObservable(this);
@@ -299,37 +306,13 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
@observable _hovering = false;
@observable _isActive: boolean = false;
@observable _isAnyChildContentActive = false;
- public static IsSelected = (doc?: Doc) => {
- if (DocumentView.getViews(doc).some(dv => dv?.IsSelected)) {
- return true;
- }
- return false;
- };
- @computed get _isUserActivated() {
- return TabDocView.IsSelected(this._document) || this._isAnyChildContentActive;
- }
- get _isContentActive() {
- return this._isUserActivated || this._hovering;
- }
@observable _document: Doc | undefined = undefined;
@observable _view: DocumentView | undefined = undefined;
+ @observable _forceInvalidateScreenToLocal = 0; // screentolocal is computed outside of react using a dom resize ovbserver. this hack allows the resize observer to trigger a react update
- @computed get layoutDoc() {
- return this._document && Doc.Layout(this._document);
- }
-
- get stack() {
- return this._props.glContainer.parent.parent;
- }
- get tab() {
- return this._props.glContainer.tab;
- }
- get view() {
- return this._view;
- }
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- _lastTab: any;
- _lastView: DocumentView | undefined;
+ @computed get layoutDoc() { return this._document && Doc.Layout(this._document); } // prettier-ignore
+ @computed get isUserActivated() { return TabDocView.IsSelected(this._document) || this._isAnyChildContentActive; } // prettier-ignore
+ @computed get isContentActive() { return this.isUserActivated || this._hovering; } // prettier-ignore
@action
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -413,7 +396,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
color === variant
? DashColor(color)
.fade(
- this._isUserActivated
+ this.isUserActivated
? 0
: this._hovering
? 0.25
@@ -522,19 +505,14 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
this._props.glContainer.layoutManager.off('activeContentItemChanged', this.onActiveContentItemChanged);
}
- // Flag indicating that when a tab is activated, it should not select it's document.
- // this is used by the link properties menu when it wants to display the link target without selecting the target (which would make the link property window go away since it would no longer be selected)
- public static DontSelectOnActivate = 'dontSelectOnActivate';
-
- @action.bound
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- private onActiveContentItemChanged(contentItem: any) {
+ onActiveContentItemChanged = (contentItem: any) => {
if (!contentItem || (this.stack === contentItem.parent && ((contentItem?.tab === this.tab && !this._isActive) || (contentItem?.tab !== this.tab && this._isActive)))) {
this._activated = this._isActive = !contentItem || contentItem?.tab === this.tab;
if (!this._view && this.tab?.contentItem?.config?.props?.panelName !== TabDocView.DontSelectOnActivate) setTimeout(() => DocumentView.SelectView(this._view, false));
!this._isActive && this._document && Doc.UnBrushDoc(this._document); // bcz: bad -- trying to simulate a pointer leave event when a new tab is opened up on top of an existing one.
}
- }
+ };
// adds a tab to the layout based on the locaiton parameter which can be:
// close[:{left,right,top,bottom}] - e.g., "close" will close the tab, "close:left" will close the left tab,
@@ -551,7 +529,6 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
const whereMods = whereFields.length > 1 ? (whereFields[1] as OpenWhereMod) : OpenWhereMod.none;
const panelName = whereFields.length > 1 ? whereFields.lastElement() : '';
if (docs[0]?.dockingConfig && !keyValue) return DashboardView.openDashboard(docs[0]);
- // prettier-ignore
switch (whereFields[0]) {
case undefined:
case OpenWhere.lightbox: return LightboxView.Instance.AddDocTab(docs[0], location);
@@ -559,7 +536,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
case OpenWhere.replace: return CollectionDockingView.ReplaceTab(docs[0], whereMods, this.stack, panelName, undefined, keyValue);
case OpenWhere.toggle: return CollectionDockingView.ToggleSplit(docs[0], whereMods, this.stack, TabDocView.DontSelectOnActivate, keyValue);
case OpenWhere.add:default:return CollectionDockingView.AddSplit(docs[0], whereMods, this.stack, undefined, keyValue);
- }
+ } // prettier-ignore
};
remDocTab = (doc: Doc | Doc[]) => {
if (doc === this._document) {
@@ -571,8 +548,6 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
};
getCurrentFrame = () => NumCast(Cast(PresBox.Instance.activeItem.presentation_targetDoc, Doc, null)._currentFrame);
-
- @action
focusFunc = () => {
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)
@@ -580,7 +555,6 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
return undefined;
};
active = () => this._isActive;
- @observable _forceInvalidateScreenToLocal = 0;
ScreenToLocalTransform = () => {
this._forceInvalidateScreenToLocal;
const { translateX, translateY } = ClientUtils.GetScreenTransform(this._mainCont?.children?.[0] as HTMLElement);
@@ -594,47 +568,44 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
whenChildContentActiveChanges = (isActive: boolean) => {
this._isAnyChildContentActive = isActive;
};
- isContentActive = () => this._isContentActive;
+ isContentActiveFunc = () => this.isContentActive;
waitForDoubleClick = () => (SnappingManager.ExploreMode ? 'never' : undefined);
- @computed get docView() {
- return !this._activated || !this._document ? null : (
- <>
- <DocumentView
- key={this._document[Id]}
- ref={action((r: DocumentView) => {
- this._lastView && DocumentView.removeView(this._lastView);
- this._view = r;
- this._lastView = this._view;
- })}
- renderDepth={0}
- LayoutTemplateString={this._props.keyValue ? KeyValueBox.LayoutString() : undefined}
- hideTitle={this._props.keyValue}
- Document={this._document}
- TemplateDataDocument={!Doc.AreProtosEqual(this._document[DocData], this._document) ? this._document[DocData] : undefined}
- waitForDoubleClickToClick={this.waitForDoubleClick}
- isContentActive={this.isContentActive}
- isDocumentActive={returnFalse}
- PanelWidth={this.PanelWidth}
- PanelHeight={this.PanelHeight}
- styleProvider={DefaultStyleProvider}
- childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyFilter}
- childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyFilter}
- searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
- addDocument={undefined}
- removeDocument={this.remDocTab}
- addDocTab={this.addDocTab}
- suppressSetHeight={!!this._document._layout_fitWidth}
- ScreenToLocalTransform={this.ScreenToLocalTransform}
- dontCenter="y"
- whenChildContentsActiveChanged={this.whenChildContentActiveChanges}
- focus={this.focusFunc}
- containerViewPath={returnEmptyDocViewList}
- pinToPres={TabDocView.PinDoc}
- />
- {this.disableMinimap() ? null : <TabMinimapView key="minimap" addDocTab={this.addDocTab} PanelHeight={this.PanelHeight} PanelWidth={this.PanelWidth} background={this.miniMapColor} document={this._document} tabView={this.tabView} />}
- </>
- );
- }
+ renderDocView = (doc: Doc) => (
+ <DocumentView
+ key={doc[Id]}
+ ref={action((r: DocumentView) => {
+ const now = Date.now();
+ this._lastSelection = this._view?.IsSelected ? now : this._lastSelection;
+ if (this._view) DocumentView.removeView(this._view);
+ this._view = r;
+ if (this._view && now - this._lastSelection < 1000) this._view.select(false);
+ })}
+ renderDepth={0}
+ LayoutTemplateString={this._props.keyValue ? KeyValueBox.LayoutString() : undefined}
+ hideTitle={this._props.keyValue}
+ Document={doc}
+ TemplateDataDocument={!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined}
+ waitForDoubleClickToClick={this.waitForDoubleClick}
+ isContentActive={this.isContentActiveFunc}
+ isDocumentActive={returnFalse}
+ PanelWidth={this.PanelWidth}
+ PanelHeight={this.PanelHeight}
+ styleProvider={DefaultStyleProvider}
+ childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyFilter}
+ childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyFilter}
+ searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
+ addDocument={undefined}
+ removeDocument={this.remDocTab}
+ addDocTab={this.addDocTab}
+ suppressSetHeight={!!doc._layout_fitWidth}
+ ScreenToLocalTransform={this.ScreenToLocalTransform}
+ dontCenter="y"
+ whenChildContentsActiveChanged={this.whenChildContentActiveChanges}
+ focus={this.focusFunc}
+ containerViewPath={returnEmptyDocViewList}
+ pinToPres={TabDocView.PinDoc}
+ />
+ );
render() {
return (
@@ -647,23 +618,21 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
onPointerLeave={action(() => { this._hovering = false; })} // prettier-ignore
onDragOver={action(() => { this._hovering = true; })} // prettier-ignore
onDragLeave={action(() => { this._hovering = false; })} // prettier-ignore
- ref={ref => {
+ ref={(ref: TabHTMLElement) => {
+ // "add" an InitTab function to this div to call from tabCreated in CollectionDockingView when div is reused
this._mainCont = ref;
if (this._mainCont) {
- if (this._lastTab) {
- this._view && DocumentView.removeView(this._view);
- }
- this._lastTab = this.tab;
- (this._mainCont as { InitTab?: (tab: object) => void }).InitTab = (tab: object) => 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);
- })
- );
- ref && new ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(ref);
+ this._mainCont.InitTab = (tab: object) => 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);
+ })); // prettier-ignore
+ new ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(this._mainCont);
}
}}>
- {this.docView}
+ {!this._activated || !this._document ? null : this.renderDocView(this._document)}
+ {this.disableMinimap() || !this._document ? null : (
+ <TabMinimapView key="minimap" addDocTab={this.addDocTab} PanelHeight={this.PanelHeight} PanelWidth={this.PanelWidth} background={this.miniMapColor} document={this._document} tabView={this.tabView} />
+ )}
</div>
);
}