From 9ee773a9e25d912bbef2a98e6037bc59565395df Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 16 Jul 2020 16:23:09 -0400
Subject: added minimaps for freeform views shown in docking view

---
 .../views/collections/CollectionDockingView.tsx    | 121 ++++++++++++++++-----
 1 file changed, 95 insertions(+), 26 deletions(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 657296566..c7e72d634 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -11,7 +11,7 @@ import { Id } from '../../../fields/FieldSymbols';
 import { FieldId } from "../../../fields/RefField";
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnOne, returnTrue, Utils, returnZero, returnEmptyFilter, setupMoveUpEvents, returnFalse } from "../../../Utils";
+import { emptyFunction, returnOne, returnTrue, Utils, returnZero, returnEmptyFilter, setupMoveUpEvents, returnFalse, emptyPath, aggregateBounds } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Docs } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
@@ -28,6 +28,8 @@ import { DockingViewButtonSelector } from './ParentDocumentSelector';
 import React = require("react");
 import { CollectionViewType } from './CollectionView';
 import { SnappingManager } from '../../util/SnappingManager';
+import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
+import { listSpec } from '../../../fields/Schema';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -816,35 +818,102 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         }
     }
 
+    @computed get renderContentBounds() {
+        const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0];
+        const xbounds = bounds[2] - bounds[0];
+        const ybounds = bounds[3] - bounds[1];
+        const dim = Math.max(xbounds, ybounds);
+        return { cx: bounds[0] + xbounds / 2, cy: bounds[1] + ybounds / 2, w: dim, h: dim };
+    }
+    @computed get miniLeft() { return 50 + (NumCast(this._document?._panX) - this.renderContentBounds.cx) / this.renderContentBounds.w * 100 - this.miniWidth / 2; }
+    @computed get miniTop() { return 50 + (NumCast(this._document?._panY) - this.renderContentBounds.cy) / this.renderContentBounds.h * 100 - this.miniHeight / 2; }
+    @computed get miniWidth() { return this.panelWidth() / NumCast(this._document?._viewScale, 1) / this.renderContentBounds.w * 100; }
+    @computed get miniHeight() { return this.panelHeight() / NumCast(this._document?._viewScale, 1) / this.renderContentBounds.h * 100; }
+    returnMiniSize = () => NumCast(this._document?._miniMapSize, 150);
+    miniDown = (e: React.PointerEvent) => {
+        setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
+            this._document!._panX = NumCast(this._document!._panX) + delta[0] / this.returnMiniSize() * this.renderContentBounds.w;
+            this._document!._panY = NumCast(this._document!._panY) + delta[1] / this.returnMiniSize() * this.renderContentBounds.h;
+            return false;
+        }), emptyFunction, emptyFunction);
+    }
+    renderMiniMap() {
+        return <div className="miniMap" style={{ width: this.returnMiniSize(), height: this.returnMiniSize() }}>
+            <CollectionFreeFormView
+                Document={this._document!}
+                LibraryPath={emptyPath}
+                CollectionView={undefined}
+                ContainingCollectionView={undefined}
+                ContainingCollectionDoc={undefined}
+                active={returnTrue}
+                select={emptyFunction}
+                dropAction={undefined}
+                isSelected={returnFalse}
+                annotationsKey={""}
+                fieldKey={Doc.LayoutFieldKey(this._document!)}
+                bringToFront={emptyFunction}
+                rootSelected={returnTrue}
+                addDocument={returnFalse}
+                moveDocument={returnFalse}
+                removeDocument={returnFalse}
+                ContentScaling={returnOne}
+                PanelWidth={this.returnMiniSize}
+                PanelHeight={this.returnMiniSize}
+                NativeHeight={returnZero}
+                NativeWidth={returnZero}
+                ScreenToLocalTransform={this.ScreenToLocalTransform}
+                renderDepth={0}
+                whenActiveChanged={emptyFunction}
+                focus={emptyFunction}
+                backgroundColor={CollectionDockingView.Instance.props.backgroundColor}
+                addDocTab={this.addDocTab}
+                pinToPres={DockedFrameRenderer.PinDoc}
+                docFilters={returnEmptyFilter}
+                fitToBox={true}
+            />
+            <div className="miniOverlay" onPointerDown={this.miniDown} >
+                <div className="miniThumb" style={{
+                    width: `${this.miniWidth}%`,
+                    height: `${this.miniHeight}%`,
+                    left: `${this.miniLeft}%`,
+                    top: `${this.miniTop}%`,
+                }}
+                />
+            </div>
+        </div>;
+    }
     @computed get docView() {
         TraceMobx();
         if (!this._document) return (null);
         const document = this._document;
-        const resolvedDataDoc = !Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined;// document.layout instanceof Doc ? document : this._dataDoc;
-        return <DocumentView key={document[Id]}
-            LibraryPath={this._libraryPath}
-            Document={document}
-            DataDoc={resolvedDataDoc}
-            bringToFront={emptyFunction}
-            rootSelected={returnTrue}
-            addDocument={undefined}
-            removeDocument={undefined}
-            ContentScaling={this.contentScaling}
-            PanelWidth={this.panelWidth}
-            PanelHeight={this.panelHeight}
-            NativeHeight={this.nativeHeight}
-            NativeWidth={this.nativeWidth}
-            ScreenToLocalTransform={this.ScreenToLocalTransform}
-            renderDepth={0}
-            parentActive={returnTrue}
-            whenActiveChanged={emptyFunction}
-            focus={emptyFunction}
-            backgroundColor={CollectionDockingView.Instance.props.backgroundColor}
-            addDocTab={this.addDocTab}
-            pinToPres={DockedFrameRenderer.PinDoc}
-            docFilters={returnEmptyFilter}
-            ContainingCollectionView={undefined}
-            ContainingCollectionDoc={undefined} />;
+        const resolvedDataDoc = !Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined;
+        return <>
+            <DocumentView key={document[Id]}
+                LibraryPath={this._libraryPath}
+                Document={document}
+                DataDoc={resolvedDataDoc}
+                bringToFront={emptyFunction}
+                rootSelected={returnTrue}
+                addDocument={undefined}
+                removeDocument={undefined}
+                ContentScaling={this.contentScaling}
+                PanelWidth={this.panelWidth}
+                PanelHeight={this.panelHeight}
+                NativeHeight={this.nativeHeight}
+                NativeWidth={this.nativeWidth}
+                ScreenToLocalTransform={this.ScreenToLocalTransform}
+                renderDepth={0}
+                parentActive={returnTrue}
+                whenActiveChanged={emptyFunction}
+                focus={emptyFunction}
+                backgroundColor={CollectionDockingView.Instance.props.backgroundColor}
+                addDocTab={this.addDocTab}
+                pinToPres={DockedFrameRenderer.PinDoc}
+                docFilters={returnEmptyFilter}
+                ContainingCollectionView={undefined}
+                ContainingCollectionDoc={undefined} />
+            {document._viewType === CollectionViewType.Freeform ? this.renderMiniMap() : (null)}
+        </>;
     }
 
     render() {
-- 
cgit v1.2.3-70-g09d2

