From 72dad52c4fea5a2fccabacbb6a49ca1494093954 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 22 Jun 2023 10:14:26 -0400
Subject: cleaned up dragging - abort presItem drags properly, fix naming for
 drag/dropAction, small fix undo of drag removeproperties, dragging in/out of
 headerBar,  fixed isContentActive to avoid SnappingManager.GetIsDragging. 
 fixed resizing videos.

---
 src/client/views/collections/TabDocView.tsx | 1 -
 1 file changed, 1 deletion(-)

(limited to 'src/client/views/collections/TabDocView.tsx')

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 3b99339af..97d4d989b 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -583,7 +583,6 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
                     isContentActive={emptyFunction}
                     isAnyChildContentActive={returnFalse}
                     select={emptyFunction}
-                    dropAction={undefined}
                     isSelected={returnFalse}
                     dontRegisterView={true}
                     fieldKey={Doc.LayoutFieldKey(this.props.document)}
-- 
cgit v1.2.3-70-g09d2


From 8c3527d61dc5c0191da81a54c3efd0a14bdc8886 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 29 Jun 2023 22:31:53 -0400
Subject: fixed minimap panning.  fixed initial zooming on images.

---
 src/client/views/collections/TabDocView.tsx                             | 2 +-
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/client/views/collections/TabDocView.tsx')

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 97d4d989b..0dcf17b48 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -569,7 +569,7 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
         if (!this.renderBounds) return null;
         const miniWidth = (this.props.PanelWidth() / NumCast(this.props.document._freeform_scale, 1) / this.renderBounds.dim) * 100;
         const miniHeight = (this.props.PanelHeight() / NumCast(this.props.document._freeform_scale, 1) / this.renderBounds.dim) * 100;
-        const miniLeft = 50 + ((NumCast(this.props.document._freeform_) - this.renderBounds.cx) / this.renderBounds.dim) * 100 - miniWidth / 2;
+        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 : (
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e6f8f3071..ef396c6b3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1053,7 +1053,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (this.layoutDoc._Transform || this.props.Document.treeViewOutlineMode === TreeViewType.outline) return;
         e.stopPropagation();
         const docHeight = NumCast(this.rootDoc[Doc.LayoutFieldKey(this.rootDoc) + '_nativeHeight'], this.nativeHeight);
-        const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey], 1) === 1 && docHeight > this.props.PanelHeight() / this.nativeDimScaling;
+        const scrollable = NumCast(this.layoutDoc[this.scaleFieldKey], 1) === 1 && docHeight > this.props.PanelHeight() / this.nativeDimScaling + 1e-4;
         switch (!e.ctrlKey ? Doc.UserDoc().freeformScrollMode : freeformScrollMode.Pan) {
             case freeformScrollMode.Pan:
                 // if ctrl is selected then zoom
-- 
cgit v1.2.3-70-g09d2


From 02926d42bd7dfefbf87709abb45f1b359e4bfcdf Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 2 Jul 2023 12:36:37 -0400
Subject: made multicolumn/row views fit contents to panel and center.  changed
 collection drop to propagate when embed is not enabled.  fixed image box drop
 .  made goldenlayout tabs selectable. turned off leaving pushpins on drag
 out.  fixed long press to disable on drag.

---
 src/client/views/DocComponent.tsx                       |  2 +-
 src/client/views/collections/CollectionSubView.tsx      | 11 ++++++-----
 src/client/views/collections/TabDocView.tsx             |  1 +
 .../CollectionMulticolumnView.scss                      |  9 ++++++---
 .../collectionMulticolumn/CollectionMulticolumnView.tsx | 17 +++++++++++------
 .../collectionMulticolumn/CollectionMultirowView.scss   | 10 +++++++---
 .../collectionMulticolumn/CollectionMultirowView.tsx    | 17 +++++++++++------
 src/client/views/nodes/DocumentView.tsx                 |  1 +
 src/client/views/nodes/ImageBox.tsx                     |  6 +++---
 9 files changed, 47 insertions(+), 27 deletions(-)

(limited to 'src/client/views/collections/TabDocView.tsx')

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 3de40a640..70d208a0b 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -173,7 +173,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
             }
             const first = doc instanceof Doc ? doc : doc[0];
             if (!first?._dragOnlyWithinContainer && addDocument !== returnFalse) {
-                return this.removeDocument(doc, annotationKey, true) && addDocument(doc, annotationKey);
+                return this.removeDocument(doc, annotationKey, false) && addDocument(doc, annotationKey);
             }
             return false;
         };
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 39fb2db1e..78789247f 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -205,7 +205,7 @@ export function CollectionSubView<X>(moreProps?: X) {
         protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
             const docDragData = de.complete.docDragData;
             if (docDragData) {
-                let added = false;
+                let added = undefined;
                 const dropAction = docDragData.dropAction || docDragData.userDropAction;
                 const targetDocments = DocListCast(this.dataDoc[this.props.fieldKey]);
                 const someMoved = !dropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag));
@@ -215,7 +215,8 @@ export function CollectionSubView<X>(moreProps?: X) {
                     const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
                     if (movedDocs.length) {
                         const canAdd = de.embedKey || dropAction || Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.rootDoc);
-                        added = docDragData.moveDocument(movedDocs, this.rootDoc, canAdd ? this.addDocument : returnFalse);
+                        const moved = docDragData.moveDocument(movedDocs, this.rootDoc, canAdd ? this.addDocument : returnFalse);
+                        added = canAdd || moved ? moved : undefined;
                     } else {
                         ScriptCast(this.rootDoc.dropConverter)?.script.run({ dragData: docDragData });
                         added = addedDocs.length ? this.addDocument(addedDocs) : true;
@@ -225,9 +226,9 @@ export function CollectionSubView<X>(moreProps?: X) {
                     added = this.addDocument(docDragData.droppedDocuments);
                     !added && alert('You cannot perform this move');
                 }
-                !added && e.preventDefault();
-                e.stopPropagation();
-                return added;
+                added === false && !this.props.isAnnotationOverlay && e.preventDefault();
+                added === true && e.stopPropagation();
+                return added ? true : false;
             } else if (de.complete.annoDragData) {
                 e.stopPropagation();
                 const dropCreator = de.complete.annoDragData.dropDocCreator;
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 0dcf17b48..118b216bf 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -335,6 +335,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     private 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) setTimeout(() => SelectionManager.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.
         }
     }
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
index 821c8d804..f87a06033 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
@@ -8,6 +8,11 @@
         display: flex;
         flex-direction: column;
         width: 100%;
+        align-items: center;
+
+        .contentFittingDocumentView {
+            width: unset;
+        }
 
         .label-wrapper {
             display: flex;
@@ -15,7 +20,6 @@
             justify-content: center;
             height: 20px;
         }
-
     }
 
     .multiColumnResizer {
@@ -30,5 +34,4 @@
             transition: 0.5s background-color ease;
         }
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 6dcd2d422..10532b9d9 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -238,7 +238,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
             ? true
             : undefined;
     };
-    getDisplayDoc = (layout: Doc, dxf: () => Transform, width: () => number, height: () => number) => {
+    getDisplayDoc = (layout: Doc, dxf: () => Transform, width: () => number, height: () => number, shouldNotScale: () => boolean) => {
         return (
             <DocumentView
                 Document={layout}
@@ -250,6 +250,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
                 renderDepth={this.props.renderDepth + 1}
                 PanelWidth={width}
                 PanelHeight={height}
+                shouldNotScale={shouldNotScale}
                 rootSelected={this.rootSelected}
                 dragAction={(this.props.Document.childDragAction ?? this.props.childDragAction) as dropActionType}
                 onClick={this.onChildClickHandler}
@@ -287,15 +288,19 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         const collector: JSX.Element[] = [];
         for (let i = 0; i < childLayoutPairs.length; i++) {
             const { layout } = childLayoutPairs[i];
+            const aspect = Doc.NativeAspect(layout, undefined, true);
+            const width = () => this.lookupPixels(layout);
+            const height = () => PanelHeight() - 2 * NumCast(Document._yMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0);
+            const docwidth = () => (layout._layout_forceReflow ? width() : Math.min(height() * aspect, width()));
+            const docheight = () => Math.min(docwidth() / aspect, height());
             const dxf = () =>
                 this.lookupIndividualTransform(layout)
-                    .translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin))
+                    .translate(-NumCast(Document._xMargin) - (width() - docwidth()) / 2, -NumCast(Document._yMargin))
                     .scale(this.props.NativeDimScaling?.() || 1);
-            const width = () => this.lookupPixels(layout);
-            const height = () => PanelHeight() - 2 * NumCast(Document._yMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0);
+            const shouldNotScale = () => this.props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox);
             collector.push(
-                <div className={'document-wrapper'} key={'wrapper' + i} style={{ width: width() }}>
-                    {this.getDisplayDoc(layout, dxf, width, height)}
+                <div className="document-wrapper" key={'wrapper' + i} style={{ width: width() }}>
+                    {this.getDisplayDoc(layout, dxf, docwidth, docheight, shouldNotScale)}
                     <WidthLabel layout={layout} collectionDoc={Document} />
                 </div>,
                 <ResizeBar
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
index 79fb195e8..ec7200a03 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
@@ -9,6 +9,12 @@
         display: flex;
         flex-direction: row;
         height: 100%;
+        align-items: center;
+        margin: auto;
+
+        .contentFittingDocumentView {
+            height: unset;
+        }
 
         .label-wrapper {
             display: flex;
@@ -16,7 +22,6 @@
             justify-content: center;
             height: 20px;
         }
-
     }
 
     .multiRowResizer {
@@ -31,5 +36,4 @@
             transition: 0.5s background-color ease;
         }
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 4df5dad5a..04cfc5456 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -238,7 +238,7 @@ export class CollectionMultirowView extends CollectionSubView() {
             ? true
             : undefined;
     };
-    getDisplayDoc = (layout: Doc, dxf: () => Transform, width: () => number, height: () => number) => {
+    getDisplayDoc = (layout: Doc, dxf: () => Transform, width: () => number, height: () => number, shouldNotScale: () => boolean) => {
         return (
             <DocumentView
                 Document={layout}
@@ -250,6 +250,7 @@ export class CollectionMultirowView extends CollectionSubView() {
                 renderDepth={this.props.renderDepth + 1}
                 PanelWidth={width}
                 PanelHeight={height}
+                shouldNotScale={shouldNotScale}
                 rootSelected={this.rootSelected}
                 dropAction={StrCast(this.rootDoc.childDragAction) as dropActionType}
                 onClick={this.onChildClickHandler}
@@ -287,15 +288,19 @@ export class CollectionMultirowView extends CollectionSubView() {
         const collector: JSX.Element[] = [];
         for (let i = 0; i < childLayoutPairs.length; i++) {
             const { layout } = childLayoutPairs[i];
+            const aspect = Doc.NativeAspect(layout, undefined, true);
+            const height = () => this.lookupPixels(layout);
+            const width = () => PanelWidth() - 2 * NumCast(Document._xMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0);
+            const docheight = () => Math.min(width() / aspect, height());
+            const docwidth = () => (layout._layout_forceReflow ? width() : Math.min(width(), docheight() * aspect));
             const dxf = () =>
                 this.lookupIndividualTransform(layout)
-                    .translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin))
+                    .translate(-NumCast(Document._xMargin) - (width() - docwidth()) / 2, -NumCast(Document._yMargin) - (height() - docheight()) / 2)
                     .scale(this.props.NativeDimScaling?.() || 1);
-            const height = () => this.lookupPixels(layout);
-            const width = () => PanelWidth() - 2 * NumCast(Document._xMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0);
+            const shouldNotScale = () => this.props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox);
             collector.push(
-                <div className={'document-wrapper'} style={{ height: height() }} key={'wrapper' + i}>
-                    {this.getDisplayDoc(layout, dxf, width, height)}
+                <div className="document-wrapper" style={{ height: height() }} key={'wrapper' + i}>
+                    {this.getDisplayDoc(layout, dxf, docwidth, docheight, shouldNotScale)}
                     <HeightLabel layout={layout} collectionDoc={Document} />
                 </div>,
                 <ResizeBar
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 733ee1ed1..c10c0005d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -561,6 +561,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
 
         if (!Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, Date.now())) {
             this.cleanupPointerEvents();
+            this._longPressSelector && clearTimeout(this._longPressSelector);
             this.startDragging(this._downX, this._downY, ((e.ctrlKey || e.altKey) && 'embed') || ((this.Document.dragAction || this.props.dragAction || undefined) as dropActionType));
         }
     };
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index f67930a3f..0bbdff719 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -135,7 +135,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
         if (de.complete.docDragData) {
-            let added = true;
+            let added: boolean | undefined = undefined;
             const targetIsBullseye = (ele: HTMLElement): boolean => {
                 if (!ele) return false;
                 if (ele === this._overlayIconRef.current) return true;
@@ -156,8 +156,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                     Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey);
                 }
             }
-            !added && e.preventDefault();
-            e.stopPropagation();
+            added === false && e.preventDefault();
+            added !== undefined && e.stopPropagation();
             return added;
         }
         return false;
-- 
cgit v1.2.3-70-g09d2


From 446ab35c19ae18a609acf26babbc4e6dc1c46876 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
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 +++++++++++----------
 src/client/views/nodes/DocumentView.tsx            |   4 +
 .../views/nodes/formattedText/FormattedTextBox.tsx |  11 +-
 5 files changed, 104 insertions(+), 71 deletions(-)

(limited to 'src/client/views/collections/TabDocView.tsx')

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<TabDocViewProps> {
+    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<TabDocViewProps> {
         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<TabDocViewProps> {
                 }
             });
             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<TabDocViewProps> {
     }
     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<TabDocViewProps> {
     };
     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<TabDocViewProps> {
                     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<TabDocViewProps> {
                     ScreenToLocalTransform={this.ScreenToLocalTransform}
                     dontCenter={'y'}
                     rootSelected={returnTrue}
-                    whenChildContentsActiveChanged={emptyFunction}
+                    whenChildContentsActiveChanged={this.whenChildContentActiveChanges}
                     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.layout_hideMinimap ? 'Open minimap' : 'Close minimap'}</div>}>
-                    <div
-                        className="miniMap-hidden"
-                        style={{
-                            display: this.disableMinimap() || this._document._type_collection !== 'freeform' ? 'none' : undefined,
-                            color: this._document.layout_hideMinimap ? Colors.BLACK : Colors.WHITE,
-                            backgroundColor: this._document.layout_hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
-                            boxShadow: this._document.layout_hideMinimap ? Shadows.STANDARD_SHADOW : undefined,
-                        }}
-                        onPointerDown={e => e.stopPropagation()}
-                        onClick={action(e => {
-                            e.stopPropagation();
-                            this._document!.layout_hideMinimap = !this._document!.layout_hideMinimap;
-                        })}>
-                        <FontAwesomeIcon icon={'globe-asia'} size="lg" />
-                    </div>
-                </Tooltip>
+                {this.disableMinimap() || this._document._type_collection !== CollectionViewType.Freeform ? null : (
+                    <TabMinimapView key="minimap" addDocTab={this.addDocTab} PanelHeight={this.PanelHeight} PanelWidth={this.PanelWidth} background={this.miniMapColor} document={this._document} tabView={this.tabView} />
+                )}
             </>
         );
     }
@@ -495,7 +489,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
 
 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<TabMinimapViewProps> {
         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 : (
-            <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
-                <CollectionFreeFormView
-                    Document={this.props.document}
-                    docViewPath={returnEmptyDoclist}
-                    childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
-                    noOverlay={true} // don't render overlay Docs since they won't scale
-                    setHeight={returnFalse}
-                    isContentActive={emptyFunction}
-                    isAnyChildContentActive={returnFalse}
-                    select={emptyFunction}
-                    isSelected={returnFalse}
-                    dontRegisterView={true}
-                    fieldKey={Doc.LayoutFieldKey(this.props.document)}
-                    bringToFront={emptyFunction}
-                    rootSelected={returnTrue}
-                    addDocument={returnFalse}
-                    moveDocument={returnFalse}
-                    removeDocument={returnFalse}
-                    PanelWidth={this.returnMiniSize}
-                    PanelHeight={this.returnMiniSize}
-                    ScreenToLocalTransform={Transform.Identity}
-                    renderDepth={0}
-                    whenChildContentsActiveChanged={emptyFunction}
-                    focus={emptyFunction}
-                    styleProvider={TabMinimapView.miniStyleProvider}
-                    addDocTab={this.props.addDocTab}
-                    pinToPres={TabDocView.PinDoc}
-                    childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
-                    childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
-                    searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
-                    fitContentsToBox={returnTrue}
-                />
-                <div className="miniOverlay" onPointerDown={this.miniDown}>
-                    <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
-                </div>
-            </div>
+        return (
+            <>
+                {' '}
+                {this.props.document?.layout_hideMinimap ? null : (
+                    <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
+                        <CollectionFreeFormView
+                            Document={this.props.document}
+                            docViewPath={returnEmptyDoclist}
+                            childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
+                            noOverlay={true} // don't render overlay Docs since they won't scale
+                            setHeight={returnFalse}
+                            isContentActive={emptyFunction}
+                            isAnyChildContentActive={returnFalse}
+                            select={emptyFunction}
+                            isSelected={returnFalse}
+                            dontRegisterView={true}
+                            fieldKey={Doc.LayoutFieldKey(this.props.document)}
+                            bringToFront={emptyFunction}
+                            rootSelected={returnTrue}
+                            addDocument={returnFalse}
+                            moveDocument={returnFalse}
+                            removeDocument={returnFalse}
+                            PanelWidth={this.returnMiniSize}
+                            PanelHeight={this.returnMiniSize}
+                            ScreenToLocalTransform={Transform.Identity}
+                            renderDepth={0}
+                            whenChildContentsActiveChanged={emptyFunction}
+                            focus={emptyFunction}
+                            styleProvider={TabMinimapView.miniStyleProvider}
+                            addDocTab={this.props.addDocTab}
+                            pinToPres={TabDocView.PinDoc}
+                            childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
+                            childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+                            searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
+                            fitContentsToBox={returnTrue}
+                        />
+                        <div className="miniOverlay" onPointerDown={this.miniDown}>
+                            <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
+                        </div>
+                    </div>
+                )}
+                <Tooltip key="ttip" title={<div className="dash-tooltip">{this.props.document.layout_hideMinimap ? 'Open minimap' : 'Close minimap'}</div>}>
+                    <div
+                        className="miniMap-hidden"
+                        style={{
+                            color: this.props.document.layout_hideMinimap ? Colors.BLACK : Colors.WHITE,
+                            backgroundColor: this.props.document.layout_hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
+                            boxShadow: this.props.document.layout_hideMinimap ? Shadows.STANDARD_SHADOW : undefined,
+                        }}
+                        onPointerDown={e => e.stopPropagation()}
+                        onClick={action(e => {
+                            e.stopPropagation();
+                            this.props.document!.layout_hideMinimap = !this.props.document!.layout_hideMinimap;
+                        })}>
+                        <FontAwesomeIcon icon="globe-asia" size="lg" />
+                    </div>
+                </Tooltip>
+            </>
         );
     }
 }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c10c0005d..19f9f15a4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -729,6 +729,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layout_fieldKey)], Doc, null);
             const appearance = cm.findByDescription('UI Controls...');
             const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : [];
+
+            if (this.props.renderDepth === 0) {
+                appearanceItems.push({ description: 'Open in Lightbox', event: () => LightboxView.SetLightboxDoc(this.rootDoc), icon: 'hand-point-right' });
+            }
             !Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template   ', event: () => this.props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' });
             !appearance && appearanceItems.length && cm.addItem({ description: 'UI Controls...', subitems: appearanceItems, icon: 'compass' });
 
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 62b3443d4..f1305b64b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -879,11 +879,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         const optionItems = options && 'subitems' in options ? options.subitems : [];
         optionItems.push({ description: `Generate Dall-E Image`, event: () => this.generateImage(), icon: 'star' });
         optionItems.push({ description: `Ask GPT-3`, event: () => this.askGPT(), icon: 'lightbulb' });
-        optionItems.push({
-            description: !this.Document._createDocOnCR ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns',
-            event: () => (this.layoutDoc._createDocOnCR = !this.layoutDoc._createDocOnCR),
-            icon: !this.Document._createDocOnCR ? 'grip-lines' : 'bars',
-        });
+        this.props.renderDepth &&
+            optionItems.push({
+                description: !this.Document._createDocOnCR ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns',
+                event: () => (this.layoutDoc._createDocOnCR = !this.layoutDoc._createDocOnCR),
+                icon: !this.Document._createDocOnCR ? 'grip-lines' : 'bars',
+            });
         !Doc.noviceMode &&
             optionItems.push({
                 description: `${this.Document._layout_autoHeight ? 'Lock' : 'Auto'} Height`,
-- 
cgit v1.2.3-70-g09d2


From ed5cf4bdac69daa373474f439dc474b9f53e1b4a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 3 Jul 2023 10:41:32 -0400
Subject: fixed making one tab always active.

---
 src/client/views/collections/TabDocView.tsx | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

(limited to 'src/client/views/collections/TabDocView.tsx')

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 83edc60df..f6220a6b8 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -52,8 +52,14 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     @observable _isActive: boolean = false;
     @observable _isAnyChildContentActive = false;
     @computed get _isContentActive() {
-        return SelectionManager.Views().some(view => view.rootDoc === this._document) || this._isAnyChildContentActive;
+        const tabs = Array.from(CollectionDockingView.Instance?.tabMap ?? new Set());
+        return (
+            SelectionManager.Views().some(view => view.rootDoc === this._document) ||
+            this._isAnyChildContentActive ||
+            (tabs.findIndex(tab => tab.DashDoc === this._document) === 0 && !tabs.some(tab => SelectionManager.Views().some(dv => dv.rootDoc === tab.DashDoc)))
+        );
     }
+
     @observable _document: Doc | undefined;
     @observable _view: DocumentView | undefined;
 
@@ -414,11 +420,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     tabView = () => this._view;
     disableMinimap = () => !this._document || this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._type_collection !== CollectionViewType.Freeform;
     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)));
+    isContentActive = () => this._isContentActive;
     @computed get docView() {
         return !this._activated || !this._document ? null : (
             <>
-- 
cgit v1.2.3-70-g09d2


From 2ddb1c812936286c4d9ae03065be8d4d9f14bc88 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 3 Jul 2023 10:59:24 -0400
Subject: better fix for activating tabs on hover

---
 src/client/views/collections/TabDocView.tsx | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

(limited to 'src/client/views/collections/TabDocView.tsx')

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index f6220a6b8..ea017db14 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
 import { clamp } from 'lodash';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableSet, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as ReactDOM from 'react-dom/client';
 import { Doc, Opt } from '../../../fields/Doc';
@@ -43,23 +43,21 @@ interface TabDocViewProps {
 }
 @observer
 export class TabDocView extends React.Component<TabDocViewProps> {
-    static _firstTab = true;
+    static _allTabs = new ObservableSet<TabDocView>();
     _mainCont: HTMLDivElement | null = null;
     _tabReaction: IReactionDisposer | undefined;
     @observable _activated: boolean = false;
     @observable _panelWidth = 0;
     @observable _panelHeight = 0;
+    @observable _hovering = false;
     @observable _isActive: boolean = false;
     @observable _isAnyChildContentActive = false;
+    @computed get _isUserActivated() {
+        return SelectionManager.Views().some(view => view.rootDoc === this._document) || this._isAnyChildContentActive;
+    }
     @computed get _isContentActive() {
-        const tabs = Array.from(CollectionDockingView.Instance?.tabMap ?? new Set());
-        return (
-            SelectionManager.Views().some(view => view.rootDoc === this._document) ||
-            this._isAnyChildContentActive ||
-            (tabs.findIndex(tab => tab.DashDoc === this._document) === 0 && !tabs.some(tab => SelectionManager.Views().some(dv => dv.rootDoc === tab.DashDoc)))
-        );
+        return this._isUserActivated || this._hovering;
     }
-
     @observable _document: Doc | undefined;
     @observable _view: DocumentView | undefined;
 
@@ -72,7 +70,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         return 'transparent';
     }
     @computed get tabColor() {
-        return this._isContentActive ? Colors.WHITE : Colors.MEDIUM_GRAY;
+        return this._isUserActivated ? Colors.WHITE : this._hovering ? Colors.LIGHT_GRAY : 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)));
@@ -314,6 +312,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         setTimeout(batch.end, 500); // need to wait until dockingview (goldenlayout) updates all its structurs
     }
 
+    @action
     componentDidMount() {
         new _global.ResizeObserver(
             action((entries: any) => {
@@ -328,16 +327,17 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         // this._tabReaction = reaction(() => ({ selected: this.active(), title: this.tab?.titleElement[0] }),
         //     ({ selected, title }) => title && (title.style.backgroundColor = selected ? "white" : ""),
         //     { fireImmediately: true });
+        TabDocView._allTabs.add(this);
     }
     componentDidUpdate() {
         this._view && DocumentManager.Instance.AddView(this._view);
-        if (TabDocView._firstTab) SelectionManager.SelectView(this._view, false);
     }
 
+    @action
     componentWillUnmount() {
         this._tabReaction?.();
         this._view && DocumentManager.Instance.RemoveView(this._view);
-        TabDocView._firstTab = false;
+        TabDocView._allTabs.delete(this);
 
         this.props.glContainer.layoutManager.off('activeContentItemChanged', this.onActiveContentItemChanged);
     }
@@ -472,6 +472,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 style={{
                     fontFamily: Doc.UserDoc().renderStyle === 'comic' ? 'Comic Sans MS' : undefined,
                 }}
+                onPointerEnter={action(() => (this._hovering = true))}
+                onPointerLeave={action(() => (this._hovering = false))}
                 ref={ref => {
                     if ((this._mainCont = ref)) {
                         if (this._lastTab) {
-- 
cgit v1.2.3-70-g09d2


From bcce8d644399a913e496619f1ae8c76f813c45e5 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 3 Jul 2023 11:36:12 -0400
Subject: fixed dragging onto non active tab from outside dash

---
 src/client/views/collections/TabDocView.tsx | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src/client/views/collections/TabDocView.tsx')

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index ea017db14..4d780f46b 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -474,6 +474,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 }}
                 onPointerEnter={action(() => (this._hovering = true))}
                 onPointerLeave={action(() => (this._hovering = false))}
+                onDragOver={action(() => (this._hovering = true))}
+                onDragLeave={action(() => (this._hovering = false))}
                 ref={ref => {
                     if ((this._mainCont = ref)) {
                         if (this._lastTab) {
-- 
cgit v1.2.3-70-g09d2

