From d99f64efe9e69f2159f1ad8f851b24533a996ba5 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 26 Feb 2024 12:57:48 -0500
Subject: fixed some string types to be enumerations for dropAction.  fixed bug
 in golden layout dragging where a stack's tabs could disappear.

---
 .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 50a9feff8..50b3dbd70 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -462,7 +462,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.Document._freeform_useClusters ? NumCast(cd.layout_cluster) : NumCast(cd.group, -1)) === cluster);
                 const clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.DocumentView?.())!);
                 const { left, top } = clusterDocs[0].getBounds || { left: 0, top: 0 };
-                const de = new DragManager.DocumentDragData(eles, e.ctrlKey || e.altKey ? 'embed' : undefined);
+                const de = new DragManager.DocumentDragData(eles, e.ctrlKey || e.altKey ? dropActionType.embed : undefined);
                 de.moveDocument = this._props.moveDocument;
                 de.offset = this.screenToFreeformContentsXf.transformDirection(ptsParent.clientX - left, ptsParent.clientY - top);
                 DragManager.StartDocumentDrag(
-- 
cgit v1.2.3-70-g09d2


From e973de1476194fe68a2f218e458e4619fb71c75e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 29 Feb 2024 09:34:56 -0500
Subject: fixed minimap to show at least as much as the freeformview is showing
 (was a problem for example when there was just a single document)

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

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

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 02aa76d82..b52f2e7b6 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -564,6 +564,12 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
         const dim = Math.max(xbounds, ybounds);
         return { l: bounds.x + xbounds / 2 - dim / 2, t: bounds.y + ybounds / 2 - dim / 2, cx: bounds.x + xbounds / 2, cy: bounds.y + ybounds / 2, dim };
     }
+    @computed get xPadding() {
+        return !this.renderBounds ? 0 : Math.max(0, this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) - 2 * (this.renderBounds.cx - this.renderBounds.l));
+    }
+    @computed get yPadding() {
+        return !this.renderBounds ? 0 : Math.max(0, this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) - 2 * (this.renderBounds.cy - this.renderBounds.l));
+    }
     childLayoutTemplate = () => Cast(this._props.document.childLayoutTemplate, Doc, null);
     returnMiniSize = () => NumCast(this._props.document._miniMapSize, 150);
     miniDown = (e: React.PointerEvent) => {
@@ -620,6 +626,8 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
                     childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
                     searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
                     fitContentsToBox={returnTrue}
+                    xPadding={this.xPadding}
+                    yPadding={this.yPadding}
                 />
                 <div className="miniOverlay" onPointerDown={this.miniDown}>
                     <TabMiniThumb miniLeft={miniLeft} miniTop={miniTop} miniWidth={miniWidth} miniHeight={miniHeight} />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 50b3dbd70..e48656f5e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -159,8 +159,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             ? { x: cb[0], y: cb[1], r: cb[2], b: cb[3] }
             : aggregateBounds(
                   this._layoutElements.filter(e => e.bounds?.width && !e.bounds.z).map(e => e.bounds!),
-                  NumCast(this.layoutDoc._xPadding, 10),
-                  NumCast(this.layoutDoc._yPadding, 10)
+                  NumCast(this.layoutDoc._xPadding, this._props.xPadding ?? 10),
+                  NumCast(this.layoutDoc._yPadding, this._props.yPadding ?? 10)
               );
     }
     @computed get nativeWidth() {
-- 
cgit v1.2.3-70-g09d2


From 49cfa95fdb3653a1224d4e5e3380e111c8e2014f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 4 Mar 2024 12:55:05 -0500
Subject: changes to restore template menu and fix freeform templates to always
 show contents.   Fix for alt-dropping an image to replace another image.

---
 src/client/views/DocumentButtonBar.tsx             | 48 +++++++++-------------
 src/client/views/DocumentDecorations.tsx           |  4 +-
 src/client/views/InkingStroke.tsx                  |  2 +-
 src/client/views/TemplateMenu.tsx                  |  2 +-
 src/client/views/collections/TabDocView.tsx        |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  9 ++--
 src/client/views/nodes/ImageBox.tsx                |  1 +
 7 files changed, 30 insertions(+), 38 deletions(-)

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

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 8a4b42ae0..d65e0b406 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -4,12 +4,12 @@ import { Tooltip } from '@mui/material';
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
+import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
 import { Doc } from '../../fields/Doc';
 import { Cast, DocCast } from '../../fields/Types';
 import { DocUtils } from '../documents/Documents';
 import { CalendarManager } from '../util/CalendarManager';
-import { DragManager } from '../util/DragManager';
+import { DragManager, dropActionType } from '../util/DragManager';
 import { IsFollowLinkScript } from '../util/LinkFollower';
 import { SelectionManager } from '../util/SelectionManager';
 import { SharingManager } from '../util/SharingManager';
@@ -24,6 +24,9 @@ import { DocumentView, DocumentViewInternal, OpenWhere } from './nodes/DocumentV
 import { DashFieldView } from './nodes/formattedText/DashFieldView';
 import { PinProps } from './nodes/trails';
 import { faCalendarDays } from '@fortawesome/free-solid-svg-icons';
+import { Popup } from 'browndash-components';
+import { TemplateMenu } from './TemplateMenu';
+import { FaEdit } from 'react-icons/fa';
 
 @observer
 export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (DocumentView | undefined)[]; stack?: any }> {
@@ -306,7 +309,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
             const dragDocView = this.view0!;
             const dragData = new DragManager.DocumentDragData([dragDocView.Document]);
             const [left, top] = dragDocView.screenToContentsTransform().inverse().transformPoint(0, 0);
-            dragData.defaultDropAction = 'embed';
+            dragData.defaultDropAction = dropActionType.embed;
             dragData.canEmbed = true;
             DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { hideSource: false });
             return true;
@@ -316,35 +319,24 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
 
     _ref = React.createRef<HTMLDivElement>();
     @observable _tooltipOpen: boolean = false;
+    @computed get templateMenu() {
+        return (
+            <div ref={this._ref}>
+                <TemplateMenu
+                    docViews={this._props
+                        .views()
+                        .filter(v => v)
+                        .map(v => v as DocumentView)}
+                />
+            </div>
+        );
+    }
     @computed
     get templateButton() {
-        const view0 = this.view0;
-        const views = this._props.views();
-        return !view0 ? null : (
+        return !this.view0 ? null : (
             <Tooltip title={<div className="dash-tooltip">Tap to Customize Layout. Drag an embedding</div>} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom">
                 <div className="documentButtonBar-linkFlyout" ref={this._dragRef} onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}>
-                    {
-                        /* <Flyout
-                        anchorPoint={anchorPoints.LEFT_TOP}
-                        onOpen={action(() => (this._embedDown = true))}
-                        onClose={action(() => (this._embedDown = false))}
-                        content={
-                            !this._embedDown ? null : (
-                                <div ref={this._ref}>
-                                    {' '}
-                                    <TemplateMenu docViews={views.filter(v => v).map(v => v as DocumentView)} />
-                                </div>
-                            )
-                        }>
-                        <div className={'documentButtonBar-linkButton-empty'} ref={this._dragRef} onPointerDown={this.onTemplateButton}>
-                            <FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" />
-                        </div>
-                    </Flyout> */
-
-                        <div className={'documentButtonBar-linkButton-empty'} ref={this._dragRef} onPointerDown={this.onTemplateButton}>
-                            <FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" />
-                        </div>
-                    }
+                    <Popup icon={<FaEdit />} popup={this.templateMenu} popupContainsPt={returnTrue} />
                 </div>
             </Tooltip>
         );
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index e9c4d9cc5..9d53c58c0 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -77,7 +77,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                 const {x,y} = Utils.rotPt(e.clientX - center.x, 
                                           e.clientY - center.y, 
                                           NumCast(SelectionManager.Views.lastElement()?.screenToViewTransform().Rotate));
-                (this._showNothing = !(this.Bounds.x !== Number.MAX_VALUE && //
+                (this._showNothing = !DocumentButtonBar.Instance?._tooltipOpen && !(this.Bounds.x !== Number.MAX_VALUE && //
                     (this.Bounds.x > center.x+x || this.Bounds.r < center.x+x || 
                      this.Bounds.y > center.y+y || this.Bounds.b < center.y+y )));
             })); // prettier-ignore
@@ -514,7 +514,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
     //
     // determines if anything being dragged directly or via a group has a fixed aspect ratio (in which case we resize uniformly)
     //
-    hasFixedAspect = (doc: Doc): boolean => (doc.isGroup ? DocListCast(doc.data).some(this.hasFixedAspect) : !BoolCast(doc.layout_nativeDimEditable));
+    hasFixedAspect = (doc: Doc): boolean => (doc.isGroup ? DocListCast(doc.data).some(this.hasFixedAspect) : !BoolCast(doc._layout_nativeDimEditable));
 
     //
     // resize a single DocumentView about the specified reference point, possibly setting/updating the native dimensions of the Doc
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 92644d3c5..122e5c4c3 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -438,7 +438,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() impleme
                 <svg
                     className="inkStroke"
                     style={{
-                        transform: isInkMask ? `rotate(-${NumCast(this._props.CollectionFreeFormDocumentView?.()._props.w_Rotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
+                        transform: isInkMask ? `rotate(-${NumCast(this._props.CollectionFreeFormDocumentView?.()._props.rotation ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
                         // mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? 'multiply' : 'unset',
                         cursor: this._props.isSelected() ? 'default' : undefined,
                     }}
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 5fc33207e..f7729dbc7 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -81,7 +81,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
     componentDidMount() {
         !this._addedKeys && (this._addedKeys = new ObservableSet());
         [...Array.from(Object.keys(this.props.docViews[0].Document[DocData])), ...Array.from(Object.keys(this.props.docViews[0].Document))]
-            .filter(key => key.startsWith('layout_'))
+            .filter(key => key.startsWith('layout_') && key !== 'layout_fieldKey')
             .map(key => runInAction(() => this._addedKeys.add(key.replace('layout_', ''))));
     }
 
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index b52f2e7b6..699ec3b95 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -638,7 +638,7 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
     render() {
         return this._props.document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._props.document)) || this._props.document?._type_collection !== CollectionViewType.Freeform ? null : (
             <div className="miniMap-hidden">
-                <Popup icon={<FontAwesomeIcon icon="globe-asia" size="lg" />} color={SettingsManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement={'top-end'} popup={this.popup} />
+                <Popup icon={<FontAwesomeIcon icon="globe-asia" size="lg" />} color={SettingsManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement="top-end" popup={this.popup} />
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e48656f5e..877569ab3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -17,7 +17,7 @@ import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../
 import { ImageField } from '../../../../fields/URLField';
 import { TraceMobx } from '../../../../fields/util';
 import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
-import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
+import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, numberValue, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils';
 import { CognitiveServices } from '../../../cognitive_services/CognitiveServices';
 import { Docs, DocUtils } from '../../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
@@ -760,7 +760,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, GestureOverlay.getBounds(points), text));
     };
 
-    @action
     onPointerMove = (e: PointerEvent) => {
         if (this.tryDragCluster(e, this._hitCluster)) {
             e.stopPropagation(); // we're moving a cluster, so stop propagation and return true to end panning and let the document drag take over
@@ -1344,7 +1343,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
     renderCutoffProvider = computedFn(
         function renderCutoffProvider(this: any, doc: Doc) {
-            return !this._renderCutoffData.get(doc[Id] + '');
+            return this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + '');
         }.bind(this)
     );
 
@@ -1467,7 +1466,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 if (!code.includes('dashDiv')) {
                     const script = CompileScript(code, { params: { docView: 'any' }, typecheck: false, editable: true });
                     if (script.compiled) script.run({ this: this.DocumentView?.() });
-                } else code && !first && eval(code);
+                } else code && !first && eval?.(code);
             },
             { fireImmediately: true }
         );
@@ -1712,7 +1711,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     incrementalRender = action(() => {
         if (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.())) {
             const layout_unrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id]));
-            const loadIncrement = 5;
+            const loadIncrement = this.Document.isTemplateDoc ? Number.MAX_VALUE : 5;
             for (var i = 0; i < Math.min(layout_unrendered.length, loadIncrement); i++) {
                 this._renderCutoffData.set(layout_unrendered[i][Id] + '', true);
             }
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 923aead64..251235b93 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -141,6 +141,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
                 const targetField = Doc.LayoutFieldKey(layoutDoc);
                 const targetDoc = layoutDoc[DocData];
                 if (targetDoc[targetField] instanceof ImageField) {
+                    added = true;
                     this.dataDoc[this.fieldKey] = ObjectField.MakeCopy(targetDoc[targetField] as ImageField);
                     Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(targetDoc), this.fieldKey);
                     Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey);
-- 
cgit v1.2.3-70-g09d2

