aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-08-24 11:16:46 -0400
committerbobzel <zzzman@gmail.com>2022-08-24 11:16:46 -0400
commit542a057edbdd4661cfb5ef5d07058aa93b47a113 (patch)
tree64b16cbb37657dfa3291c932d283865ed5201d33 /src
parent1b7c0f466d02feddcaafce2fc9877126f6886a31 (diff)
cleaned up some of the pin with view code. added a pin button to menu bar when tab is selected to avoid needing to use context menu
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts5
-rw-r--r--src/client/util/SelectionManager.ts3
-rw-r--r--src/client/views/collections/CollectionMenu.tsx44
-rw-r--r--src/client/views/collections/TabDocView.tsx39
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx3
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx96
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx4
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx358
8 files changed, 124 insertions, 428 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 17d58595c..99a8c895f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -267,7 +267,7 @@ export class CurrentUserUtils {
{key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }},
// {key: "DataViz", creator: opts => Docs.Create.DataVizDocument(opts), opts: { _width: 300, _height: 300 }},
{key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _autoHeight: true,}},
- {key: "Presentation",creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 500, _viewType: CollectionViewType.Stacking, targetDropAction: "alias" as any, _chromeHidden: true, boxShadow: "0 0" }},
+ {key: "Presentation",creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 500, _viewType: CollectionViewType.Stacking, targetDropAction: "alias" as any, treeViewHideTitle: true, _chromeHidden: true, boxShadow: "0 0" }},
{key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _backgroundGridShow: true, }},
{key: "Slide", creator: opts => Docs.Create.TreeDocument([], opts), opts: { _width: 300, _height: 200, _viewType: CollectionViewType.Tree,
treeViewHasOverlay: true, _fontSize: "20px", _autoHeight: true,
@@ -675,8 +675,9 @@ 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: "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: "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_)'}},
{ title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, funcs: {hidden: '!SelectionManager_selectedDocType()'}, ignoreClick: true, width: 20, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}}, // Only when a document is selected
{ title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, funcs: {hidden: '!SelectionManager_selectedDocType()'}, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}},
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 1c84af94a..7a555d5f8 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -101,6 +101,9 @@ export namespace SelectionManager {
}
}
ScriptingGlobals.add(function SelectionManager_selectedDocType(docType?: DocumentType, colType?: CollectionViewType, checkContext?: boolean) {
+ if (colType === ('tab' as any)) {
+ return SelectionManager.Views().lastElement()?.props.renderDepth === 0;
+ }
let selected = (sel => (checkContext ? DocCast(sel?.context) : sel))(SelectionManager.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement());
return docType ? selected?.type === docType : colType ? selected?.viewType === colType : true;
});
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index eb55650e4..0dc30e0fd 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -587,49 +587,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
}
@undoBatch
- @action
- pinWithView = (targetDoc: Opt<Doc>) => {
- if (targetDoc) {
- TabDocView.PinDoc(targetDoc);
- const presArray: Doc[] = PresBox.Instance?.sortArray();
- const size: number = PresBox.Instance?._selectedArray.size;
- const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
- const activeDoc = presSelected ? PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.indexOf(presSelected) + 1] : PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1];
- if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking || targetDoc._viewType === CollectionViewType.NoteTaking) {
- const scroll = targetDoc._scrollTop;
- activeDoc.presPinView = true;
- activeDoc.presPinViewScroll = scroll;
- } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.MAP) {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeDoc.presPinView = true;
- activeDoc.presPinViewX = x;
- activeDoc.presPinViewY = y;
- activeDoc.presPinViewScale = scale;
- } else if (targetDoc.type === DocumentType.VID) {
- activeDoc.presPinView = true;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const width = targetDoc._clipWidth;
- activeDoc.presPinClipWidth = width;
- activeDoc.presPinView = true;
- }
- }
- };
-
- @computed
- get pinWithViewButton() {
- const presPinWithViewIcon = <img src={`/assets/pinWithView.png`} style={{ margin: 'auto', width: 19 }} />;
- return !this.selectedDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">{'Pin with current view'}</div>} placement="top">
- <button className="antimodeMenu-button" style={{ justifyContent: 'center' }} onClick={() => this.pinWithView(this.selectedDoc)}>
- {presPinWithViewIcon}
- </button>
- </Tooltip>
- );
- }
-
- @undoBatch
onAlias = () => {
if (this.selectedDoc && this.selectedDocumentView) {
// const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true);
@@ -722,7 +679,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
{this.aliasButton}
{/* {this.pinButton} */}
{this.toggleOverlayButton}
- {this.pinWithViewButton}
<div className="collectionMenu-divider" key="divider2"></div>
{this.subChrome}
<div className="collectionMenu-divider" key="divider3"></div>
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index e147f34d2..73574bdb3 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -242,43 +242,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
const size: number = PresBox.Instance?._selectedArray.size;
const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
const duration = NumCast(doc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], null);
- // If pinWithView option set then update scale and x / y props of slide
- if (pinProps?.pinWithView) {
- const viewProps = pinProps.pinWithView;
- pinDoc.presPinView = true;
- pinDoc.presPinViewX = viewProps.bounds.left + viewProps.bounds.width / 2;
- pinDoc.presPinViewY = viewProps.bounds.top + viewProps.bounds.height / 2;
- pinDoc.presPinViewScale = viewProps.scale;
- pinDoc.contentBounds = new List<number>([viewProps.bounds.left, viewProps.bounds.top, viewProps.bounds.left + viewProps.bounds.width, viewProps.bounds.top + viewProps.bounds.height]);
- }
- if (pinProps?.pinDocView) {
- const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(pinDoc.type as any) || pinDoc._viewType === CollectionViewType.Stacking;
- const pannable: boolean = (pinDoc.type === DocumentType.COL && doc._viewType === CollectionViewType.Freeform) || doc.type === DocumentType.IMG;
- if (scrollable) {
- const scroll = doc._scrollTop;
- pinDoc.presPinView = true;
- pinDoc.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(doc.type as any)) {
- pinDoc.presPinView = true;
- pinDoc.presStartTime = doc._currentTimecode;
- pinDoc.presEndTime = NumCast(doc._currentTimecode) + 0.1;
- } else if (pannable) {
- pinDoc.presPinView = true;
- pinDoc.presPinViewX = pinDoc._panX;
- pinDoc.presPinViewY = pinDoc._panY;
- pinDoc.presPinViewScale = pinDoc._viewScale;
- const pw = NumCast(pinProps.panelWidth);
- const ph = NumCast(pinProps.panelHeight);
- const ps = NumCast(pinDoc._viewScale);
- if (pw && ph && ps) {
- pinDoc.contentBounds = new List<number>([NumCast(pinDoc.panX) - pw / 2 / ps, NumCast(pinDoc.panY) - ph / 2 / ps, NumCast(pinDoc.panX) + pw / 2 / ps, NumCast(pinDoc.panY) + ph / 2 / ps]);
- }
- } else if (doc.type === DocumentType.COMPARISON) {
- const width = doc._clipWidth;
- pinDoc.presPinClipWidth = width;
- pinDoc.presPinView = true;
- }
- }
+
+ PresBox.pinDocView(pinDoc, pinProps);
pinDoc.onClick = ScriptField.MakeFunction('navigateToDoc(self.presentationTargetDoc, self)');
Doc.AddDocToList(curPres, 'data', pinDoc, presSelected);
if (!pinProps?.audioRange && duration !== undefined) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 03beaf65e..052cbd3bb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -2213,3 +2213,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() }));
+});
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index fc5bf86f4..c72b5ca9b 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -254,16 +254,13 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
const script = ScriptCast(this.rootDoc.script);
- if (!script) {
- return null;
- }
let noviceList: string[] = [];
let text: string | undefined;
let dropdown = true;
let icon: IconProp = 'caret-down';
try {
- if (script.script.originalScript.startsWith('setView')) {
+ if (script?.script.originalScript.startsWith('setView')) {
const selected = SelectionManager.Docs().lastElement();
if (selected) {
if (StrCast(selected.type) === DocumentType.COL) {
@@ -279,7 +276,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
text = 'User Default';
}
noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
- } else if (script.script.originalScript.startsWith('setFont')) {
+ } else if (script?.script.originalScript.startsWith('setFont')) {
const editorView = RichTextMenu.Instance?.TextView?.EditorView;
text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
noviceList = ['Roboto', 'Times New Roman', 'Arial', 'Georgia', 'Comic Sans MS', 'Tahoma', 'Impact', 'Crimson Text'];
@@ -289,11 +286,9 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
}
// Get items to place into the list
- const list = this.buttonList.map(value => {
- if (Doc.noviceMode && !noviceList.includes(value)) {
- return;
- }
- return (
+ const list = this.buttonList
+ .filter(value => !Doc.noviceMode || noviceList.includes(value))
+ .map(value => (
<div
className="list-item"
key={`${value}`}
@@ -304,8 +299,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
onClick={() => script.script.run({ value }).result}>
{value[0].toUpperCase() + value.slice(1)}
</div>
- );
- });
+ ));
const label =
!this.label || !FontIconBox.GetShowLabels() ? null : (
@@ -451,7 +445,6 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
@computed get defaultButton() {
const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const active: string = StrCast(this.rootDoc.dropDownOpen);
return (
<div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu} style={{ backgroundColor: 'transparent', borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
<div className="menuButton-wrap">
@@ -487,89 +480,50 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
render() {
const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const label =
- !this.label || !FontIconBox.GetShowLabels() ? null : (
- <div className="fontIconBox-label" style={{ color, backgroundColor }}>
- {this.label}
- </div>
- );
-
- const menuLabel =
+ const label = (noBackground: boolean = false) =>
!this.label || !FontIconBox.GetShowLabels() ? null : (
- <div className="fontIconBox-label" style={{ color, backgroundColor: 'transparent' }}>
+ <div className="fontIconBox-label" style={{ color, backgroundColor: noBackground ? 'transparent' : backgroundColor }}>
{this.label}
</div>
);
-
// TODO:glr Add label of button type
- let button: JSX.Element | null = this.defaultButton;
+ let button: JSX.Element = this.defaultButton;
+ // prettier-ignore
switch (this.type) {
- case ButtonType.TextButton:
- button = (
+ case ButtonType.DropdownList: return this.dropdownListButton;
+ case ButtonType.ColorButton: return this.colorButton;
+ case ButtonType.NumberButton: return this.numberButton;
+ case ButtonType.EditableText: return this.editableText;
+ case ButtonType.DropdownButton: button = this.dropdownButton; break;
+ case ButtonType.ToggleButton: button = this.toggleButton; break;
+ case ButtonType.TextButton: button = (
<div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
{this.Icon(color)}
{StrCast(this.rootDoc.buttonText) ? <div className="button-text">{StrCast(this.rootDoc.buttonText)}</div> : null}
- {label}
- </div>
- );
- // button = <TextButton {...buttonProps}></TextButton>
- break;
- case ButtonType.EditableText:
- button = this.editableText;
- break;
- case ButtonType.NumberButton:
- button = this.numberButton;
- break;
- case ButtonType.DropdownButton:
- button = this.dropdownButton;
- break;
- case ButtonType.DropdownList:
- button = this.dropdownListButton;
- break;
- case ButtonType.ColorButton:
- button = this.colorButton;
- break;
- case ButtonType.ToolButton:
- button = (
- <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? 'Label' : '')}`} style={{ opacity: 1, backgroundColor, color }}>
- {this.Icon(color)}
- {label}
+ {label()}
</div>
);
break;
- case ButtonType.ToggleButton:
- button = this.toggleButton;
- // button = <ToggleButton {...buttonProps}></ToggleButton>
- break;
case ButtonType.ClickButton:
- button = (
- <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? 'Label' : '')}`} style={{ color, backgroundColor, opacity: 1 }}>
+ case ButtonType.ToolButton: button = (
+ <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? 'Label' : '')}`} style={{ backgroundColor, color, opacity: 1 }}>
{this.Icon(color)}
- {label}
+ {label()}
</div>
);
break;
- case ButtonType.MenuButton:
- button = (
+ case ButtonType.MenuButton: button = (
<div className={`menuButton ${this.type}`} style={{ color, backgroundColor }}>
{this.Icon(color)}
- {menuLabel}
+ {label(true)}
<FontIconBadge value={Cast(this.Document.badgeValue, 'string', null)} />
</div>
);
break;
- default:
- break;
}
- const retval =
- !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? (
- button
- ) : button !== null ? (
- <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>{button}</Tooltip>
- ) : null;
- return retval;
+ return !this.layoutDoc.toolTip ? button : <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>{button}</Tooltip>;
}
}
@@ -698,7 +652,7 @@ ScriptingGlobals.add(function setFontHighlight(color?: string, checkResult?: boo
ScriptingGlobals.add(function setFontSize(size: string | number, checkResult?: boolean) {
const editorView = RichTextMenu.Instance?.TextView?.EditorView;
if (checkResult) {
- return RichTextMenu.Instance.fontSize.replace('px', '');
+ return RichTextMenu.Instance?.fontSize.replace('px', '');
}
if (typeof size === 'number') size = size.toString();
if (size && Number(size).toString() === size) size += 'px';
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 2a77210ae..0cbe60c0c 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -16,7 +16,7 @@ import { SelectionManager } from '../../../util/SelectionManager';
import { undoBatch, UndoManager } from '../../../util/UndoManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
import { FieldViewProps } from '../FieldView';
-import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox';
+import { FormattedTextBox } from './FormattedTextBox';
import { updateBullets } from './ProsemirrorExampleTransfer';
import './RichTextMenu.scss';
import { schema } from './schema_rts';
@@ -29,7 +29,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
private _linkToRef = React.createRef<HTMLInputElement>();
@observable public view?: EditorView;
- public editorProps: (FieldViewProps & FormattedTextBoxProps) | undefined;
+ public editorProps: FieldViewProps | undefined;
public _brushMap: Map<string, Set<Mark>> = new Map();
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 05e09361b..eb40089ec 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -358,20 +358,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (bestTarget) this._navTimer = PresBox.navigateToDoc(bestTarget, activeItem, false);
};
+ static pinDataTypes(target: Doc) {
+ const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(target.type as any) || target._viewType === CollectionViewType.Stacking;
+ 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);
+ return { scrollable, pannable, temporal, clippable };
+ }
// navigates to the bestTarget document by making sure it is on screen,
// then it applies the view specs stored in activeItem to
@action
static navigateToDoc(bestTarget: Doc, activeItem: Doc, jumpToDoc: boolean) {
- if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) {
- bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
- bestTarget._scrollTop = activeItem.presPinViewScroll;
- } else if (bestTarget.type === DocumentType.COMPARISON) {
- bestTarget._clipWidth = activeItem.presPinClipWidth;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(bestTarget.type as any)) {
- bestTarget._currentTimecode = activeItem.presStartTime;
- } else {
+ bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
+ const { scrollable, pannable, temporal, clippable } = this.pinDataTypes(bestTarget);
+ if (clippable) bestTarget._clipWidth = activeItem.presPinClipWidth;
+ if (temporal) bestTarget._currentTimecode = activeItem.presStartTime;
+ if (scrollable) bestTarget._scrollTop = activeItem.presPinViewScroll;
+ if (pannable) {
const contentBounds = Cast(activeItem.contentBounds, listSpec('number'));
- bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
if (contentBounds) {
bestTarget._panX = (contentBounds[0] + contentBounds[2]) / 2;
bestTarget._panY = (contentBounds[1] + contentBounds[3]) / 2;
@@ -388,6 +392,43 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return setTimeout(() => (bestTarget._viewTransition = undefined), activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
}
+ /// copies values from the targetDoc (which is the prototype of the pinDoc) to
+ /// reserved fields on the pinDoc so that those values can be restored to the
+ /// target doc when navigating to it.
+ @action
+ static pinDocView(pinDoc: Doc, pinProps: PinProps | undefined) {
+ 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.presPinViewScale = pinProps.pinWithView.scale;
+ pinDoc.contentBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
+ }
+ if (pinProps?.pinDocView) {
+ const { scrollable, pannable, temporal, clippable } = this.pinDataTypes(pinDoc);
+ pinDoc.presPinView = (pinProps?.pinWithView ? true : false) || scrollable || temporal || pannable || clippable;
+
+ if (scrollable) pinDoc.presPinViewScroll = pinDoc._scrollTop;
+ else if (clippable) pinDoc.presPinClipWidth = pinDoc._clipWidth;
+ else if (temporal) pinDoc.presEndTime = NumCast((pinDoc.presStartTime = pinDoc._currentTimecode)) + 0.1;
+ else if (pannable) {
+ 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);
+ if (pw && ph && ps) {
+ pinDoc.contentBounds = 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;
+ }
+ }
+ }
+
/**
* This method makes sure that cursor navigates to the element that
* has the option open and last in the group.
@@ -1540,26 +1581,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
- @computed get effectDirection(): string {
- let effect = '';
+ @computed get effectDirection() {
+ // prettier-ignore
switch (this.activeItem.presEffectDirection) {
- case 'left':
- effect = 'Enter from left';
- break;
- case 'right':
- effect = 'Enter from right';
- break;
- case 'top':
- effect = 'Enter from top';
- break;
- case 'bottom':
- effect = 'Enter from bottom';
- break;
- default:
- effect = 'Enter from center';
- break;
+ case 'left': return 'Enter from left';
+ case 'right': return 'Enter from right';
+ case 'top': return'Enter from top';
+ case 'bottom': return 'Enter from bottom';
}
- return effect;
+ return 'Enter from center';
}
@undoBatch
@@ -1582,179 +1612,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
});
};
- @computed get presPinViewOptionsDropdown() {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: 'auto', width: 16, filter: 'invert(1)' }} />;
- return (
- <>
- {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : null}
- <div className="ribbon-doubleButton">
- <Tooltip
- title={
- <>
- <div className="dash-tooltip">{activeItem.presPinView ? 'Turn off pin with view' : 'Turn on pin with view'}</div>
- </>
- }>
- <div
- className="ribbon-toggle"
- style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? Colors.LIGHT_BLUE : '' }}
- onClick={() => {
- activeItem.presPinView = !activeItem.presPinView;
- targetDoc.presPinView = activeItem.presPinView;
- if (activeItem.presPinView) {
- if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
- const scroll = targetDoc._scrollTop;
- activeItem.presPinView = true;
- activeItem.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
- activeItem.presStartTime = targetDoc._currentTimecode;
- activeItem.presEndTime = NumCast(targetDoc._currentTimecode) + 0.1;
- } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeItem.presPinView = true;
- activeItem.presPinViewX = x;
- activeItem.presPinViewY = y;
- activeItem.presPinViewScale = scale;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const width = targetDoc._clipWidth;
- activeItem.presPinClipWidth = width;
- activeItem.presPinView = true;
- }
- }
- }}>
- {presPinWithViewIcon}
- </div>
- </Tooltip>
- {activeItem.presPinView ? (
- <Tooltip
- title={
- <>
- <div className="dash-tooltip">{'Update the pinned view with the view of the selected document'}</div>
- </>
- }>
- <div
- className="ribbon-button"
- onClick={() => {
- if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
- const scroll = targetDoc._scrollTop;
- activeItem.presPinViewScroll = scroll;
- } else if ([DocumentType.AUDIO, DocumentType.VID].includes(targetDoc.type as any)) {
- activeItem.presStartTime = targetDoc._currentTimecode;
- activeItem.presStartTime = NumCast(targetDoc._currentTimecode) + 0.1;
- } else if (targetDoc.type === DocumentType.COMPARISON) {
- const clipWidth = targetDoc._clipWidth;
- activeItem.presPinClipWidth = clipWidth;
- } else {
- const x = targetDoc._panX;
- const y = targetDoc._panY;
- const scale = targetDoc._viewScale;
- activeItem.presPinViewX = x;
- activeItem.presPinViewY = y;
- activeItem.presPinViewScale = scale;
- }
- }}>
- Update
- </div>
- </Tooltip>
- ) : null}
- </div>
- </>
- );
- }
-
- @computed get panOptionsDropdown() {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- return (
- <>
- {this.panable ? (
- <div style={{ display: activeItem.presPinView ? 'block' : 'none' }}>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Pan X</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input
- className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number"
- value={NumCast(activeItem.presPinViewX)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
- const val = e.target.value;
- activeItem.presPinViewX = Number(val);
- })}
- />
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Pan Y</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input
- className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number"
- value={NumCast(activeItem.presPinViewY)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
- const val = e.target.value;
- activeItem.presPinViewY = Number(val);
- })}
- />
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Scale</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input
- className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number"
- value={NumCast(activeItem.presPinViewScale)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
- const val = e.target.value;
- activeItem.presPinViewScale = Number(val);
- })}
- />
- </div>
- </div>
- </div>
- ) : null}
- </>
- );
- }
-
- @computed get scrollOptionsDropdown() {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- return (
- <>
- {this.scrollable ? (
- <div style={{ display: activeItem.presPinView ? 'block' : 'none' }}>
- <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
- <div className="presBox-subheading">Scroll</div>
- <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
- <input
- className="presBox-input"
- style={{ textAlign: 'left', width: 50 }}
- type="number"
- value={NumCast(activeItem.presPinViewScroll)}
- onKeyDown={e => e.stopPropagation()}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
- const val = e.target.value;
- activeItem.presPinViewScroll = Number(val);
- })}
- />
- </div>
- </div>
- </div>
- ) : null}
- </>
- );
- }
-
@computed get mediaStopSlides() {
const activeItem: Doc = this.activeItem;
const list = this.childDocs.map((doc, i) => {
@@ -2102,42 +1959,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
createTemplate = (layout: string, input?: string) => {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- let x = 0;
- let y = 0;
- if (activeItem && targetDoc) {
- x = NumCast(targetDoc.x);
- y = NumCast(targetDoc.y) + NumCast(targetDoc._height) + 20;
- }
- let doc = undefined;
- const title = Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 58, _fontSize: '24pt' });
- const subtitle = Docs.Create.TextDocument('Click to change subtitle', { title: 'Slide subtitle', _width: 380, _height: 50, x: 10, y: 118, _fontSize: '16pt' });
- const header = Docs.Create.TextDocument('Click to change header', { title: 'Slide header', _width: 380, _height: 65, x: 10, y: 80, _fontSize: '20pt' });
- const contentTitle = Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 10, _fontSize: '24pt' });
- const content = Docs.Create.TextDocument('Click to change text', { title: 'Slide text', _width: 380, _height: 145, x: 10, y: 70, _fontSize: '14pt' });
- const content1 = Docs.Create.TextDocument('Click to change text', { title: 'Column 1', _width: 185, _height: 140, x: 10, y: 80, _fontSize: '14pt' });
- const content2 = Docs.Create.TextDocument('Click to change text', { title: 'Column 2', _width: 185, _height: 140, x: 205, y: 80, _fontSize: '14pt' });
+ const x = this.activeItem && this.targetDoc ? NumCast(this.targetDoc.x) : 0;
+ const y = this.activeItem && this.targetDoc ? NumCast(this.targetDoc.y) + NumCast(this.targetDoc._height) + 20 : 0;
+ const title = () => Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 58, _fontSize: '24pt' });
+ const subtitle = () => Docs.Create.TextDocument('Click to change subtitle', { title: 'Slide subtitle', _width: 380, _height: 50, x: 10, y: 118, _fontSize: '16pt' });
+ const header = () => Docs.Create.TextDocument('Click to change header', { title: 'Slide header', _width: 380, _height: 65, x: 10, y: 80, _fontSize: '20pt' });
+ const contentTitle = () => Docs.Create.TextDocument('Click to change title', { title: 'Slide title', _width: 380, _height: 60, x: 10, y: 10, _fontSize: '24pt' });
+ const content = () => Docs.Create.TextDocument('Click to change text', { title: 'Slide text', _width: 380, _height: 145, x: 10, y: 70, _fontSize: '14pt' });
+ const content1 = () => Docs.Create.TextDocument('Click to change text', { title: 'Column 1', _width: 185, _height: 140, x: 10, y: 80, _fontSize: '14pt' });
+ const content2 = () => Docs.Create.TextDocument('Click to change text', { title: 'Column 2', _width: 185, _height: 140, x: 205, y: 80, _fontSize: '14pt' });
+ // prettier-ignore
switch (layout) {
- case 'blank':
- doc = Docs.Create.FreeformDocument([], { title: input ? input : 'Blank slide', _width: 400, _height: 225, x: x, y: y });
- break;
- case 'title':
- doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : 'Title slide', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
- break;
- case 'header':
- doc = Docs.Create.FreeformDocument([header], { title: input ? input : 'Section header', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
- break;
- case 'content':
- doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : 'Title and content', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
- break;
- case 'twoColumns':
- doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _fitContentsToBox: true, x: x, y: y });
- break;
- default:
- break;
+ case 'blank': return Docs.Create.FreeformDocument([], { title: input ? input : 'Blank slide', _width: 400, _height: 225, x, y });
+ case 'title': return Docs.Create.FreeformDocument([title(), subtitle()], { title: input ? input : 'Title slide', _width: 400, _height: 225, _fitContentsToBox: true, x, y });
+ case 'header': return Docs.Create.FreeformDocument([header()], { title: input ? input : 'Section header', _width: 400, _height: 225, _fitContentsToBox: true, x, y });
+ case 'content': return Docs.Create.FreeformDocument([contentTitle(), content()], { title: input ? input : 'Title and content', _width: 400, _height: 225, _fitContentsToBox: true, x, y });
+ case 'twoColumns': return Docs.Create.FreeformDocument([contentTitle(), content1(), content2()], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _fitContentsToBox: true, x, y })
}
- return doc;
};
// Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
@@ -2201,42 +2039,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
/**
* Returns the collection type as a string for headers
*/
- @computed get stringType(): string {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- let type: string = '';
- if (activeItem) {
- switch (targetDoc.type) {
- case DocumentType.PDF:
- type = 'PDF';
- break;
- case DocumentType.RTF:
- type = 'Text node';
- break;
- case DocumentType.COL:
- type = 'Collection';
- break;
- case DocumentType.AUDIO:
- type = 'Audio';
- break;
- case DocumentType.VID:
- type = 'Video';
- break;
- case DocumentType.IMG:
- type = 'Image';
- break;
- case DocumentType.WEB:
- type = 'Web page';
- break;
- case DocumentType.MAP:
- type = 'Map';
- break;
- default:
- type = 'Other node';
- break;
+ @computed get stringType() {
+ if (this.activeItem) {
+ // prettier-ignore
+ switch (this.targetDoc.type) {
+ case DocumentType.PDF: return 'PDF';
+ case DocumentType.RTF: return 'Text node';
+ case DocumentType.COL: return 'Collection';
+ case DocumentType.AUDIO: return 'Audio';
+ case DocumentType.VID: return 'Video';
+ case DocumentType.IMG: return 'Image';
+ case DocumentType.WEB: return 'Web page';
+ case DocumentType.MAP: return 'Map';
+ default: return 'Other node';
}
}
- return type;
+ return '';
}
@observable private openActiveColorPicker: boolean = false;
@@ -2845,10 +2663,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
case DocumentType.PDF || DocumentType.RTF || DocumentType.WEB:
this.updateList(activeItem.frameList);
break;
- case DocumentType.COL:
- break;
- default:
- break;
}
};