From 446ab35c19ae18a609acf26babbc4e6dc1c46876 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 2 Jul 2023 19:06:56 -0400 Subject: improved highlighting of tabs to show focus/active. added. menu item to open a tab in lightbox --- .../views/collections/CollectionDockingView.scss | 6 + .../views/collections/CollectionDockingView.tsx | 10 +- src/client/views/collections/TabDocView.tsx | 144 +++++++++++---------- 3 files changed, 94 insertions(+), 66 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 78e44dfa2..4c15d5eed 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -15,6 +15,12 @@ cursor: grab; color: $black; } +.collectiondockingview-container .lm_splitter { + opacity: 0.2; + &:hover { + opacity: 1; + } +} .lm_title.focus-visible { -webkit-appearance: none; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 3bf3f1a74..2ed55b3ca 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -29,6 +29,7 @@ import { CollectionFreeFormView } from './collectionFreeForm'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { TabDocView } from './TabDocView'; import React = require('react'); +import { DocumentManager } from '../../util/DocumentManager'; const _global = (window /* browser */ || global) /* node */ as any; @observer @@ -410,7 +411,14 @@ export class CollectionDockingView extends CollectionSubView() { if (!htmlTarget.closest('*.lm_content') && (htmlTarget.closest('*.lm_tab') || htmlTarget.closest('*.lm_stack'))) { const className = typeof htmlTarget.className === 'string' ? htmlTarget.className : ''; if (className.includes('lm_maximise')) this._flush = UndoManager.StartBatch('tab maximize'); - else if (!className.includes('lm_close')) DocServer.UPDATE_SERVER_CACHE(); + else { + const tabTarget = (e.target as HTMLElement)?.parentElement?.className.includes('lm_tab') ? (e.target as HTMLElement).parentElement : (e.target as HTMLElement); + const map = Array.from(this.tabMap).find(tab => tab.element[0] === tabTarget); + if (map?.DashDoc && DocumentManager.Instance.getFirstDocumentView(map.DashDoc)) { + SelectionManager.SelectView(DocumentManager.Instance.getFirstDocumentView(map.DashDoc), false); + } + if (!className.includes('lm_close')) DocServer.UPDATE_SERVER_CACHE(); + } } } if (!InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 118b216bf..83edc60df 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -43,12 +43,17 @@ interface TabDocViewProps { } @observer export class TabDocView extends React.Component { + static _firstTab = true; _mainCont: HTMLDivElement | null = null; _tabReaction: IReactionDisposer | undefined; @observable _activated: boolean = false; @observable _panelWidth = 0; @observable _panelHeight = 0; @observable _isActive: boolean = false; + @observable _isAnyChildContentActive = false; + @computed get _isContentActive() { + return SelectionManager.Views().some(view => view.rootDoc === this._document) || this._isAnyChildContentActive; + } @observable _document: Doc | undefined; @observable _view: DocumentView | undefined; @@ -61,9 +66,7 @@ export class TabDocView extends React.Component { return 'transparent'; } @computed get tabColor() { - let tabColor = StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); - if (tabColor === 'transparent') return 'black'; - return tabColor; + return this._isContentActive ? Colors.WHITE : Colors.MEDIUM_GRAY; } @computed get tabTextColor() { return this._document?.type === DocumentType.PRES ? 'black' : StrCast(this._document?._color, StrCast(this._document?.color, DefaultStyleProvider(this._document, undefined, StyleProp.Color))); @@ -191,7 +194,7 @@ export class TabDocView extends React.Component { } }); tab._disposers.selectionDisposer = reaction( - () => SelectionManager.Views().some(v => v.topMost && v.props.Document === doc), + () => SelectionManager.Views().some(view => view.rootDoc === this._document), action(selected => { if (selected) this._activated = true; const toggle = tab.element[0].children[2].children[0] as HTMLInputElement; @@ -322,11 +325,13 @@ export class TabDocView extends React.Component { } componentDidUpdate() { this._view && DocumentManager.Instance.AddView(this._view); + if (TabDocView._firstTab) SelectionManager.SelectView(this._view, false); } componentWillUnmount() { this._tabReaction?.(); this._view && DocumentManager.Instance.RemoveView(this._view); + TabDocView._firstTab = false; this.props.glContainer.layoutManager.off('activeContentItemChanged', this.onActiveContentItemChanged); } @@ -405,11 +410,15 @@ export class TabDocView extends React.Component { }; PanelWidth = () => this._panelWidth; PanelHeight = () => this._panelHeight; - miniMapColor = () => this.tabColor; + miniMapColor = () => Colors.MEDIUM_GRAY; tabView = () => this._view; disableMinimap = () => !this._document || this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._type_collection !== CollectionViewType.Freeform; - hideMinimap = () => this.disableMinimap() || BoolCast(this._document?.layout_hideMinimap); - + whenChildContentActiveChanges = (isActive: boolean) => (this._isAnyChildContentActive = isActive); + tabs = () => Array.from(CollectionDockingView.Instance?.tabMap ?? new Set()); + isContentActive = () => + SelectionManager.Views().some(dv => dv.rootDoc === this._document) || + this._isAnyChildContentActive || + (this.tabs().findIndex(tab => tab.DashDoc === this._document) === 0 && !this.tabs().some(tab => SelectionManager.Views().some(dv => dv.rootDoc === tab.DashDoc))); @computed get docView() { return !this._activated || !this._document ? null : ( <> @@ -427,7 +436,7 @@ export class TabDocView extends React.Component { DataDoc={!Doc.AreProtosEqual(this._document[DocData], this._document) ? this._document[DocData] : undefined} onBrowseClick={MainView.Instance.exploreMode} waitForDoubleClickToClick={MainView.Instance.waitForDoubleClick} - isContentActive={returnTrue} + isContentActive={this.isContentActive} isDocumentActive={returnFalse} PanelWidth={this.PanelWidth} PanelHeight={this.PanelHeight} @@ -441,30 +450,15 @@ export class TabDocView extends React.Component { ScreenToLocalTransform={this.ScreenToLocalTransform} dontCenter={'y'} rootSelected={returnTrue} - whenChildContentsActiveChanged={emptyFunction} + whenChildContentsActiveChanged={this.whenChildContentActiveChanges} focus={this.focusFunc} docViewPath={returnEmptyDoclist} bringToFront={emptyFunction} pinToPres={TabDocView.PinDoc} /> - - {this._document.layout_hideMinimap ? 'Open minimap' : 'Close minimap'}}> -
e.stopPropagation()} - onClick={action(e => { - e.stopPropagation(); - this._document!.layout_hideMinimap = !this._document!.layout_hideMinimap; - })}> - -
-
+ {this.disableMinimap() || this._document._type_collection !== CollectionViewType.Freeform ? null : ( + + )} ); } @@ -495,7 +489,6 @@ export class TabDocView extends React.Component { interface TabMinimapViewProps { document: Doc; - hideMinimap: () => boolean; tabView: () => DocumentView | undefined; addDocTab: (doc: Doc, where: OpenWhere) => boolean; PanelWidth: () => number; @@ -573,43 +566,64 @@ export class TabMinimapView extends React.Component { const miniLeft = 50 + ((NumCast(this.props.document._freeform_panX) - this.renderBounds.cx) / this.renderBounds.dim) * 100 - miniWidth / 2; const miniTop = 50 + ((NumCast(this.props.document._freeform_panY) - this.renderBounds.cy) / this.renderBounds.dim) * 100 - miniHeight / 2; const miniSize = this.returnMiniSize(); - return this.props.hideMinimap() ? null : ( -
- -
-
-
-
+ return ( + <> + {' '} + {this.props.document?.layout_hideMinimap ? null : ( +
+ +
+
+
+
+ )} + {this.props.document.layout_hideMinimap ? 'Open minimap' : 'Close minimap'}
}> +
e.stopPropagation()} + onClick={action(e => { + e.stopPropagation(); + this.props.document!.layout_hideMinimap = !this.props.document!.layout_hideMinimap; + })}> + +
+ + ); } } -- cgit v1.2.3-70-g09d2