From d98db79837171d364d7897ac9b7bc6771af2a2a7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 26 Sep 2022 11:44:20 -0400
Subject: added onClick capability to linearView subMenu buttons so that
 inkTools could turn pen off when opening/closing.

---
 .../collectionLinear/CollectionLinearView.tsx        | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

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

diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 0d7d67dd8..f6eb2fce4 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -198,13 +198,7 @@ export class CollectionLinearView extends CollectionSubView() {
             <div className={`collectionLinearView-outer ${this.layoutDoc.linearViewSubMenu}`} style={{ backgroundColor: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : 'transparent' }}>
                 <div className="collectionLinearView" ref={this.createDashEventsTarget} onContextMenu={this.myContextMenu}>
                     {!expandable ? null : (
-                        <Tooltip
-                            title={
-                                <>
-                                    <div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? 'Close' : 'Open'}</div>
-                                </>
-                            }
-                            placement="top">
+                        <Tooltip title={<div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? 'Close' : 'Open'}</div>} placement="top">
                             {menuOpener}
                         </Tooltip>
                     )}
@@ -213,7 +207,17 @@ export class CollectionLinearView extends CollectionSubView() {
                         type="checkbox"
                         checked={BoolCast(this.props.Document.linearViewIsExpanded)}
                         ref={this.addMenuToggle}
-                        onChange={action(() => (this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked))}
+                        onChange={action(e => {
+                            ScriptCast(this.Document.onClick).script.run({
+                                this: this.layoutDoc,
+                                self: this.rootDoc,
+                                _readOnly_: false,
+                                scriptContext: this.props.scriptContext,
+                                thisContainer: this.props.ContainingCollectionDoc,
+                                documentView: this.props.docViewPath().lastElement(),
+                            });
+                            this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked;
+                        })}
                     />
 
                     <div
-- 
cgit v1.2.3-70-g09d2


From 2de2e154912d95a15e5f890c9d1a3a7a11610107 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 29 Sep 2022 20:44:33 -0400
Subject: a bunch of changes to trails: link to trail to initiate trail when
 following link.  cleanly separate pin layout data vs. content data.

---
 src/client/documents/Documents.ts                  |   3 +
 src/client/util/CurrentUserUtils.ts                |   2 +-
 src/client/util/DocumentManager.ts                 |   2 +-
 src/client/util/type_decls.d                       |   3 +
 src/client/views/DocumentButtonBar.scss            |  22 ++-
 src/client/views/DocumentButtonBar.tsx             |  71 +++++++---
 src/client/views/DocumentDecorations.tsx           |   3 +-
 src/client/views/MainView.tsx                      |   1 +
 src/client/views/collections/TabDocView.tsx        |   2 +-
 src/client/views/collections/TreeView.tsx          |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   6 +-
 .../collectionFreeForm/MarqueeOptionsMenu.tsx      |  42 +++---
 .../collections/collectionFreeForm/MarqueeView.tsx |  12 +-
 .../collectionLinear/CollectionLinearView.tsx      |   2 +-
 src/client/views/nodes/DocumentView.tsx            |   4 +-
 src/client/views/nodes/ScriptingBox.tsx            |   5 +
 src/client/views/nodes/trails/PresBox.tsx          | 147 +++++++++------------
 src/client/views/nodes/trails/PresElementBox.tsx   |  66 ++++++---
 18 files changed, 225 insertions(+), 170 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fb68fba38..4ca9972f8 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1398,6 +1398,9 @@ export namespace DocUtils {
                         heading: Doc.name,
                         checked: 'boolean',
                         containingTreeView: Doc.name,
+                        altKey: 'boolean',
+                        ctrlKey: 'boolean',
+                        shiftKey: 'boolean',
                     });
                 }
             });
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index fdac3c00a..6f9975be4 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -657,7 +657,7 @@ export class CurrentUserUtils {
                     CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map,
                     CollectionViewType.Grid, CollectionViewType.NoteTaking]),
               title: "Perspective",                    toolTip: "View",                 btnType: ButtonType.DropdownList,                                                                                    ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}},
-            { title: "Pin",     icon: "map-pin",       toolTip: "Pin View to Trail",    btnType: ButtonType.ClickButton,         funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "tab")'},                        width: 20,  scripts: { onClick: 'pinWithView(_readOnly_)'}},
+            { title: "Pin",     icon: "map-pin",       toolTip: "Pin View to Trail",    btnType: ButtonType.ClickButton,         funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "tab")'},                        width: 20,  scripts: { onClick: 'pinWithView(_readOnly_, altKey)'}},
             { title: "Back",    icon: "chevron-left",  toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton,         funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()'}, width: 20,  scripts: { onClick: 'prevKeyFrame(_readOnly_)'}},
             { title: "Num",     icon: "",              toolTip: "Frame Number",         btnType: ButtonType.TextButton,          funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()', buttonText: 'selectedDocs()?.lastElement()?.currentFrame.toString()'}, width: 20,  scripts: {}},
             { title: "Fwd",     icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton,         funcs: {hidden: '!SelectionManager_selectedDocType(undefined, "freeform") || IsNoviceMode()'}, width: 20,  scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 50190061a..9a46d20de 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -244,7 +244,7 @@ export class DocumentManager {
                             res(ViewAdjustment.doNothing);
                         }),
                 });
-            if (focusView.props.Document.layoutKey === 'layout_icon') {
+            if (focusView.props.Document.layoutKey === 'layout_icon' && focusView.rootDoc.type !== DocumentType.SCRIPTING) {
                 focusView.iconify(() => doFocus(true));
             } else {
                 doFocus(false);
diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index 9063dc894..1a93bbe59 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -67,6 +67,9 @@ interface RegExp {
     readonly sticky: boolean;
     readonly unicode: boolean;
 }
+interface Date {
+    now() : string;
+}
 interface String {
     codePointAt(pos: number): number | undefined;
     includes(searchString: string, position?: number): boolean;
diff --git a/src/client/views/DocumentButtonBar.scss b/src/client/views/DocumentButtonBar.scss
index a112f4745..1e93ba5e2 100644
--- a/src/client/views/DocumentButtonBar.scss
+++ b/src/client/views/DocumentButtonBar.scss
@@ -1,6 +1,6 @@
-@import "global/globalCssVariables";
+@import 'global/globalCssVariables';
 
-$linkGap : 3px;
+$linkGap: 3px;
 
 .documentButtonBar-linkFlyout {
     grid-column: 2/4;
@@ -18,6 +18,21 @@ $linkGap : 3px;
     cursor: pointer;
 }
 
+.documentButtonBar-pinTypes {
+    position: absolute;
+    display: flex;
+    width: 60px;
+    top: -14px;
+    background: black;
+    height: 20px;
+    align-items: center;
+}
+.documentButtonBar-pinIcon {
+    &:hover {
+        background-color: lightblue;
+    }
+}
+
 .documentButtonBar-linkButton-empty,
 .documentButtonBar-linkButton-nonempty {
     height: 20px;
@@ -99,7 +114,6 @@ $linkGap : 3px;
     transform: scale(1.05);
 }
 
-
 @-moz-keyframes spin {
     100% {
         -moz-transform: rotate(360deg);
@@ -127,4 +141,4 @@ $linkGap : 3px;
     100% {
         box-shadow: 0 0 0 10px rgba(0, 255, 0, 0);
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 0bfe6e87a..d42ff436f 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -5,8 +5,8 @@ import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc } from '../../fields/Doc';
 import { RichTextField } from '../../fields/RichTextField';
-import { Cast, DocCast, NumCast } from '../../fields/Types';
-import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
+import { Cast, NumCast } from '../../fields/Types';
+import { emptyFunction, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
 import { Docs } from '../documents/Documents';
@@ -26,7 +26,6 @@ import { DashFieldView } from './nodes/formattedText/DashFieldView';
 import { GoogleRef } from './nodes/formattedText/FormattedTextBox';
 import { TemplateMenu } from './TemplateMenu';
 import React = require('react');
-import { DocumentType } from '../documents/DocumentTypes';
 const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -159,12 +158,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         })();
 
         return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? null : (
-            <Tooltip
-                title={
-                    <>
-                        <div className="dash-tooltip">{title}</div>
-                    </>
-                }>
+            <Tooltip title={<div className="dash-tooltip">{title}</div>}>
                 <div
                     className="documentButtonBar-button"
                     style={{ backgroundColor: this.pullColor }}
@@ -202,14 +196,12 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
                         size="sm"
                         style={{ WebkitAnimation: animation, MozAnimation: animation }}
                         icon={(() => {
+                            // prettier-ignore
                             switch (this.openHover) {
                                 default:
-                                case UtilityButtonState.Default:
-                                    return dataDoc.googleDocUnchanged === false ? (this.pullIcon as any) : fetch;
-                                case UtilityButtonState.OpenRight:
-                                    return 'arrow-alt-circle-right';
-                                case UtilityButtonState.OpenExternally:
-                                    return 'share';
+                                case UtilityButtonState.Default: return dataDoc.googleDocUnchanged === false ? (this.pullIcon as any) : fetch;
+                                case UtilityButtonState.OpenRight: return 'arrow-alt-circle-right';
+                                case UtilityButtonState.OpenExternally: return 'share';
                             }
                         })()}
                     />
@@ -231,21 +223,66 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             </Tooltip>
         );
     }
+    @observable expandPin = false;
+    @observable subPin = '';
     @computed
     get pinButton() {
         const targetDoc = this.view0?.props.Document;
+        const pinBtn = (pinDocLayout: boolean, pinDocContent: boolean, icon: IconProp) => {
+            const tooltip = `Pin Document and Save ${this.subPin} to trail`;
+            return !tooltip ? null : (
+                <Tooltip title={<div className="dash-tooltip">{tooltip}</div>}>
+                    <div className="documentButtonBar-pinIcon">
+                        <FontAwesomeIcon
+                            className="documentdecorations-icon"
+                            style={{ width: 20 }}
+                            key={icon.toString()}
+                            size="sm"
+                            icon={icon}
+                            onPointerEnter={action(
+                                e =>
+                                    (this.subPin =
+                                        (pinDocLayout ? 'Layout' : '') +
+                                        (pinDocLayout && pinDocContent ? ' &' : '') +
+                                        (pinDocContent ? ' Content View' : '') +
+                                        (pinDocLayout && pinDocContent ? '(shift+alt)' : pinDocLayout ? '(shift)' : pinDocContent ? '(alt)' : ''))
+                            )}
+                            onPointerLeave={action(e => (this.subPin = ''))}
+                            onClick={e => {
+                                const docs = this.props
+                                    .views()
+                                    .filter(v => v)
+                                    .map(dv => dv!.rootDoc);
+                                TabDocView.PinDoc(docs, { pinDocLayout, pinDocContent, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
+                                e.stopPropagation();
+                            }}
+                        />
+                    </div>
+                </Tooltip>
+            );
+        };
         return !targetDoc ? null : (
-            <Tooltip title={<div className="dash-tooltip">{SelectionManager.Views().length > 1 ? 'Pin multiple documents to trail (use shift to pin with view)' : 'Pin to trail (use shift to pin with view)'}</div>}>
+            <Tooltip title={<div className="dash-tooltip">{`Pin Document ${SelectionManager.Views().length > 1 ? 'multiple documents' : ''} to Trail`}</div>}>
                 <div
                     className="documentButtonBar-icon"
                     style={{ color: 'white' }}
+                    onPointerEnter={action(e => (this.expandPin = true))}
+                    onPointerLeave={action(e => (this.expandPin = false))}
                     onClick={e => {
                         const docs = this.props
                             .views()
                             .filter(v => v)
                             .map(dv => dv!.rootDoc);
-                        TabDocView.PinDoc(docs, { pinDocView: e.shiftKey, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
+                        TabDocView.PinDoc(docs, { pinDocLayout: e.shiftKey, pinDocContent: e.altKey, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
+                        e.stopPropagation();
                     }}>
+                    {this.expandPin ? (
+                        <div className="documentButtonBar-pinTypes">
+                            {pinBtn(true, false, 'window-maximize')}
+                            {pinBtn(false, true, 'address-card')}
+                            {pinBtn(true, true, 'id-card')}
+                        </div>
+                    ) : null}
                     <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
                 </div>
             </Tooltip>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4675571c2..3e0de6d15 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -678,8 +678,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
         bounds.r = Math.max(bounds.x, Math.max(leftBounds, Math.min(window.innerWidth, bounds.r + borderRadiusDraggerWidth + this._resizeBorderWidth / 2) - this._resizeBorderWidth / 2 - borderRadiusDraggerWidth));
         bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight));
 
-        // Rotation constants: Only allow rotation on ink and images
-        const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox || seldoc.ComponentView instanceof VideoBox;
+        const useRotation = true; // when do we want an object to not rotate?
         const rotation = NumCast(seldoc.rootDoc._jitterRotation);
 
         const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : '';
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 857a5522c..350883f70 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -303,6 +303,7 @@ export class MainView extends React.Component {
                 fa.faStop,
                 fa.faCalculator,
                 fa.faWindowMaximize,
+                fa.faIdCard,
                 fa.faAddressCard,
                 fa.faQuestionCircle,
                 fa.faArrowLeft,
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index b1f57f3fd..c4da70371 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -233,7 +233,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             pinDoc.presentationTargetDoc = doc;
             pinDoc.title = doc.title + ' - Slide';
             pinDoc.data = new List<Doc>(); // the children of the alias' layout are the presentation slide children.  the alias' data field might be children of a collection, PDF data, etc -- in any case we don't want the tree view to "see" this data
-            pinDoc.presMovement = pinProps?.pinDocView && !pinProps?.pinWithView ? PresMovement.None : PresMovement.Zoom;
+            pinDoc.presMovement = doc.type === DocumentType.SCRIPTING || pinProps?.pinDocLayout ? PresMovement.None : PresMovement.Zoom;
             pinDoc.groupWithUp = false;
             pinDoc.context = curPres;
             // these should potentially all be props passed down by the CollectionTreeView to the TreeView elements.  That way the PresBox could configure all of its children at render time
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index c34a6faaa..640984ad6 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -782,7 +782,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
     onChildDoubleClick = () => ScriptCast(this.props.treeView.Document.treeViewChildDoubleClick, !this.props.treeView.outlineMode ? this._openScript?.() : null);
 
-    refocus = () => this.props.treeView.props.focus(this.props.treeView.props.Document);
+    refocus = () => this.props.treeView.props.focus(this.props.treeView.props.Document, {});
     ignoreEvent = (e: any) => {
         if (this.props.isContentActive(true)) {
             e.stopPropagation();
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 7b6944e1e..8824c2b01 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1719,7 +1719,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             event: () => (this.Document._fitContentsToBox = !this.fitContentsToBox),
             icon: !this.fitContentsToBox ? 'expand-arrows-alt' : 'compress-arrows-alt',
         });
-        appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, { pinDocView: true, panelWidth: this.props.PanelWidth(), panelHeight: this.props.PanelHeight() }), icon: 'map-pin' });
+        appearanceItems.push({ description: `Pin View`, event: () => TabDocView.PinDoc(this.rootDoc, { pinViewport: MarqueeView.CurViewBounds(this.rootDoc, this.props.PanelWidth(), this.props.PanelHeight()) }), icon: 'map-pin' });
         //appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
         this.props.ContainingCollectionView && appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' });
 
@@ -2249,6 +2249,6 @@ ScriptingGlobals.add(function nextKeyFrame(readOnly: boolean) {
 ScriptingGlobals.add(function prevKeyFrame(readOnly: boolean) {
     !readOnly && (SelectionManager.Views()[0].ComponentView as CollectionFreeFormView)?.changeKeyFrame(true);
 });
-ScriptingGlobals.add(function pinWithView(readOnly: boolean) {
-    !readOnly && SelectionManager.Views().forEach(view => TabDocView.PinDoc(view.rootDoc, { pinDocView: true, panelWidth: view.props.PanelWidth(), panelHeight: view.props.PanelHeight() }));
+ScriptingGlobals.add(function pinWithView(readOnly: boolean, pinDocContent: boolean) {
+    !readOnly && SelectionManager.Views().forEach(view => TabDocView.PinDoc(view.rootDoc, { pinDocContent, pinViewport: MarqueeView.CurViewBounds(view.rootDoc, view.props.PanelWidth(), view.props.PanelHeight()) }));
 });
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index 8a8b528f6..488f51d77 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -1,11 +1,11 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
-import { observer } from "mobx-react";
-import { unimplementedFunction } from "../../../../Utils";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { AntimodeMenu, AntimodeMenuProps } from "../../AntimodeMenu";
+import React = require('react');
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
+import { observer } from 'mobx-react';
+import { unimplementedFunction } from '../../../../Utils';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { SelectionManager } from '../../../util/SelectionManager';
+import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
 
 @observer
 export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -25,44 +25,34 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
 
     render() {
-        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: "auto", width: 19, transform: 'translate(-2px, -2px)' }} />;
+        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: 'auto', width: 19, transform: 'translate(-2px, -2px)' }} />;
         const buttons = [
             <Tooltip key="collect" title={<div className="dash-tooltip">Create a Collection</div>} placement="bottom">
-                <button
-                    className="antimodeMenu-button"
-                    onPointerDown={this.createCollection}>
+                <button className="antimodeMenu-button" onPointerDown={this.createCollection}>
                     <FontAwesomeIcon icon="object-group" size="lg" />
                 </button>
             </Tooltip>,
             <Tooltip key="group" title={<div className="dash-tooltip">Create a Grouping</div>} placement="bottom">
-                <button
-                    className="antimodeMenu-button"
-                    onPointerDown={e => this.createCollection(e, true)}>
+                <button className="antimodeMenu-button" onPointerDown={e => this.createCollection(e, true)}>
                     <FontAwesomeIcon icon="layer-group" size="lg" />
                 </button>
             </Tooltip>,
             <Tooltip key="summarize" title={<div className="dash-tooltip">Summarize Documents</div>} placement="bottom">
-                <button
-                    className="antimodeMenu-button"
-                    onPointerDown={this.summarize}>
+                <button className="antimodeMenu-button" onPointerDown={this.summarize}>
                     <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
                 </button>
             </Tooltip>,
             <Tooltip key="delete" title={<div className="dash-tooltip">Delete Documents</div>} placement="bottom">
-                <button
-                    className="antimodeMenu-button"
-                    onPointerDown={this.delete}>
+                <button className="antimodeMenu-button" onPointerDown={this.delete}>
                     <FontAwesomeIcon icon="trash-alt" size="lg" />
                 </button>
             </Tooltip>,
-            <Tooltip key="pinWithView" title={<div className="dash-tooltip">Pin with selected region</div>} placement="bottom">
-                <button
-                    className="antimodeMenu-button"
-                    onPointerDown={this.pinWithView}>
+            <Tooltip key="pinWithView" title={<div className="dash-tooltip">Pin selected region to trail</div>} placement="bottom">
+                <button className="antimodeMenu-button" onPointerDown={this.pinWithView}>
                     {presPinWithViewIcon}
                 </button>
             </Tooltip>,
         ];
         return this.getElement(buttons);
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 584c9690f..a020b67cd 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -18,7 +18,7 @@ import { Transform } from '../../../util/Transform';
 import { undoBatch, UndoManager } from '../../../util/UndoManager';
 import { ContextMenu } from '../../ContextMenu';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
-import { PinViewProps, PresBox } from '../../nodes/trails/PresBox';
+import { PresBox } from '../../nodes/trails/PresBox';
 import { VideoBox } from '../../nodes/VideoBox';
 import { pasteImageBitmap } from '../../nodes/WebBoxRenderer';
 import { PreviewCursor } from '../../PreviewCursor';
@@ -61,6 +61,11 @@ export interface MarqueeViewBounds {
 
 @observer
 export class MarqueeView extends React.Component<SubCollectionViewProps & MarqueeViewProps> {
+    public static CurViewBounds(pinDoc: Doc, panelWidth: number, panelHeight: number) {
+        const ps = NumCast(pinDoc._viewScale, 1);
+        return { left: NumCast(pinDoc._panX) - panelWidth / 2 / ps, top: NumCast(pinDoc._panY) - panelHeight / 2 / ps, width: panelWidth / ps, height: panelHeight / ps };
+    }
+
     private _commandExecuted = false;
     @observable _lastX: number = 0;
     @observable _lastY: number = 0;
@@ -426,10 +431,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     @action
     pinWithView = async () => {
         const doc = this.props.Document;
-        const viewOptions: PinViewProps = {
-            bounds: this.Bounds,
-        };
-        TabDocView.PinDoc(doc, { pinWithView: viewOptions, pinDocView: true });
+        TabDocView.PinDoc(doc, { pinViewport: this.Bounds });
         MarqueeOptionsMenu.Instance.fadeOut(true);
         this.hideMarquee();
     };
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index f6eb2fce4..92f6bbb64 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -208,7 +208,7 @@ export class CollectionLinearView extends CollectionSubView() {
                         checked={BoolCast(this.props.Document.linearViewIsExpanded)}
                         ref={this.addMenuToggle}
                         onChange={action(e => {
-                            ScriptCast(this.Document.onClick).script.run({
+                            ScriptCast(this.Document.onClick)?.script.run({
                                 this: this.layoutDoc,
                                 self: this.rootDoc,
                                 _readOnly_: false,
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ba061ce8f..913d5a7ef 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -577,6 +577,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                                 documentView: this.props.DocumentView(),
                                 clientX,
                                 clientY,
+                                altKey,
                                 shiftKey,
                             },
                             console.log
@@ -589,7 +590,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                 }
             } else if (this.onClickHandler?.script && !isScriptBox()) {
                 // bcz: hack? don't execute script if you're clicking on a scripting box itself
-                const { clientX, clientY, shiftKey } = e;
+                const { clientX, clientY, shiftKey, altKey } = e;
                 const func = () =>
                     this.onClickHandler.script.run(
                         {
@@ -602,6 +603,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                             clientX,
                             clientY,
                             shiftKey,
+                            altKey,
                         },
                         console.log
                     ).result?.select === true
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 1c9b0bc0e..37afcdd8b 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -115,6 +115,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
 
     @action
     componentDidMount() {
+        this.props.setContentView?.(this);
         this.rawText = this.rawScript;
         const observer = new _global.ResizeObserver(
             action((entries: any) => {
@@ -480,6 +481,10 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
         return value;
     }
 
+    scrollFocus = () => {
+        return undefined;
+    };
+
     getSuggestedParams(pos: number) {
         const firstScript = this.rawText.slice(0, pos);
         const indexP = firstScript.lastIndexOf('.');
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 0c4d514cd..18441aace 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -31,19 +31,16 @@ import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentVie
 import { FieldView, FieldViewProps } from '../FieldView';
 import './PresBox.scss';
 import { PresEffect, PresMovement, PresStatus } from './PresEnums';
+import { privateEncrypt } from 'crypto';
+import { ScriptingBox } from '../ScriptingBox';
 
 export interface PinProps {
     audioRange?: boolean;
     activeFrame?: number;
     hidePresBox?: boolean;
-    pinWithView?: PinViewProps;
-    pinDocView?: boolean; // whether the current view specs of the document should be saved the pinned document
-    panelWidth?: number; // panel width and height of the document (used to compute the bounds of the pinned view area)
-    panelHeight?: number;
-}
-
-export interface PinViewProps {
-    bounds: MarqueeViewBounds;
+    pinViewport?: MarqueeViewBounds; // pin a specific viewport on a freeform view (use MarqueeView.CurViewBounds to compute if no region has been selected)
+    pinDocLayout?: boolean; // pin layout info (width/height/x/y)
+    pinDocContent?: boolean; // pin data info (scroll/pan/zoom/text)
 }
 
 @observer
@@ -268,6 +265,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode
             this.nextSlide(0);
         }
+        return this.itemIndex;
     };
 
     // Called when the user activates 'back' - to move to the previous part of the pres. trail
@@ -298,6 +296,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             // Case 3: Pres loop is on so it should go to the last slide
             this.gotoDocument(this.childDocs.length - 1, activeItem);
         }
+        return this.itemIndex;
     };
 
     //The function that is called when a document is clicked or reached through next or back.
@@ -351,7 +350,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const pannable = [DocumentType.IMG].includes(target.type as any) || (target.type === DocumentType.COL && target._viewType === CollectionViewType.Freeform);
         const temporal = [DocumentType.AUDIO, DocumentType.VID].includes(target.type as any);
         const clippable = [DocumentType.COMPARISON].includes(target.type as any);
-        const dataview = [DocumentType.INK].includes(target.type as any) && target.activeFrame === undefined;
+        const dataview = [DocumentType.INK, DocumentType.COL].includes(target.type as any) && target.activeFrame === undefined;
         const textview = [DocumentType.RTF].includes(target.type as any) && target.activeFrame === undefined;
         return { scrollable, pannable, temporal, clippable, dataview, textview };
     }
@@ -383,7 +382,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 const dv = DocumentManager.Instance.getDocumentView(bestTarget);
                 if (dv) {
                     const computedScale = NumCast(activeItem.presZoom, 1) * Math.min(dv.props.PanelWidth() / viewport.width, dv.props.PanelHeight() / viewport.height);
-                    activeItem.presMovement === 'zoom' && (bestTarget._viewScale = activeItem.presZoom !== undefined ? computedScale : Math.min(computedScale, NumCast(bestTarget._viewScale)));
+                    activeItem.presMovement === 'zoom' && (bestTarget._viewScale = computedScale);
                     dv.ComponentView?.brushView?.(viewport);
                 }
             } else {
@@ -400,47 +399,40 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     /// target doc when navigating to it.
     @action
     static pinDocView(pinDoc: Doc, pinProps: PinProps | undefined, targetDoc: Doc) {
-        if (pinProps?.pinWithView) {
-            // If pinWithView option set then update scale and x / y props of slide
-            const bounds = pinProps.pinWithView.bounds;
-            pinDoc.presPinView = true;
-            pinDoc.presPinViewX = bounds.left + bounds.width / 2;
-            pinDoc.presPinViewY = bounds.top + bounds.height / 2;
-            pinDoc.presPinViewBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
-        }
-        if (pinProps?.pinDocView) {
-            const { scrollable, pannable, temporal, clippable, dataview, textview } = this.pinDataTypes(pinDoc);
-            pinDoc.presPinView = (pinProps?.pinWithView ? true : false) || scrollable || temporal || pannable || clippable || dataview || textview || pinProps.activeFrame !== undefined;
+        const { scrollable, pannable, temporal, clippable, dataview, textview } = this.pinDataTypes(pinDoc);
+        if (pinProps?.pinDocLayout) {
+            pinDoc.presPinLayout = true;
             pinDoc.presX = NumCast(targetDoc.x);
             pinDoc.presY = NumCast(targetDoc.y);
             pinDoc.presRot = NumCast(targetDoc.jitterRotation);
             pinDoc.presWidth = NumCast(targetDoc.width);
             pinDoc.presHeight = NumCast(targetDoc.height);
-
-            if (scrollable) {
-                pinDoc.presPinViewScroll = pinDoc._scrollTop;
-            }
+        }
+        if (pinProps?.pinDocContent) {
+            pinDoc.presPinData = scrollable || temporal || pannable || clippable || dataview || textview || pinProps.activeFrame !== undefined;
+            if (textview) pinDoc.presData = targetDoc.text instanceof ObjectField ? targetDoc.text[Copy]() : targetDoc.text;
+            if (scrollable) pinDoc.presPinViewScroll = pinDoc._scrollTop;
             if (clippable) pinDoc.presPinClipWidth = pinDoc._clipWidth;
+            if (dataview) pinDoc.presData = targetDoc.data instanceof ObjectField ? targetDoc.data[Copy]() : targetDoc.data;
+            if (pannable) {
+                pinDoc.presPinViewX = NumCast(pinDoc._panX);
+                pinDoc.presPinViewY = NumCast(pinDoc._panY);
+                pinDoc.presPinViewScale = NumCast(pinDoc._viewScale, 1);
+            }
             if (temporal) {
                 pinDoc.presStartTime = pinDoc._currentTimecode;
                 const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], NumCast(pinDoc.presStartTime) + 0.1);
                 pinDoc.presEndTime = NumCast(pinDoc.clipEnd, duration);
             }
-            if (textview) pinDoc.presData = targetDoc.text instanceof ObjectField ? targetDoc.text[Copy]() : targetDoc.text;
-            if (dataview) pinDoc.presData = targetDoc.data instanceof ObjectField ? targetDoc.data[Copy]() : targetDoc.data;
-            if (pannable || scrollable) {
-                const panX = NumCast(pinDoc._panX);
-                const panY = NumCast(pinDoc._panY);
-                const pw = NumCast(pinProps.panelWidth);
-                const ph = NumCast(pinProps.panelHeight);
-                const ps = NumCast(pinDoc._viewScale, 1);
-                if (pw && ph && ps) {
-                    pinDoc.presPinViewBounds = new List<number>([panX - pw / 2 / ps, panY - ph / 2 / ps, panX + pw / 2 / ps, panY + ph / 2 / ps]);
-                }
-                pinDoc.presPinViewX = panX;
-                pinDoc.presPinViewY = panY;
-                pinDoc.presPinViewScale = ps;
-            }
+        }
+        if (pinProps?.pinViewport) {
+            // If pinWithView option set then update scale and x / y props of slide
+            const bounds = pinProps.pinViewport;
+            pinDoc.presPinView = true;
+            pinDoc.presPinViewScale = NumCast(pinDoc._viewScale, 1);
+            pinDoc.presPinViewX = bounds.left + bounds.width / 2;
+            pinDoc.presPinViewY = bounds.top + bounds.height / 2;
+            pinDoc.presPinViewBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
         }
     }
 
@@ -497,7 +489,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     };
 
     static NavigateToTarget(targetDoc: Doc, activeItem: Doc, openInTab: any, srcContext: Doc, finished?: () => void) {
-        if (activeItem.presPinView && DocCast(targetDoc.context)?._currentFrame === undefined) {
+        if ((activeItem.presPinLayout || activeItem.presPinView) && DocCast(targetDoc.context)?._currentFrame === undefined) {
             const transTime = NumCast(activeItem.presTransition, 500);
             const presTransitionTime = `all ${transTime}ms`;
             targetDoc._dataTransition = presTransitionTime;
@@ -514,11 +506,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         } else if (targetDoc && activeItem.presMovement !== PresMovement.None) {
             LightboxView.SetLightboxDoc(undefined);
             const zooming = activeItem.presMovement !== PresMovement.Pan;
-            DocumentManager.Instance.jumpToDocument(targetDoc, zooming, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, finished, undefined, true, NumCast(activeItem.presZoom));
+            DocumentManager.Instance.jumpToDocument(targetDoc, zooming, openInTab, srcContext ? [srcContext] : [], undefined, undefined, undefined, finished, undefined, true, NumCast(activeItem.presZoom, 1));
+        } else if (activeItem.presMovement === PresMovement.None && targetDoc.type === DocumentType.SCRIPTING) {
+            (DocumentManager.Instance.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.();
         }
         // After navigating to the document, if it is added as a presPinView then it will
         // adjust the pan and scale to that of the pinView when it was added.
-        if (activeItem.presPinView) {
+        if (activeItem.presPinData || activeItem.presPinView) {
             clearTimeout(PresBox._navTimer);
             // targetDoc may or may not be displayed.  this gets the first available document (or alias) view that matches targetDoc
             const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document;
@@ -615,42 +609,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
     @action
     startAutoPres = (startSlide: number) => {
-        this.updateCurrentPresentation();
-        let activeItem: Doc = this.activeItem;
-        let targetDoc: Doc = this.targetDoc;
-        let duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
-        const timer = (ms: number) => new Promise(res => (this._presTimer = setTimeout(res, ms)));
-        const load = async () => {
-            // Wrap the loop into an async function for this to work
-            for (var i = startSlide; i < this.childDocs.length; i++) {
-                activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-                targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-                duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
-                if (duration < 100) {
-                    duration = 2500;
-                }
-                if (NumCast(targetDoc.lastFrame) > 0) {
-                    for (var f = 0; f < NumCast(targetDoc.lastFrame); f++) {
-                        await timer(duration / NumCast(targetDoc.lastFrame));
-                        this.next();
-                    }
-                }
-
-                await timer(duration);
-                this.next(); // then the created Promise can be awaited
-                if (i === this.childDocs.length - 1) {
-                    setTimeout(() => {
-                        clearTimeout(this._presTimer);
-                        if (this.layoutDoc.presStatus === 'auto' && !this.layoutDoc.presLoop) this.layoutDoc.presStatus = PresStatus.Manual;
-                        else if (this.layoutDoc.presLoop) this.startAutoPres(0);
-                    }, duration);
-                }
-            }
-        };
         this.layoutDoc.presStatus = PresStatus.Autoplay;
         this.startPresentation(startSlide);
-        this.gotoDocument(startSlide, activeItem);
-        load();
+        clearTimeout(this._presTimer);
+        const func = (itemIndex: number) => {
+            if (itemIndex === this.next()) this.layoutDoc.presStatus = PresStatus.Manual;
+            else
+                this._presTimer = setTimeout(
+                    () => this.layoutDoc.presStatus !== PresStatus.Manual && func(this.itemIndex),
+                    NumCast(this.activeItem.presDuration, this.activeItem.type === DocumentType.SCRIPTING ? 0 : 2500) + NumCast(this.activeItem.presTransition)
+                );
+        };
+
+        func(this.itemIndex);
     };
 
     // The function pauses the auto presentation
@@ -659,7 +630,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (this.layoutDoc.presStatus === PresStatus.Autoplay) {
             if (this._presTimer) clearTimeout(this._presTimer);
             this.layoutDoc.presStatus = PresStatus.Manual;
-            this.layoutDoc.presLoop = false;
             this.childDocs.forEach(this.stopTempMedia);
         }
     };
@@ -667,7 +637,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     //The function that resets the presentation by removing every action done by it. It also
     //stops the presentaton.
     resetPresentation = () => {
-        this.rootDoc._itemIndex = 0;
         this.childDocs
             .map(doc => Cast(doc.presentationTargetDoc, Doc, null))
             .filter(doc => doc instanceof Doc)
@@ -706,8 +675,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
      * @param startIndex: index that the presentation will start at
      */
     startPresentation = (startIndex: number) => {
-        this.updateCurrentPresentation();
-        this.childDocs.map(doc => {
+        this.childDocs.forEach(doc => {
             const tagDoc = doc.presentationTargetDoc as Doc;
             if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) {
                 tagDoc.opacity = 0;
@@ -716,6 +684,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 tagDoc.opacity = 0;
             }
         });
+        this.gotoDocument(startIndex, this.activeItem);
     };
 
     /**
@@ -996,7 +965,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 break;
             case 'Spacebar':
             case ' ':
-                if (this.layoutDoc.presStatus === PresStatus.Manual) this.startAutoPres(this.itemIndex);
+                if (this.layoutDoc.presStatus === PresStatus.Manual) this.startOrPause(true);
                 else if (this.layoutDoc.presStatus === PresStatus.Autoplay) if (this._presTimer) clearTimeout(this._presTimer);
                 handled = true;
                 break;
@@ -1254,7 +1223,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (activeItem && targetDoc) {
             const type = targetDoc.type;
             const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
-            const zoom = activeItem.presZoom ? NumCast(activeItem.presZoom) * 100 : 75;
+            const zoom = NumCast(activeItem.presZoom, 1) * 100;
             let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
             if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
             const effect = this.activeItem.presEffect ? this.activeItem.presEffect : 'None';
@@ -1808,6 +1777,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         );
     }
 
+    scrollFocus = () => {
+        this.startOrPause(false);
+        return undefined;
+    };
+
     // Case in which the document has keyframes to navigate to next key frame
     @action
     nextKeyframe = (tagDoc: Doc, curDoc: Doc): void => {
@@ -2480,7 +2454,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     <FontAwesomeIcon icon={'arrow-left'} />
                 </div>
                 <Tooltip title={<div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>}>
-                    <div className="presPanel-button" onClick={this.startOrPause}>
+                    <div className="presPanel-button" onClick={e => this.startOrPause(true)}>
                         <FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} />
                     </div>
                 </Tooltip>
@@ -2529,7 +2503,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     }
 
     @action
-    startOrPause = () => {
+    startOrPause = (makeActive = true) => {
+        makeActive && this.updateCurrentPresentation();
         if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex);
         else this.pauseAutoPres();
     };
@@ -2613,7 +2588,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         <FontAwesomeIcon icon={'arrow-left'} />
                     </div>
                     <Tooltip title={<div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>}>
-                        <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.startOrPause, false, false)}>
+                        <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, () => this.startOrPause(true), false, false)}>
                             <FontAwesomeIcon icon={this.layoutDoc.presStatus === 'auto' ? 'pause' : 'play'} />
                         </div>
                     </Tooltip>
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index e6d08cd53..fe2668492 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -26,6 +26,7 @@ import { PresMovement } from './PresEnums';
 import React = require('react');
 import { InkField } from '../../../../fields/InkField';
 import { RichTextField } from '../../../../fields/RichTextField';
+import { MarqueeView } from '../../collections/collectionFreeForm';
 /**
  * This class models the view a document added to presentation will have in the presentation.
  * It involves some functionality for its buttons and options.
@@ -142,7 +143,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     this.presExpandDocumentClick();
                 }}>
                 <div className="presItem-groupNum">{`${ind + 1}.`}</div>
-                {/* style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105, cursor: isSelected ? 'text' : 'grab' }} */}
                 <div className="presItem-name">
                     <EditableView
                         ref={this._titleRef}
@@ -304,7 +304,22 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
      */
     @undoBatch
     @action
-    updateView = (targetDoc: Doc, activeItem: Doc) => {
+    updateCapturedContainerLayout = (targetDoc: Doc, activeItem: Doc) => {
+        activeItem.presX = NumCast(targetDoc.x);
+        activeItem.presY = NumCast(targetDoc.y);
+        activeItem.presRot = NumCast(targetDoc.jitterRotation);
+        activeItem.presWidth = NumCast(targetDoc.width);
+        activeItem.presHeight = NumCast(targetDoc.height);
+    };
+    /**
+     * Method called for updating the view of the currently selected document
+     *
+     * @param targetDoc
+     * @param activeItem
+     */
+    @undoBatch
+    @action
+    updateCapturedViewContents = (targetDoc: Doc, activeItem: Doc) => {
         switch (targetDoc.type) {
             case DocumentType.PDF:
             case DocumentType.WEB:
@@ -326,20 +341,22 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 const clipWidth = targetDoc._clipWidth;
                 activeItem.presPinClipWidth = clipWidth;
                 break;
+            case DocumentType.COL:
             default:
-                const x = targetDoc._panX;
-                const y = targetDoc._panY;
-                const scale = targetDoc._viewScale;
-                activeItem.presPinViewX = x;
-                activeItem.presPinViewY = y;
-                activeItem.presPinViewScale = scale;
+                const bestView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
+                if (activeItem.presPinViewBounds && bestView) {
+                    const bounds = MarqueeView.CurViewBounds(targetDoc, bestView.props.PanelWidth(), bestView.props.PanelHeight());
+                    activeItem.presPinView = true;
+                    activeItem.presPinViewScale = NumCast(targetDoc._viewScale, 1);
+                    activeItem.presPinViewX = bounds.left + bounds.width / 2;
+                    activeItem.presPinViewY = bounds.top + bounds.height / 2;
+                    activeItem.presPinViewBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
+                } else {
+                    activeItem.presPinViewX = targetDoc._panX;
+                    activeItem.presPinViewY = targetDoc._panY;
+                    activeItem.presPinViewScale = targetDoc._viewScale;
+                }
         }
-
-        activeItem.presX = NumCast(targetDoc.x);
-        activeItem.presY = NumCast(targetDoc.y);
-        activeItem.presRot = NumCast(targetDoc.jitterRotation);
-        activeItem.presWidth = NumCast(targetDoc.width);
-        activeItem.presHeight = NumCast(targetDoc.height);
     };
 
     @computed get recordingIsInOverlay() {
@@ -506,16 +523,23 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         {/* <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.transition}</div></Tooltip> */}
                         {/* <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.duration}</div></Tooltip> */}
                         <div className="presItem-slideButtons">
-                            <Tooltip title={<div className="dash-tooltip">Update view</div>}>
-                                <div className="slideButton" onClick={() => this.updateView(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinView ? 'flex' : 'none' }}>
-                                    V
+                            <Tooltip title={<div className="dash-tooltip">Update captured doc layout</div>}>
+                                <div className="slideButton" onClick={() => this.updateCapturedContainerLayout(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinLayout ? 'flex' : 'none' }}>
+                                    L
                                 </div>
                             </Tooltip>
-                            {!Doc.noviceMode && <Tooltip title={<div className="dash-tooltip">{this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}</div>}>
-                                <div className="slideButton" onClick={e => (this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}>
-                                    <FontAwesomeIcon icon={`video${this.recordingIsInOverlay ? '-slash' : ''}`} onPointerDown={e => e.stopPropagation()} />
+                            <Tooltip title={<div className="dash-tooltip">Update captured doc content</div>}>
+                                <div className="slideButton" onClick={() => this.updateCapturedViewContents(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinData || activeItem.presPinView ? 'flex' : 'none' }}>
+                                    C
                                 </div>
-                            </Tooltip>}
+                            </Tooltip>
+                            {!Doc.noviceMode && (
+                                <Tooltip title={<div className="dash-tooltip">{this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}</div>}>
+                                    <div className="slideButton" onClick={e => (this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}>
+                                        <FontAwesomeIcon icon={`video${this.recordingIsInOverlay ? '-slash' : ''}`} onPointerDown={e => e.stopPropagation()} />
+                                    </div>
+                                </Tooltip>
+                            )}
                             <Tooltip title={<div className="dash-tooltip">{activeItem.groupWithUp ? 'Ungroup' : 'Group with up'}</div>}>
                                 <div
                                     className="slideButton"
-- 
cgit v1.2.3-70-g09d2

