aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/trails
diff options
context:
space:
mode:
authorbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-01-19 14:33:22 -0500
committerbrynnchernosky <56202540+brynnchernosky@users.noreply.github.com>2023-01-19 14:33:22 -0500
commit0ef7050b0792ce183c7d5cda637cb79b7a92b704 (patch)
treed1dca8f09ddc2954c2ce88439172aeded672c0b6 /src/client/views/nodes/trails
parentceb338752aacc383c97a0e3a9b608365a1cf39b6 (diff)
parentd5f796b433d7e72130d4109a3775347ccb10c454 (diff)
Merge branch 'master' of github.com:brown-dash/Dash-Web into master
Diffstat (limited to 'src/client/views/nodes/trails')
-rw-r--r--src/client/views/nodes/trails/PresBox.scss26
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx1443
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx17
-rw-r--r--src/client/views/nodes/trails/PresEnums.ts5
4 files changed, 558 insertions, 933 deletions
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index 4d60a02f1..fd202590e 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -938,14 +938,19 @@
min-width: 15px;
max-width: 100px;
left: 8px;
+ margin: auto;
+ margin-left: unset;
+ height: 100%;
}
.presBox-presentPanel {
display: flex;
justify-self: end;
width: 100%;
- max-width: 300px;
- min-width: 150px;
+ margin: auto;
+ margin-right: unset;
+ height: 100%;
+ position: relative;
}
select {
@@ -955,7 +960,7 @@
.presBox-button {
cursor: pointer;
- height: 25px;
+ //height: 100%;
border-radius: 5px;
display: none;
justify-content: center;
@@ -986,6 +991,9 @@
width: max-content;
position: absolute;
right: 10px;
+ margin: auto;
+ margin-right: unset;
+ height: 100%;
.present-icon {
margin-right: 7px;
@@ -999,9 +1007,16 @@
position: relative;
display: inline-block;
left: 8px;
+ margin: auto;
+ margin-left: unset;
}
}
+.presBox-buttons.inOverlay {
+ padding-top: unset;
+ padding-bottom: unset;
+}
+
.presBox-backward,
.presBox-forward {
width: 25px;
@@ -1052,6 +1067,8 @@
font-size: 30px;
position: absolute;
min-width: 50px;
+ margin: auto;
+ margin-left: unset;
}
}
@@ -1087,13 +1104,12 @@
color: $white;
border-radius: 5px;
grid-template-rows: 100%;
- height: 25;
+ height: 100%;
width: max-content;
min-width: max-content;
justify-content: space-evenly;
align-items: center;
display: flex;
- position: absolute;
transition: all 0.2s;
.presPanel-button-text {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 4e8aed8a6..855a7f171 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,18 +1,18 @@
import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
-import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableSet, observe, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { ColorState, SketchPicker } from 'react-color';
-import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
-import { Doc, DocListCast, FieldResult, StrListCast } from '../../../../fields/Doc';
+import { AnimationSym, Doc, DocListCast, FieldResult, HighlightSym, Opt, StrListCast } from '../../../../fields/Doc';
import { Copy, Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
import { ObjectField } from '../../../../fields/ObjectField';
import { listSpec } from '../../../../fields/Schema';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, returnOne, returnTrue, setupMoveUpEvents, StopEvent } from '../../../../Utils';
+import { AudioField } from '../../../../fields/URLField';
+import { emptyFunction, emptyPath, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { Docs } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
@@ -22,25 +22,40 @@ import { SelectionManager } from '../../../util/SelectionManager';
import { SettingsManager } from '../../../util/SettingsManager';
import { undoBatch, UndoManager } from '../../../util/UndoManager';
import { CollectionDockingView } from '../../collections/CollectionDockingView';
-import { CollectionFreeFormView, MarqueeViewBounds } from '../../collections/collectionFreeForm';
+import { CollectionFreeFormView, computeTimelineLayout, MarqueeViewBounds } from '../../collections/collectionFreeForm';
import { CollectionView } from '../../collections/CollectionView';
import { TabDocView } from '../../collections/TabDocView';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { LightboxView } from '../../LightboxView';
import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentView';
+import { DocFocusOptions, DocumentView, OpenWhere, OpenWhereMod } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
import { ScriptingBox } from '../ScriptingBox';
import './PresBox.scss';
-import { PresEffect, PresMovement, PresStatus } from './PresEnums';
+import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
+import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline';
+const { Howl } = require('howler');
export interface PinProps {
audioRange?: boolean;
activeFrame?: number;
+ currentFrame?: number;
hidePresBox?: boolean;
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)
+ pinAudioPlay?: boolean; // pin audio annotation
+ pinData?: {
+ scrollable?: boolean | undefined;
+ pannable?: boolean | undefined;
+ temporal?: boolean | undefined;
+ clippable?: boolean | undefined;
+ dataview?: boolean | undefined;
+ textview?: boolean | undefined;
+ poslayoutview?: boolean | undefined;
+ dataannos?: boolean | undefined;
+ };
}
@observer
@@ -49,39 +64,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return FieldView.LayoutString(PresBox, fieldKey);
}
- /**
- * returns an entrance animation effect function to wrap a JSX element
- * @param presEffectDoc presentation effects document that specifies the animation effect parameters
- * @returns a function that will wrap a JSX animation element wrapping any JSX element
- */
- public static AnimationEffect(renderDoc: JSX.Element, presEffectDoc: Doc) {
- const effectProps = {
- left: presEffectDoc.presEffectDirection === PresEffect.Left,
- right: presEffectDoc.presEffectDirection === PresEffect.Right,
- top: presEffectDoc.presEffectDirection === PresEffect.Top,
- bottom: presEffectDoc.presEffectDirection === PresEffect.Bottom,
- opposite: true,
- delay: NumCast(presEffectDoc.presTransition),
- };
- //prettier-ignore
- switch (StrCast(presEffectDoc.presEffect)) {
- default:
- case PresEffect.None: return renderDoc;
- case PresEffect.Zoom: return <Zoom {...effectProps}>{renderDoc}</Zoom>;
- case PresEffect.Fade: return <Fade {...effectProps}>{renderDoc}</Fade>;
- case PresEffect.Flip: return <Flip {...effectProps}>{renderDoc}</Flip>;
- case PresEffect.Rotate: return <Rotate {...effectProps}>{renderDoc}</Rotate>;
- case PresEffect.Bounce: return <Bounce {...effectProps}>{renderDoc}</Bounce>;
- case PresEffect.Roll: return <Roll {...effectProps}>{renderDoc}</Roll>;
- case PresEffect.Lightspeed: return <LightSpeed {...effectProps}>{renderDoc}</LightSpeed>;
- }
- }
-
private _disposers: { [name: string]: IReactionDisposer } = {};
public selectedArray = new ObservableSet<Doc>();
@observable public static Instance: PresBox;
- @observable static startMarquee: boolean = false; // onclick "+ new slide" in presentation mode, set as true, then when marquee selection finish, onPointerUp automatically triggers PinWithView
@observable _isChildActive = false;
@observable _moveOnFromAudio: boolean = true;
@@ -93,7 +79,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable _expandBoolean: boolean = false;
@observable _transitionTools: boolean = false;
@observable _newDocumentTools: boolean = false;
- @observable _progressivizeTools: boolean = false;
@observable _openMovementDropdown: boolean = false;
@observable _openEffectDropdown: boolean = false;
@observable _presentTools: boolean = false;
@@ -125,7 +110,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return Cast(this.activeItem?.presentationTargetDoc, Doc, null);
}
@computed get scrollable() {
- if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true;
+ if ([DocumentType.PDF, DocumentType.WEB, DocumentType.RTF].includes(this.targetDoc.type as DocumentType) || this.targetDoc._viewType === CollectionViewType.Stacking) return true;
return false;
}
@computed get panable() {
@@ -151,6 +136,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
componentWillUnmount() {
this._unmounting = true;
+ if (this._presTimer) clearTimeout(this._presTimer);
document.removeEventListener('keydown', PresBox.keyEventsWrapper, true);
this.resetPresentation();
// Turn of progressivize editors
@@ -158,7 +144,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
Object.values(this._disposers).forEach(disposer => disposer?.());
}
- @action
componentDidMount() {
this._disposers.keyboard = reaction(
() => this.selectedDoc,
@@ -182,10 +167,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
this.props.setContentView?.(this);
this._unmounting = false;
- this.rootDoc._forceRenderEngine = 'timeline';
- this.layoutDoc.presStatus = PresStatus.Edit;
- this.layoutDoc._gridGap = 0;
- this.layoutDoc._yMargin = 0;
+ if (this.props.renderDepth > 0) {
+ runInAction(() => {
+ this.rootDoc._forceRenderEngine = computeTimelineLayout.name;
+ this.layoutDoc._gridGap = 0;
+ this.layoutDoc._yMargin = 0;
+ });
+ }
this.turnOffEdit(true);
this._disposers.selection = reaction(
() => SelectionManager.Views(),
@@ -199,17 +187,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
PresBox.Instance = this;
};
- // There are still other internal frames and should go through all frames before going to next slide
- nextInternalFrame = (targetDoc: Doc, activeItem: Doc) => {
- const currentFrame = Cast(targetDoc?._currentFrame, 'number', null);
- const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
- targetDoc._viewTransition = 'all 1s';
- setTimeout(() => (targetDoc._viewTransition = undefined), 1010);
- this.nextKeyframe(targetDoc, activeItem);
- if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc);
- else targetDoc.keyFrameEditing = true;
- };
-
_mediaTimer!: [NodeJS.Timeout, Doc];
// 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
startTempMedia = (targetDoc: Doc, activeItem: Doc) => {
@@ -232,38 +209,53 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// TODO: to handle child slides (entering into subtrail and exiting), also the next() and back() functions
// No more frames in current doc and next slide is defined, therefore move to next slide
nextSlide = (slideNum?: number) => {
- let nextSelected = slideNum ?? this.itemIndex + 1;
- this.gotoDocument(nextSelected, this.activeItem);
- for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
- if (this.childDocs[nextSelected].groupWithUp) {
- this.gotoDocument(nextSelected, this.activeItem, true);
- } else {
- break;
+ const nextSlideInd = slideNum ?? this.itemIndex + 1;
+ let curSlideInd = nextSlideInd;
+ const resetSelection = action(() => {
+ this.clearSelectedArray();
+ for (let i = nextSlideInd; i <= curSlideInd; i++) {
+ this.addToSelectedArray(this.childDocs[i]);
}
- }
+ });
+ CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => DocumentManager.Instance.getDocumentView(clip)?.ComponentView?.Pause?.());
+ this.clearSelectedArray();
+ const doGroupWithUp =
+ (nextSelected: number, force = false) =>
+ () => {
+ if (nextSelected < this.childDocs.length) {
+ if (force || this.childDocs[nextSelected].groupWithUp) {
+ const serial = nextSelected + 1 < this.childDocs.length && NumCast(this.childDocs[nextSelected + 1].groupWithUp) > 1;
+ if (serial) {
+ this.gotoDocument(nextSelected, this.activeItem, true, async () => {
+ const waitTime = NumCast(this.activeItem.presDuration) - NumCast(this.activeItem.presTransition);
+ await new Promise<void>(res => setTimeout(() => res(), Math.max(0, waitTime)));
+ doGroupWithUp(nextSelected + 1)();
+ });
+ } else {
+ this.gotoDocument(nextSelected, this.activeItem, undefined, resetSelection);
+ curSlideInd = this.itemIndex;
+ doGroupWithUp(nextSelected + 1)();
+ }
+ }
+ }
+ };
+ doGroupWithUp(curSlideInd, true)();
};
// Called when the user activates 'next' - to move to the next part of the pres. trail
@action
next = () => {
- const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null);
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- const lastFrame = Cast(targetDoc?.lastFrame, 'number', null);
- const curFrame = NumCast(targetDoc?._currentFrame);
- let internalFrames: boolean = false;
- if (activeItem.presProgressivize || activeItem.zoomProgressivize || targetDoc.scrollProgressivize) internalFrames = true;
- if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) {
- // Case 1: There are still other frames and should go through all frames before going to next slide
- this.nextInternalFrame(targetDoc, activeItem);
- } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
- // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
+ if (this.childDocs[this.itemIndex + 1] !== undefined) {
+ // Case 1: No more frames in current doc and next slide is defined, therefore move to next slide
const slides = DocListCast(this.rootDoc[StrCast(this.presFieldKey, 'data')]);
const curLast = this.selectedArray.size ? Math.max(...Array.from(this.selectedArray).map(d => slides.indexOf(DocCast(d)))) : this.itemIndex;
- this.nextSlide(curLast + 1);
- } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
- // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode
- this.nextSlide(0);
+ this.nextSlide(curLast + 1 === this.childDocs.length ? (this.layoutDoc.presLoop ? 0 : curLast) : curLast + 1);
+ } else {
+ if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
+ // Case 2: Last slide and presLoop is toggled ON or it is in Edit mode
+ this.nextSlide(0);
+ }
+ return 0;
}
return this.itemIndex;
};
@@ -272,29 +264,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
back = () => {
const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
const prevItem = Cast(this.childDocs[Math.max(0, this.itemIndex - 1)], Doc, null);
- const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null);
- const lastFrame = Cast(targetDoc.lastFrame, 'number', null);
- const curFrame = NumCast(targetDoc._currentFrame);
let prevSelected = this.itemIndex;
// Functionality for group with up
let didZoom = activeItem.presMovement;
for (; prevSelected > 0 && this.childDocs[Math.max(0, prevSelected - 1)].groupWithUp; prevSelected--) {
didZoom = didZoom === 'none' ? this.childDocs[prevSelected].presMovement : didZoom;
}
- if (lastFrame !== undefined && curFrame >= 1) {
- // Case 1: There are still other frames and should go through all frames before going to previous slide
- this.prevKeyframe(targetDoc, activeItem);
- } else if (activeItem && this.childDocs[this.itemIndex - 1] !== undefined) {
+ if (activeItem && this.childDocs[this.itemIndex - 1] !== undefined) {
// Case 2: There are no other frames so it should go to the previous slide
prevSelected = Math.max(0, prevSelected - 1);
this.nextSlide(prevSelected);
this.rootDoc._itemIndex = prevSelected;
- if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc._currentFrame = NumCast(prevTargetDoc.lastFrame);
} else if (this.childDocs[this.itemIndex - 1] === undefined && this.layoutDoc.presLoop) {
// Case 3: Pres loop is on so it should go to the last slide
- this.gotoDocument(this.childDocs.length - 1, activeItem);
+ this.nextSlide(this.childDocs.length - 1);
}
return this.itemIndex;
};
@@ -302,21 +286,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
//The function that is called when a document is clicked or reached through next or back.
//it'll also execute the necessary actions if presentation is playing.
@undoBatch
- public gotoDocument = action((index: number, from?: Doc, group?: boolean) => {
+ public gotoDocument = action((index: number, from?: Doc, group?: boolean, finished?: () => void) => {
Doc.UnBrushAllDocs();
-
if (index >= 0 && index < this.childDocs.length) {
this.rootDoc._itemIndex = index;
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
- if (activeItem.presActiveFrame !== undefined) {
+ const activeFrame = activeItem.presActiveFrame ?? activeItem.presCurrentFrame;
+ if (activeFrame !== undefined) {
const transTime = NumCast(activeItem.presTransition, 500);
- const context = DocCast(DocCast(activeItem.presentationTargetDoc).context);
+ const acontext = activeItem.presActiveFrame !== undefined ? DocCast(DocCast(activeItem.presentationTargetDoc).context) : DocCast(activeItem.presentationTargetDoc);
+ const context = DocCast(acontext)?.annotationOn ? DocCast(DocCast(acontext).annotationOn) : acontext;
if (context) {
- const contextView = DocumentManager.Instance.getFirstDocumentView(context);
- if (contextView?.ComponentView) {
- CollectionFreeFormDocumentView.gotoKeyframe((contextView.ComponentView as CollectionFreeFormView).childDocs.slice(), transTime);
- context._currentFrame = NumCast(activeItem.presActiveFrame);
+ const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.ComponentView as CollectionFreeFormView;
+ if (ffview?.childDocs) {
+ this._keyTimer = CollectionFreeFormDocumentView.gotoKeyframe(this._keyTimer, ffview.childDocs.slice(), transTime);
+ context._currentFrame = NumCast(activeFrame);
}
}
}
@@ -330,56 +315,91 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && activeItem.mediaStart === 'auto') {
this.startTempMedia(targetDoc, activeItem);
}
- if (targetDoc) {
- Doc.linkFollowHighlight(targetDoc.annotationOn instanceof Doc ? [targetDoc, targetDoc.annotationOn] : targetDoc);
- targetDoc && runInAction(() => (targetDoc.focusSpeed = activeItem.presMovement === PresMovement.Jump ? 0 : NumCast(activeItem.presTransition, 500)));
- setTimeout(() => (targetDoc.focusSpeed = undefined), NumCast(targetDoc.focusSpeed) + 10);
- }
- if (targetDoc?.lastFrame !== undefined) {
- targetDoc._currentFrame = 0;
- }
if (!group) this.clearSelectedArray();
this.childDocs[index] && this.addToSelectedArray(this.childDocs[index]); //Update selected array
this.turnOffEdit();
- this.navigateToActiveItem(); //Handles movement to element only when presTrail is list
+ this.navigateToActiveItem(finished); //Handles movement to element only when presTrail is list
this.onHideDocument(); //Handles hide after/before
}
});
- 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);
- const dataview = [DocumentType.INK, DocumentType.COL].includes(target.type as any) && target.activeFrame === undefined;
- const poslayoutview = [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, poslayoutview };
+ static pinDataTypes(target?: Doc): { scrollable?: boolean; pannable?: boolean; temporal?: boolean; clippable?: boolean; dataview?: boolean; textview?: boolean; poslayoutview?: boolean; dataannos?: boolean } {
+ const targetType = target?.type as any;
+ const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetType) || target?._viewType === CollectionViewType.Stacking;
+ const pannable = [DocumentType.IMG, DocumentType.PDF].includes(targetType) || (targetType === DocumentType.COL && target?._viewType === CollectionViewType.Freeform);
+ const temporal = [DocumentType.AUDIO, DocumentType.VID].includes(targetType);
+ const clippable = [DocumentType.COMPARISON].includes(targetType);
+ const dataview = [DocumentType.INK, DocumentType.COL, DocumentType.IMG].includes(targetType) && target?.activeFrame === undefined;
+ const poslayoutview = [DocumentType.COL].includes(targetType) && target?.activeFrame === undefined;
+ const textview = [DocumentType.RTF].includes(targetType) && target?.activeFrame === undefined;
+ const dataannos = false;
+ return { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview, dataannos };
}
@action
- static restoreTargetDocView(bestTarget: Doc, activeItem: Doc) {
- const transTime = NumCast(activeItem.presTransition, 500);
- const presTransitionTime = `all ${transTime}ms`;
- const { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview } = this.pinDataTypes(bestTarget);
- bestTarget._viewTransition = presTransitionTime;
- if (clippable) bestTarget._clipWidth = activeItem.presPinClipWidth;
- if (temporal) bestTarget._currentTimecode = activeItem.presStartTime;
- if (scrollable) {
- bestTarget._scrollTop = activeItem.presPinViewScroll;
- const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
- if (contentBounds) {
- const dv = DocumentManager.Instance.getDocumentView(bestTarget)?.ComponentView;
- dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] });
+ playAnnotation = (anno: AudioField) => {};
+ @action
+ static restoreTargetDocView(bestTargetView: Opt<DocumentView>, pinProps: PinProps | undefined, activeItem: Doc, transTime: number, pinDataTypes = this.pinDataTypes(bestTargetView?.rootDoc)) {
+ if (!bestTargetView) return;
+ const bestTarget = bestTargetView.rootDoc;
+ let changed = false;
+ if (pinProps?.pinDocLayout) {
+ if (
+ bestTarget.x !== NumCast(activeItem.presX, NumCast(bestTarget.x)) ||
+ bestTarget.y !== NumCast(activeItem.presY, NumCast(bestTarget.y)) ||
+ bestTarget.rotation !== NumCast(activeItem.presRot, NumCast(bestTarget.rotation)) ||
+ bestTarget.width !== NumCast(activeItem.presWidth, NumCast(bestTarget.width)) ||
+ bestTarget.height !== NumCast(activeItem.presHeight, NumCast(bestTarget.height))
+ ) {
+ bestTarget._dataTransition = `all ${transTime}ms`;
+ bestTarget.x = NumCast(activeItem.presX, NumCast(bestTarget.x));
+ bestTarget.y = NumCast(activeItem.presY, NumCast(bestTarget.y));
+ bestTarget.rotation = NumCast(activeItem.presRot, NumCast(bestTarget.rotation));
+ bestTarget.width = NumCast(activeItem.presWidth, NumCast(bestTarget.width));
+ bestTarget.height = NumCast(activeItem.presHeight, NumCast(bestTarget.height));
+ setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10);
+ changed = true;
+ }
+ }
+ if (pinDataTypes.clippable) {
+ if (bestTarget._clipWidth !== activeItem.presPinClipWidth) {
+ bestTarget._clipWidth = activeItem.presPinClipWidth;
+ changed = true;
+ }
+ }
+ if (pinDataTypes.temporal) {
+ if (bestTarget._currentTimecode !== activeItem.presStartTime) {
+ bestTarget._currentTimecode = activeItem.presStartTime;
+ changed = true;
}
}
- if (dataview) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
- if (textview) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
- if (poslayoutview) {
+ if (pinDataTypes.scrollable) {
+ if (bestTarget._scrollTop !== activeItem.presPinViewScroll) {
+ bestTarget._scrollTop = activeItem.presPinViewScroll;
+ changed = true;
+ const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
+ if (contentBounds) {
+ const dv = DocumentManager.Instance.getDocumentView(bestTarget)?.ComponentView;
+ dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] });
+ }
+ }
+ }
+ if (pinDataTypes.dataannos) {
+ const fkey = Doc.LayoutFieldKey(bestTarget);
+ Doc.GetProto(bestTarget)[fkey + '-annotations'] = new List<Doc>([...DocListCast(bestTarget[fkey + '-annotations']).filter(doc => doc.unrendered), ...DocListCast(activeItem.presAnnotations)]);
+ }
+ if (pinDataTypes.dataview && activeItem.presData !== undefined) {
+ const fkey = Doc.LayoutFieldKey(bestTarget);
+ Doc.GetProto(bestTarget)[fkey] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+ bestTarget[fkey + '-useAlt'] = activeItem.presUseAlt;
+ }
+ if (pinDataTypes.textview && activeItem.presData !== undefined) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+ if (pinDataTypes.poslayoutview) {
+ changed = true;
StrListCast(activeItem.presPinLayoutData)
.map(str => JSON.parse(str) as { id: string; x: number; y: number; w: number; h: number })
.forEach(data => {
const doc = DocServer.GetCachedRefField(data.id) as Doc;
- doc._dataTransition = presTransitionTime;
+ doc._dataTransition = `all ${transTime}ms`;
doc.x = data.x;
doc.y = data.y;
doc._width = data.w;
@@ -389,16 +409,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
() =>
StrListCast(activeItem.presPinLayoutData)
.map(str => JSON.parse(str) as { id: string; x: number; y: number; w: number; h: number })
- .forEach(
- action(data => {
- const doc = DocServer.GetCachedRefField(data.id) as Doc;
- doc._dataTransition = undefined;
- })
- ),
+ .forEach(action(data => ((DocServer.GetCachedRefField(data.id) as Doc)._dataTransition = undefined))),
transTime + 10
);
}
- if (pannable) {
+ if (pinDataTypes.pannable) {
const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
if (contentBounds) {
const viewport = { panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] };
@@ -407,25 +422,29 @@ 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 = computedScale);
+ activeItem.presMovement === PresMovement.Zoom && (bestTarget._viewScale = computedScale);
dv.ComponentView?.brushView?.(viewport);
}
} else {
- bestTarget._panX = activeItem.presPinViewX;
- bestTarget._panY = activeItem.presPinViewY;
- activeItem.presMovement === 'zoom' && (bestTarget._viewScale = activeItem.presPinViewScale);
+ if (bestTarget._panX !== activeItem.presPinViewX || bestTarget._panY !== activeItem.presPinViewY || bestTarget._viewScale !== activeItem.presPinViewScale) {
+ bestTarget._panX = activeItem.presPinViewX;
+ bestTarget._panY = activeItem.presPinViewY;
+ bestTarget._viewScale = activeItem.presPinViewScale;
+ changed = true;
+ }
}
}
- return setTimeout(() => (bestTarget._viewTransition = undefined), transTime + 10);
+ if (changed) {
+ return bestTargetView.setViewTransition('all', transTime);
+ }
}
/// 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, targetDoc: Doc) {
- const { scrollable, pannable, temporal, clippable, dataview, textview, poslayoutview } = this.pinDataTypes(pinDoc);
- if (pinProps?.pinDocLayout) {
+ static pinDocView(pinDoc: Doc, pinProps: PinProps, targetDoc: Doc) {
+ if (pinProps.pinDocLayout) {
pinDoc.presPinLayout = true;
pinDoc.presX = NumCast(targetDoc.x);
pinDoc.presY = NumCast(targetDoc.y);
@@ -433,36 +452,51 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
pinDoc.presWidth = NumCast(targetDoc.width);
pinDoc.presHeight = NumCast(targetDoc.height);
}
- if (pinProps?.pinDocContent) {
- pinDoc.presPinData = scrollable || temporal || pannable || clippable || dataview || textview || poslayoutview || pinProps.activeFrame !== undefined;
- if (dataview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.data;
- if (textview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.text;
- if (scrollable) pinDoc.presPinViewScroll = pinDoc._scrollTop;
- if (clippable) pinDoc.presPinClipWidth = pinDoc._clipWidth;
- if (poslayoutview) pinDoc.presPinLayoutData = new List<string>(DocListCast(pinDoc.presData).map(d => JSON.stringify({ id: d[Id], x: NumCast(d.x), y: NumCast(d.y), w: NumCast(d._width), h: NumCast(d._height) })));
- if (pannable) {
- pinDoc.presPinViewX = NumCast(pinDoc._panX);
- pinDoc.presPinViewY = NumCast(pinDoc._panY);
- pinDoc.presPinViewScale = NumCast(pinDoc._viewScale, 1);
+ if (pinProps.pinAudioPlay) pinDoc.followLinkAudio = true;
+ if (pinProps.pinData) {
+ pinDoc.presPinData =
+ pinProps.pinData.scrollable ||
+ pinProps.pinData.temporal ||
+ pinProps.pinData.pannable ||
+ pinProps.pinData.clippable ||
+ pinProps.pinData.dataview ||
+ pinProps.pinData.textview ||
+ pinProps.pinData.poslayoutview ||
+ pinProps?.activeFrame !== undefined;
+ if (pinProps.pinData.dataview) {
+ const fkey = Doc.LayoutFieldKey(targetDoc);
+ pinDoc.presUseAlt = targetDoc[fkey + '-useAlt'];
+ pinDoc.presData = targetDoc[fkey] instanceof ObjectField ? (targetDoc[fkey] as ObjectField)[Copy]() : targetDoc.data;
+ }
+ if (pinProps.pinData.dataannos) {
+ const fkey = Doc.LayoutFieldKey(targetDoc);
+ pinDoc.presAnnotations = new List<Doc>(DocListCast(Doc.GetProto(targetDoc)[fkey + '-annotations']).filter(doc => !doc.unrendered));
}
- 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 (pinProps.pinData.textview) pinDoc.presData = targetDoc[Doc.LayoutFieldKey(targetDoc)] instanceof ObjectField ? (targetDoc[Doc.LayoutFieldKey(targetDoc)] as ObjectField)[Copy]() : targetDoc.text;
+ if (pinProps.pinData.scrollable) pinDoc.presPinViewScroll = targetDoc._scrollTop;
+ if (pinProps.pinData.clippable) pinDoc.presPinClipWidth = targetDoc._clipWidth;
+ if (pinProps.pinData.poslayoutview) pinDoc.presPinLayoutData = new List<string>(DocListCast(targetDoc.presData).map(d => JSON.stringify({ id: d[Id], x: NumCast(d.x), y: NumCast(d.y), w: NumCast(d._width), h: NumCast(d._height) })));
+ if (pinProps.pinData.pannable) {
+ pinDoc.presPinViewX = NumCast(targetDoc._panX);
+ pinDoc.presPinViewY = NumCast(targetDoc._panY);
+ pinDoc.presPinViewScale = NumCast(targetDoc._viewScale, 1);
+ }
+ if (pinProps.pinData.temporal) {
+ pinDoc.presStartTime = targetDoc._currentTimecode;
+ const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], NumCast(targetDoc.presStartTime) + 0.1);
+ pinDoc.presEndTime = NumCast(targetDoc.clipEnd, duration);
}
}
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.presPinViewScale = NumCast(targetDoc._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]);
}
}
-
- static _navTimer: NodeJS.Timeout;
/**
* This method makes sure that cursor navigates to the element that
* has the option open and last in the group.
@@ -471,127 +505,106 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
* a new tab. If presCollection is undefined it will open the document
* on the right.
*/
- navigateToActiveItem = () => {
+ navigateToActiveItem = (afterNav?: () => void) => {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
+ const finished = () => {
+ afterNav?.();
+ console.log('Finish Slide Nav: ' + targetDoc.title);
+ targetDoc[AnimationSym] = undefined;
+ };
const srcContext = Cast(targetDoc.context, Doc, null) ?? Cast(Cast(targetDoc.annotationOn, Doc, null)?.context, Doc, null);
const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
- const includesDoc: boolean = DocListCast(presCollection?.data).includes(targetDoc);
- const tab = CollectionDockingView.Instance && Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === srcContext);
+ const includesDoc = () => (DocumentManager.Instance.getDocumentView(targetDoc) ? true : false); // DocListCast(presCollection?.data).includes(targetDoc);
+ const tabMap = CollectionDockingView.Instance?.tabMap;
+ const tab = tabMap && Array.from(tabMap).find(tab => tab.DashDoc === srcContext || tab.DashDoc === targetDoc);
// Handles the setting of presCollection
- if (includesDoc) {
+ if (includesDoc()) {
//Case 1: Pres collection should not change as it is already the same
} else if (tab !== undefined) {
// Case 2: Pres collection should update
this.layoutDoc.presCollection = srcContext;
}
- const presStatus = this.rootDoc.presStatus;
const selViewCache = Array.from(this.selectedArray);
const dragViewCache = Array.from(this._dragArray);
const eleViewCache = Array.from(this._eleArray);
- const self = this;
const resetSelection = action(() => {
- const presDocView = DocumentManager.Instance.getDocumentView(self.rootDoc);
- if (presDocView) SelectionManager.SelectView(presDocView, false);
- self.rootDoc.presStatus = presStatus;
- self.clearSelectedArray();
- selViewCache.forEach(doc => self.addToSelectedArray(doc));
- self._dragArray.splice(0, self._dragArray.length, ...dragViewCache);
- self._eleArray.splice(0, self._eleArray.length, ...eleViewCache);
+ if (!includesDoc()) {
+ const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc);
+ if (presDocView) SelectionManager.SelectView(presDocView, false);
+ this.clearSelectedArray();
+ selViewCache.forEach(doc => this.addToSelectedArray(doc));
+ this._dragArray.splice(0, this._dragArray.length, ...dragViewCache);
+ this._eleArray.splice(0, this._eleArray.length, ...eleViewCache);
+ }
+ finished();
});
- const openInTab = (doc: Doc, finished?: () => void) => {
- (collectionDocView ?? this).props.addDocTab(doc, '');
+ const createDocView = (doc: Doc, finished?: () => void) => {
+ DocumentManager.Instance.AddViewRenderedCb(doc, () => finished?.());
+ (collectionDocView ?? this).props.addDocTab(doc, OpenWhere.lightbox);
this.layoutDoc.presCollection = targetDoc;
- // this still needs some fixing
- setTimeout(resetSelection, 500);
- if (doc !== targetDoc) {
- setTimeout(finished ?? emptyFunction, 100); /// give it some time to create the targetDoc if we're opening up its context
- } else {
- finished?.();
- }
};
- PresBox.NavigateToTarget(targetDoc, activeItem, openInTab, srcContext, includesDoc || tab ? undefined : resetSelection);
+ PresBox.NavigateToTarget(targetDoc, activeItem, createDocView, srcContext, includesDoc() || tab ? finished : resetSelection);
};
- static NavigateToTarget(targetDoc: Doc, activeItem: Doc, openInTab: any, srcContext: Doc, finished?: () => void) {
- if ((activeItem.presPinLayout || activeItem.presPinView) && DocCast(targetDoc.context)?._currentFrame === undefined) {
- const transTime = NumCast(activeItem.presTransition, 500);
- const presTransitionTime = `all ${transTime}ms`;
- targetDoc._dataTransition = presTransitionTime;
- targetDoc.x = NumCast(activeItem.presX, NumCast(targetDoc.x));
- targetDoc.y = NumCast(activeItem.presY, NumCast(targetDoc.y));
- targetDoc.rotation = NumCast(activeItem.presRot, NumCast(targetDoc.rotation));
- targetDoc.width = NumCast(activeItem.presWidth, NumCast(targetDoc.width));
- targetDoc.height = NumCast(activeItem.presHeight, NumCast(targetDoc.height));
- setTimeout(() => (targetDoc._dataTransition = undefined), transTime + 10);
+ static NavigateToTarget(targetDoc: Doc, activeItem: Doc, createDocView: any, srcContext: Doc, finished?: () => void) {
+ if (activeItem.presMovement === PresMovement.None && targetDoc.type === DocumentType.SCRIPTING) {
+ (DocumentManager.Instance.getFirstDocumentView(targetDoc)?.ComponentView as ScriptingBox)?.onRun?.();
+ return;
}
+ const restoreLayout = () => {
+ // 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.
+ const pinDocLayout = (BoolCast(activeItem.presPinLayout) || BoolCast(activeItem.presPinView)) && DocCast(targetDoc.context)?._currentFrame === undefined;
+ if (activeItem.presPinData || activeItem.presPinView || pinDocLayout) {
+ // targetDoc may or may not be displayed. so get the first available document (or alias) view that matches targetDoc and use it
+ PresBox.restoreTargetDocView(DocumentManager.Instance.getFirstDocumentView(targetDoc), { pinDocLayout }, activeItem, NumCast(activeItem.presTransition, 500));
+ }
+ };
// If openDocument is selected then it should open the document for the user
if (activeItem.openDocument) {
LightboxView.SetLightboxDoc(targetDoc); // openInTab(targetDoc);
- } 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, 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.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;
- if (bestTarget) PresBox._navTimer = PresBox.restoreTargetDocView(bestTarget, activeItem);
+ setTimeout(restoreLayout);
+ } else {
+ if (targetDoc) {
+ const options: DocFocusOptions = {
+ willPan: activeItem.presMovement !== PresMovement.None,
+ willPanZoom: activeItem.presMovement === PresMovement.Zoom || activeItem.presMovement === PresMovement.Jump || activeItem.presMovement === PresMovement.Center,
+ zoomScale: activeItem.presMovement === PresMovement.Center ? 0 : NumCast(activeItem.presZoom, 1),
+ zoomTime: activeItem.presMovement === PresMovement.Jump ? 0 : NumCast(activeItem.presTransition, 500),
+ effect: activeItem,
+ noSelect: true,
+ originatingDoc: activeItem,
+ easeFunc: StrCast(activeItem.presEaseFunc, 'ease') as any,
+ zoomTextSelections: true,
+ };
+ if (activeItem.presentationTargetDoc instanceof Doc) activeItem.presentationTargetDoc[AnimationSym] = undefined;
+ var containerDocContext = srcContext ? [srcContext] : [];
+ while (containerDocContext.length && !DocumentManager.Instance.getDocumentView(containerDocContext[0]) && containerDocContext[0].context) {
+ containerDocContext = [Cast(containerDocContext[0].context, Doc, null), ...containerDocContext];
+ }
+ const testTarget = containerDocContext.length ? containerDocContext[0] : targetDoc;
+ if (LightboxView.LightboxDoc && !DocumentManager.Instance.getLightboxDocumentView(testTarget)) {
+ DocumentManager.Instance.AddViewRenderedCb(LightboxView.LightboxDoc, dv => {
+ if (LightboxView.LightboxDoc && !DocumentManager.Instance.getLightboxDocumentView(LightboxView.LightboxDoc)) {
+ DocumentManager.Instance.jumpToDocument(targetDoc, options, createDocView, containerDocContext, finished);
+ restoreLayout();
+ } else {
+ LightboxView.SetLightboxDoc(undefined);
+ DocumentManager.Instance.jumpToDocument(targetDoc, options, createDocView, containerDocContext, finished);
+ restoreLayout();
+ }
+ });
+ return;
+ }
+ DocumentManager.Instance.jumpToDocument(targetDoc, options, createDocView, containerDocContext, finished);
+ restoreLayout();
+ } else restoreLayout();
}
}
/**
- * Uses the viewfinder to progressivize through the different views of a single collection.
- * @param activeItem: document for which internal zoom is used
- */
- zoomProgressivizeNext = (activeItem: Doc) => {
- const targetDoc: Doc = this.targetDoc;
- const srcContext = Cast(targetDoc?.context, Doc, null);
- const docView = DocumentManager.Instance.getDocumentView(targetDoc);
- const vfLeft = this.checkList(targetDoc, activeItem['viewfinder-left-indexed']);
- const vfWidth = this.checkList(targetDoc, activeItem['viewfinder-width-indexed']);
- const vfTop = this.checkList(targetDoc, activeItem['viewfinder-top-indexed']);
- const vfHeight = this.checkList(targetDoc, activeItem['viewfinder-height-indexed']);
- // Case 1: document that is not a Golden Layout tab
- if (srcContext) {
- const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
- if (srcDocView) {
- const layoutdoc = Doc.Layout(targetDoc);
- const panelWidth: number = srcDocView.props.PanelWidth();
- const panelHeight: number = srcDocView.props.PanelHeight();
- const newPanX = NumCast(targetDoc.x) + NumCast(layoutdoc._width) / 2;
- const newPanY = NumCast(targetDoc.y) + NumCast(layoutdoc._height) / 2;
- const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
- srcContext._panX = newPanX + (vfLeft + vfWidth / 2);
- srcContext._panY = newPanY + (vfTop + vfHeight / 2);
- srcContext._viewScale = newScale;
- }
- }
- // Case 2: document is the containing collection
- if (docView && !srcContext) {
- const panelWidth: number = docView.props.PanelWidth();
- const panelHeight: number = docView.props.PanelHeight();
- const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
- targetDoc._panX = vfLeft + vfWidth / 2;
- targetDoc._panY = vfTop + vfWidth / 2;
- targetDoc._viewScale = newScale;
- }
- const resize = document.getElementById('resizable');
- if (resize) {
- resize.style.width = vfWidth + 'px';
- resize.style.height = vfHeight + 'px';
- resize.style.top = vfTop + 'px';
- resize.style.left = vfLeft + 'px';
- }
- };
-
- /**
* For 'Hide Before' and 'Hide After' buttons making sure that
* they are hidden each time the presentation is updated.
*/
@@ -600,54 +613,57 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.childDocs.forEach((doc, index) => {
const curDoc = Cast(doc, Doc, null);
const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
- //if (tagDoc) tagDoc.opacity = 1;
const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc);
- const curInd: number = itemIndexes.indexOf(index);
if (tagDoc === this.layoutDoc.presCollection) {
tagDoc.opacity = 1;
} else {
- if (curDoc.presHideBefore) {
- if (itemIndexes.length > 1 && curInd !== 0) {
+ if (curDoc.presHide) {
+ if (index !== this.itemIndex) {
tagDoc.opacity = 1;
- } else {
- if (index > this.itemIndex) {
- tagDoc.opacity = 0;
- } else if (index === this.itemIndex || !curDoc.presHideAfter) {
- tagDoc.opacity = 1;
- }
}
}
- if (curDoc.presHideAfter) {
- if (itemIndexes.length > 1 && curInd !== itemIndexes.length - 1) {
+ const hidingIndBef = itemIndexes.find(item => item >= this.itemIndex);
+ if (curDoc.presHideBefore && index === hidingIndBef) {
+ if (index > this.itemIndex) {
+ tagDoc.opacity = 0;
+ } else if (index === this.itemIndex || !curDoc.presHideAfter) {
tagDoc.opacity = 1;
- } else {
- if (index < this.itemIndex) {
- tagDoc.opacity = 0;
- } else if (index === this.itemIndex || !curDoc.presHideBefore) {
- tagDoc.opacity = 1;
- }
+ }
+ }
+ const hidingIndAft = itemIndexes
+ .slice()
+ .reverse()
+ .find(item => item < this.itemIndex);
+ if (curDoc.presHideAfter && index === hidingIndAft) {
+ if (index < this.itemIndex) {
+ tagDoc.opacity = 0;
+ } else if (index === this.itemIndex || !curDoc.presHideBefore) {
+ tagDoc.opacity = 1;
+ }
+ }
+ const hidingInd = itemIndexes.find(item => item === this.itemIndex);
+ if (curDoc.presHide && index === hidingInd) {
+ if (index === this.itemIndex) {
+ tagDoc.opacity = 0;
}
}
}
});
};
- //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
- @action
- startAutoPres = (startSlide: number) => {
- this.layoutDoc.presStatus = PresStatus.Autoplay;
- this.startPresentation(startSlide);
- 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)
- );
+ _exitTrail: Opt<() => void>;
+ PlayTrail = (doc: Doc) => {
+ const savedState = { c: doc, x: NumCast(doc.panX), y: NumCast(doc.panY), s: NumCast(doc.viewScale) };
+ this.startPresentation(0);
+ this._exitTrail = () => {
+ const { x, y, s, c } = savedState;
+ c._panX = x;
+ c._panY = y;
+ c._viewScale = s;
+ LightboxView.SetLightboxDoc(undefined);
+ Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, this.rootDoc);
+ return PresStatus.Edit;
};
-
- func(this.itemIndex);
};
// The function pauses the auto presentation
@@ -676,14 +692,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
// The function allows for viewing the pres path on toggle
- @action togglePath = (srcContext: Doc, off?: boolean) => {
- if (off) {
- this._pathBoolean = false;
- srcContext.presPathView = false;
- } else {
- runInAction(() => (this._pathBoolean = !this._pathBoolean));
- srcContext.presPathView = this._pathBoolean;
- }
+ @action togglePath = (off?: boolean) => {
+ this._pathBoolean = off ? false : !this._pathBoolean;
+ CollectionFreeFormView.ShowPresPaths = this._pathBoolean;
};
// The function allows for expanding the view of pres on toggle
@@ -701,40 +712,54 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
* @param startIndex: index that the presentation will start at
*/
startPresentation = (startIndex: number) => {
- this.childDocs.forEach(doc => {
- const tagDoc = doc.presentationTargetDoc as Doc;
- if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) {
- tagDoc.opacity = 0;
- }
- if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) {
- tagDoc.opacity = 0;
- }
- });
- this.gotoDocument(startIndex, this.activeItem);
+ clearTimeout(this._presTimer);
+ if (this.childDocs.length) {
+ this.layoutDoc.presStatus = PresStatus.Autoplay;
+ this.childDocs.forEach(doc => {
+ const tagDoc = doc.presentationTargetDoc as Doc;
+ if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) tagDoc.opacity = 0;
+ if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) tagDoc.opacity = 0;
+ // if (doc.presHide && this.childDocs.indexOf(doc) === startIndex) tagDoc.opacity = 0;
+ });
+ const func = () => {
+ const delay = NumCast(this.activeItem.presDuration, this.activeItem.type === DocumentType.SCRIPTING ? 0 : 2500) + NumCast(this.activeItem.presTransition);
+ this._presTimer = setTimeout(() => {
+ if (!this.next()) this.layoutDoc.presStatus = this._exitTrail?.() ?? PresStatus.Manual;
+ this.layoutDoc.presStatus === PresStatus.Autoplay && func();
+ }, delay);
+ };
+ this.gotoDocument(startIndex, this.activeItem, undefined, func);
+ }
};
/**
* The method called to open the presentation as a minimized view
*/
@action
- updateMinimize = async () => {
+ enterMinimize = () => {
+ clearTimeout(this._presTimer);
+ const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ this.props.removeDocument?.(this.layoutDoc);
+ return PresBox.OpenPresMinimized(this.rootDoc, [pt[0] + (this.props.PanelWidth() - 250), pt[1] + 10]);
+ };
+ exitMinimize = () => {
if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc)) {
- this.layoutDoc.presStatus = PresStatus.Edit;
Doc.RemoveDocFromList(Doc.MyOverlayDocs, undefined, this.rootDoc);
- CollectionDockingView.AddSplit(this.rootDoc, 'right');
- } else {
- this.layoutDoc.presStatus = PresStatus.Edit;
- clearTimeout(this._presTimer);
- const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
- this.rootDoc.overlayX = pt[0] + (this.props.PanelWidth() - 250);
- this.rootDoc.overlayY = pt[1] + 10;
- this.rootDoc._height = 30;
- this.rootDoc._width = 248;
- Doc.AddDocToList(Doc.MyOverlayDocs, undefined, this.rootDoc);
- this.props.removeDocument?.(this.layoutDoc);
+ CollectionDockingView.AddSplit(this.rootDoc, OpenWhereMod.right);
}
+ return PresStatus.Edit;
};
+ public static minimizedWidth = 198;
+ public static OpenPresMinimized(doc: Doc, pt: number[]) {
+ doc.overlayX = pt[0];
+ doc.overlayY = pt[1];
+ doc._height = 30;
+ doc._width = PresBox.minimizedWidth;
+ Doc.AddDocToList(Doc.MyOverlayDocs, undefined, doc);
+ return (doc.presStatus = PresStatus.Manual);
+ }
+
/**
* Called when the user changes the view type
* Either 'List' (stacking) or 'Slides' (carousel)
@@ -766,20 +791,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) {
const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
list.push(activeItem);
- // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
- console.log(list);
+ // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;\
} else {
this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List<Doc>();
const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
list.push(activeItem);
// this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
- console.log(list);
}
});
movementName = action((activeItem: Doc) => {
- if (![PresMovement.Zoom, PresMovement.Pan, PresMovement.Jump, PresMovement.None].includes(StrCast(activeItem.presMovement) as any)) {
- activeItem.presMovement = 'zoom';
+ if (![PresMovement.Zoom, PresMovement.Pan, PresMovement.Center, PresMovement.Jump, PresMovement.None].includes(StrCast(activeItem.presMovement) as any)) {
+ return PresMovement.Zoom;
}
return StrCast(activeItem.presMovement);
});
@@ -804,7 +827,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
} else {
if (!doc.aliasOf) {
const original = Doc.MakeAlias(doc);
- TabDocView.PinDoc(original);
+ TabDocView.PinDoc(original, {});
setTimeout(() => this.removeDocument(doc), 0);
return false;
} else {
@@ -868,6 +891,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
//Regular click
@action
selectElement = async (doc: Doc) => {
+ CollectionStackedTimeline.CurrentlyPlaying?.map((clip, i) => DocumentManager.Instance.getDocumentView(clip)?.ComponentView?.Pause?.());
this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem);
if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(DocCast(doc.context)), 0);
else this.updateCurrentPresentation(DocCast(doc.context));
@@ -920,7 +944,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
else this.regularSelect(doc, ref, drag, focus);
};
- static keyEventsWrapper = (e: KeyboardEvent) => PresBox.Instance.keyEvents(e);
+ static keyEventsWrapper = (e: KeyboardEvent) => PresBox.Instance?.keyEvents(e);
// Key for when the presentaiton is active
@action
@@ -947,11 +971,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
break;
case 'Escape':
if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc)) {
- this.updateMinimize();
- } else if (this.layoutDoc.presStatus === 'edit') {
+ this.exitClicked();
+ } else if (this.layoutDoc.presStatus === PresStatus.Edit) {
this.clearSelectedArray();
this._eleArray.length = this._dragArray.length = 0;
- } else this.layoutDoc.presStatus = 'edit';
+ } else {
+ this.layoutDoc.presStatus = PresStatus.Edit;
+ }
if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
break;
@@ -1010,17 +1036,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
};
- /**
- *
- */
- @action
- viewPaths = () => {
- const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
- if (srcContext) {
- this.togglePath(srcContext);
- }
- };
-
getAllIndexes = (arr: Doc[], val: Doc) => arr.map((doc, i) => (doc === val ? i : -1)).filter(i => i !== -1);
// Adds the index in the pres path graphically
@@ -1100,16 +1115,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
*/
@computed get paths() {
let pathPoints = '';
- const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
this.childDocs.forEach((doc, index) => {
const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
- const srcContext = Cast(tagDoc?.context, Doc, null);
- if (tagDoc && presCollection === srcContext) {
+ if (tagDoc) {
const n1x = NumCast(tagDoc.x) + NumCast(tagDoc._width) / 2;
const n1y = NumCast(tagDoc.y) + NumCast(tagDoc._height) / 2;
if ((index = 0)) pathPoints = n1x + ',' + n1y;
else pathPoints = pathPoints + ' ' + n1x + ',' + n1y;
- } else if (doc.presPinView && presCollection === tagDoc) {
+ } else if (doc.presPinView) {
const n1x = NumCast(doc.presPinViewX);
const n1y = NumCast(doc.presPinViewY);
if ((index = 0)) pathPoints = n1x + ',' + n1y;
@@ -1133,14 +1146,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
/>
);
}
+ getPaths = (collection: Doc) => this.paths; // needs to be smarter and figure out the paths to draw for this specific collection. or better yet, draw everything in an overlay layer instad of within a collection
// Converts seconds to ms and updates presTransition
- setTransitionTime = (number: String, change?: number) => {
+ public static SetTransitionTime = (number: String, setter: (timeInMS: number) => void, change?: number) => {
let timeInMS = Number(number) * 1000;
if (change) timeInMS += change;
if (timeInMS < 100) timeInMS = 100;
- if (timeInMS > 10000) timeInMS = 10000;
- this.selectedArray.forEach(doc => (doc.presTransition = timeInMS));
+ if (timeInMS > 100000) timeInMS = 100000;
+ setter(timeInMS);
+ };
+ setTransitionTime = (number: String, change?: number) => {
+ PresBox.SetTransitionTime(number, (timeInMS: number) => this.selectedArray.forEach(doc => (doc.presTransition = timeInMS)), change);
};
// Converts seconds to ms and updates presTransition
@@ -1176,6 +1193,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@undoBatch
@action
+ updateHide = (activeItem: Doc) => {
+ activeItem.presHide = !activeItem.presHide;
+ this.selectedArray.forEach(doc => (doc.presHide = activeItem.presHide));
+ };
+
+ @undoBatch
+ @action
updateHideAfter = (activeItem: Doc) => {
activeItem.presHideAfter = !activeItem.presHideAfter;
this.selectedArray.forEach(doc => (doc.presHideAfter = activeItem.presHideAfter));
@@ -1187,10 +1211,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
activeItem.openDocument = !activeItem.openDocument;
this.selectedArray.forEach(doc => (doc.openDocument = activeItem.openDocument));
};
+ @undoBatch
+ @action
+ updateEaseFunc = (activeItem: Doc) => {
+ activeItem.presEaseFunc = activeItem.presEaseFunc === 'linear' ? 'ease' : 'linear';
+ this.selectedArray.forEach(doc => (doc.presEaseFunc = activeItem.presEaseFunc));
+ };
@undoBatch
@action
- updateEffectDirection = (effect: PresEffect, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (doc.presEffectDirection = effect));
+ updateEffectDirection = (effect: PresEffectDirection, all?: boolean) => (all ? this.childDocs : this.selectedArray).forEach(doc => (doc.presEffectDirection = effect));
@undoBatch
@action
@@ -1198,13 +1228,36 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
_batch: UndoManager.Batch | undefined = undefined;
+ public static inputter = (min: string, step: string, max: string, value: number, active: boolean, change: (val: string) => void, hmargin?: number) => {
+ let batch: any;
+ return (
+ <input
+ type="range"
+ step={step}
+ min={min}
+ max={max}
+ value={value}
+ style={{ marginLeft: hmargin, marginRight: hmargin, width: `calc(100% - ${2 * (hmargin ?? 0)}px)` }}
+ className={`toolbar-slider ${active ? '' : 'none'}`}
+ onPointerDown={e => {
+ batch = UndoManager.StartBatch('pres slider');
+ e.stopPropagation();
+ }}
+ onPointerUp={() => batch?.end()}
+ onChange={e => {
+ e.stopPropagation();
+ change(e.target.value);
+ }}
+ />
+ );
+ };
@computed get transitionDropdown() {
const activeItem: Doc = this.activeItem;
const targetDoc: Doc = this.targetDoc;
const isPresCollection: boolean = targetDoc === this.layoutDoc.presCollection;
const isPinWithView: boolean = BoolCast(activeItem.presPinView);
const presEffect = (effect: PresEffect) => (
- <div className={`presBox-dropdownOption ${this.activeItem.presEffect === effect || (effect === PresEffect.None && !this.activeItem.presEffect) ? 'active' : ''}`} onPointerDown={StopEvent} onClick={() => this.updateEffect(effect)}>
+ <div className={`presBox-dropdownOption ${activeItem.presEffect === effect || (effect === PresEffect.None && !activeItem.presEffect) ? 'active' : ''}`} onPointerDown={StopEvent} onClick={() => this.updateEffect(effect)}>
{effect}
</div>
);
@@ -1213,47 +1266,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{movement}
</div>
);
- const presDirection = (diretion: PresEffect, icon: string, gridColumn: number, gridRow: number, opts: object) => {
- const color = this.activeItem.presEffectDirection === diretion || (diretion === PresEffect.Center && !this.activeItem.presEffectDirection) ? Colors.LIGHT_BLUE : 'black';
+ const presDirection = (direction: PresEffectDirection, icon: string, gridColumn: number, gridRow: number, opts: object) => {
+ const color = activeItem.presEffectDirection === direction || (direction === PresEffectDirection.Center && !activeItem.presEffectDirection) ? Colors.LIGHT_BLUE : 'black';
return (
- <Tooltip title={<div className="dash-tooltip">{diretion}</div>}>
+ <Tooltip title={<div className="dash-tooltip">{direction}</div>}>
<div
- style={{ ...opts, border: diretion === PresEffect.Center ? `solid 2px ${color}` : undefined, borderRadius: '100%', cursor: 'pointer', gridColumn, gridRow, justifySelf: 'center', color }}
- onClick={() => this.updateEffectDirection(diretion)}>
+ style={{ ...opts, border: direction === PresEffectDirection.Center ? `solid 2px ${color}` : undefined, borderRadius: '100%', cursor: 'pointer', gridColumn, gridRow, justifySelf: 'center', color }}
+ onClick={() => this.updateEffectDirection(direction)}>
{icon ? <FontAwesomeIcon icon={icon as any} /> : null}
</div>
</Tooltip>
);
};
- const inputter = (min: string, step: string, max: string, value: number, active: boolean, change: (val: string) => void) => {
- return (
- <input
- type="range"
- step={step}
- min={min}
- max={max}
- value={value}
- className={`toolbar-slider ${active ? '' : 'none'}`}
- onPointerDown={e => {
- this._batch = UndoManager.StartBatch('pres slider');
- e.stopPropagation();
- }}
- onPointerUp={() => this._batch?.end()}
- onChange={e => {
- e.stopPropagation();
- change(e.target.value);
- }}
- />
- );
- };
if (activeItem && targetDoc) {
const type = targetDoc.type;
const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
const zoom = NumCast(activeItem.presZoom, 1) * 100;
- let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
+ let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 0;
if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
- const effect = this.activeItem.presEffect ? this.activeItem.presEffect : 'None';
- activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
+ const effect = activeItem.presEffect ? activeItem.presEffect : PresMovement.None;
+ // activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : PresMovement.Zoom;
return (
<div
className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? 'active' : ''}`}
@@ -1277,6 +1309,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
<div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={StopEvent} style={{ display: this._openMovementDropdown ? 'grid' : 'none' }}>
{isPresCollection || (isPresCollection && isPinWithView) ? null : presMovement(PresMovement.None)}
+ {presMovement(PresMovement.Center)}
{presMovement(PresMovement.Zoom)}
{presMovement(PresMovement.Pan)}
{isPresCollection || (isPresCollection && isPinWithView) ? null : presMovement(PresMovement.Jump)}
@@ -1296,9 +1329,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
</div>
- {inputter('0', '1', '100', zoom, activeItem.presMovement === PresMovement.Zoom, this.setZoom)}
- <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
- <div className="presBox-subheading">Movement Speed</div>
+ {PresBox.inputter('0', '1', '100', zoom, activeItem.presMovement === PresMovement.Zoom, this.setZoom)}
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Transition Speed</div>
<div className="ribbon-property">
<input className="presBox-input" type="number" value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.setTransitionTime(e.target.value))} /> s
</div>
@@ -1311,8 +1344,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
</div>
- {inputter('0.1', '0.1', '10', transitionSpeed, [PresMovement.Pan, PresMovement.Zoom].includes(activeItem.presMovement as any), this.setTransitionTime)}
- <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? '' : 'none'}`}>
+ {PresBox.inputter('0.1', '0.1', '100', transitionSpeed, true, this.setTransitionTime)}
+ <div className={'slider-headers'}>
<div className="slider-text">Fast</div>
<div className="slider-text">Medium</div>
<div className="slider-text">Slow</div>
@@ -1329,6 +1362,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</Tooltip>
)}
{isPresCollection ? null : (
+ <Tooltip title={<div className="dash-tooltip">{'Hide while presented'}</div>}>
+ <div className={`ribbon-toggle ${activeItem.presHide ? 'active' : ''}`} onClick={() => this.updateHide(activeItem)}>
+ Hide
+ </div>
+ </Tooltip>
+ )}
+ {isPresCollection ? null : (
<Tooltip title={<div className="dash-tooltip">{'Hide after presented'}</div>}>
<div className={`ribbon-toggle ${activeItem.presHideAfter ? 'active' : ''}`} onClick={() => this.updateHideAfter(activeItem)}>
Hide after
@@ -1340,6 +1380,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
Lightbox
</div>
</Tooltip>
+ <Tooltip title={<div className="dash-tooltip">{'Transition movement style'}</div>}>
+ <div className="ribbon-toggle" onClick={() => this.updateEaseFunc(activeItem)}>
+ {`${StrCast(activeItem.presEaseFunc, 'ease')}`}
+ </div>
+ </Tooltip>
</div>
{type === DocumentType.AUDIO || type === DocumentType.VID ? null : (
<>
@@ -1357,7 +1402,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
</div>
- {inputter('0.1', '0.1', '20', duration, targetDoc.type !== DocumentType.AUDIO, this.setDurationTime)}
+ {PresBox.inputter('0.1', '0.1', '20', duration, targetDoc.type !== DocumentType.AUDIO, this.setDurationTime)}
<div className={'slider-headers'} style={{ display: targetDoc.type === DocumentType.AUDIO ? 'none' : 'grid' }}>
<div className="slider-text">Short</div>
<div className="slider-text">Medium</div>
@@ -1369,6 +1414,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{isPresCollection ? null : (
<div className="ribbon-box">
Effects
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Play Audio Annotation</div>
+ <input className="presBox-checkbox" style={{ margin: 10 }} type="checkbox" onChange={() => (activeItem.followLinkAudio = !BoolCast(activeItem.followLinkAudio))} checked={BoolCast(activeItem.followLinkAudio)} />
+ </div>
<div
className="presBox-dropdown"
onClick={action(e => {
@@ -1376,7 +1425,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._openEffectDropdown = !this._openEffectDropdown;
})}
style={{ borderBottomLeftRadius: this._openEffectDropdown ? 0 : 5, border: this._openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
- {effect.toString()}
+ {effect?.toString()}
<FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
<div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this._openEffectDropdown ? 'grid' : 'none' }} onPointerDown={e => e.stopPropagation()}>
{presEffect(PresEffect.None)}
@@ -1387,16 +1436,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{presEffect(PresEffect.Roll)}
</div>
</div>
- <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? 'none' : 'inline-flex' }}>
+ <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}>
<div className="presBox-subheading">Effect direction</div>
<div className="ribbon-property">{StrCast(this.activeItem.presEffectDirection)}</div>
</div>
- <div className="effectDirection" style={{ display: effect === 'None' ? 'none' : 'grid', width: 40 }}>
- {presDirection(PresEffect.Left, 'angle-right', 1, 2, {})}
- {presDirection(PresEffect.Right, 'angle-left', 3, 2, {})}
- {presDirection(PresEffect.Top, 'angle-down', 2, 1, {})}
- {presDirection(PresEffect.Bottom, 'angle-up', 2, 3, {})}
- {presDirection(PresEffect.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
+ <div className="effectDirection" style={{ display: effect === PresEffectDirection.None ? 'none' : 'grid', width: 40 }}>
+ {presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
+ {presDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
+ {presDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
+ {presDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
+ {presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
</div>
</div>
)}
@@ -1415,7 +1464,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
applyTo = (array: Doc[]) => {
this.updateMovement(this.activeItem.presMovement as PresMovement, true);
this.updateEffect(this.activeItem.presEffect as PresEffect, true);
- this.updateEffectDirection(this.activeItem.presEffectDirection as PresEffect, true);
+ this.updateEffectDirection(this.activeItem.presEffectDirection as PresEffectDirection, true);
const { presTransition, presDuration, presHideBefore, presHideAfter } = this.activeItem;
array.forEach(curDoc => {
curDoc.presTransition = presTransition;
@@ -1745,10 +1794,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const presData = Cast(this.rootDoc.data, listSpec(Doc));
if (data && presData) {
data.push(doc);
- TabDocView.PinDoc(doc);
+ TabDocView.PinDoc(doc, {});
this.gotoDocument(this.childDocs.length, this.activeItem);
} else {
- this.props.addDocTab(doc, 'add:right');
+ this.props.addDocTab(doc, OpenWhere.addRight);
}
}
};
@@ -1781,7 +1830,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
className="dropdown-play-button"
onClick={undoBatch(
action(() => {
- this.updateMinimize();
+ this.enterMinimize();
this.turnOffEdit(true);
this.gotoDocument(this.itemIndex, this.activeItem);
})
@@ -1804,37 +1853,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
scrollFocus = () => {
- this.startOrPause(false);
+ // this.gotoDocument(0);
+ // 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 => {
- const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
- const currentFrame = Cast(tagDoc._currentFrame, 'number', null);
- if (currentFrame === undefined) {
- tagDoc._currentFrame = 0;
- // CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
- // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
- }
- // if (tagDoc.editScrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
- CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc);
- tagDoc._currentFrame = Math.max(0, (currentFrame || 0) + 1);
- tagDoc.lastFrame = Math.max(NumCast(tagDoc._currentFrame), NumCast(tagDoc.lastFrame));
- };
-
- @action
- prevKeyframe = (tagDoc: Doc, actItem: Doc): void => {
- const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
- const currentFrame = Cast(tagDoc._currentFrame, 'number', null);
- if (currentFrame === undefined) {
- tagDoc._currentFrame = 0;
- // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
- }
- CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
- tagDoc._currentFrame = Math.max(0, (currentFrame || 0) - 1);
- };
+ _keyTimer: NodeJS.Timeout | undefined;
/**
* Returns the collection type as a string for headers
@@ -1860,123 +1884,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable private openActiveColorPicker: boolean = false;
@observable private openViewedColorPicker: boolean = false;
- @computed get progressivizeDropdown() {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- if (activeItem && targetDoc) {
- const activeFontColor = targetDoc['pres-text-color'] ? StrCast(targetDoc['pres-text-color']) : 'Black';
- const viewedFontColor = targetDoc['pres-text-viewed-color'] ? StrCast(targetDoc['pres-text-viewed-color']) : 'Black';
- return (
- <div className={`presBox-ribbon ${this._progressivizeTools && this.layoutDoc.presStatus === 'edit' ? 'active' : ''}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
- <div className="ribbon-box">
- {this.stringType} selected
- <div
- className="ribbon-doubleButton"
- style={{
- borderTop: 'solid 1px darkgrey',
- display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? 'inline-flex' : 'none',
- }}>
- <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeChild}>
- Contents
- </div>
- <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editProgressivize}>
- Edit
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? 'inline-flex' : 'none' }}>
- <div className="presBox-subheading">Active text color</div>
- <div
- className="ribbon-colorBox"
- style={{ backgroundColor: activeFontColor, height: 15, width: 15 }}
- onClick={action(() => {
- this.openActiveColorPicker = !this.openActiveColorPicker;
- })}></div>
- </div>
- {this.activeColorPicker}
- <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? 'inline-flex' : 'none' }}>
- <div className="presBox-subheading">Viewed font color</div>
- <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => (this.openViewedColorPicker = !this.openViewedColorPicker))}></div>
- </div>
- {this.viewedColorPicker}
- <div
- className="ribbon-doubleButton"
- style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? 'inline-flex' : 'none' }}>
- <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeZoom}>
- Zoom
- </div>
- <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editZoomProgressivize}>
- Edit
- </div>
- </div>
- <div
- className="ribbon-doubleButton"
- style={{
- borderTop: 'solid 1px darkgrey',
- display: targetDoc._viewType === 'stacking' || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? 'inline-flex' : 'none',
- }}>
- <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.progressivizeScroll}>
- Scroll
- </div>
- <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? Colors.LIGHT_BLUE : '' }} onClick={this.editScrollProgressivize}>
- Edit
- </div>
- </div>
- </div>
- <div className="ribbon-final-box">
- Frames
- <div className="ribbon-doubleButton">
- <div className="ribbon-frameSelector">
- <div
- key="back"
- title="back frame"
- className="backKeyframe"
- onClick={e => {
- e.stopPropagation();
- this.prevKeyframe(targetDoc, activeItem);
- }}>
- <FontAwesomeIcon icon={'caret-left'} size={'lg'} />
- </div>
- <div
- key="num"
- title="toggle view all"
- className="numKeyframe"
- style={{ color: targetDoc.keyFrameEditing ? 'white' : 'black', backgroundColor: targetDoc.keyFrameEditing ? Colors.MEDIUM_BLUE : Colors.LIGHT_BLUE }}
- onClick={action(() => (targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing))}>
- {NumCast(targetDoc._currentFrame)}
- </div>
- <div
- key="fwd"
- title="forward frame"
- className="fwdKeyframe"
- onClick={e => {
- e.stopPropagation();
- this.nextKeyframe(targetDoc, activeItem);
- }}>
- <FontAwesomeIcon icon={'caret-right'} size={'lg'} />
- </div>
- </div>
- <Tooltip
- title={
- <>
- <div className="dash-tooltip">{'Last frame'}</div>
- </>
- }>
- <div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div>
- </Tooltip>
- </div>
- <div className="ribbon-frameList">
- {this.frameListHeader}
- {this.frameList}
- </div>
- <div className="ribbon-toggle" style={{ height: 20, backgroundColor: Colors.LIGHT_BLUE }} onClick={() => console.log(' TODO: play frames')}>
- Play
- </div>
- </div>
- </div>
- );
- }
- }
-
@undoBatch
@action
switchActive = (color: ColorState) => {
@@ -2011,262 +1918,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@action
- turnOffEdit = (paths?: boolean) => {
- // Turn off paths
- if (paths) {
- const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
- if (srcContext) this.togglePath(srcContext, true);
- }
- // Turn off the progressivize editors for each document
- this.childDocs.forEach(doc => {
- doc.editSnapZoomProgressivize = false;
- doc.editZoomProgressivize = false;
- const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
- if (targetDoc) {
- targetDoc.editZoomProgressivize = false;
- // targetDoc.editScrollProgressivize = false;
- }
- });
- };
-
- //Toggle whether the user edits or not
- @action
- editZoomProgressivize = (e: React.MouseEvent) => {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- if (!targetDoc.editZoomProgressivize) {
- if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true;
- targetDoc.zoomProgressivize = true;
- targetDoc.editZoomProgressivize = true;
- activeItem.editZoomProgressivize = true;
- } else {
- targetDoc.editZoomProgressivize = false;
- activeItem.editZoomProgressivize = false;
- }
- };
-
- //Toggle whether the user edits or not
- @action
- editScrollProgressivize = (e: React.MouseEvent) => {
- const targetDoc: Doc = this.targetDoc;
- if (!targetDoc.editScrollProgressivize) {
- if (!targetDoc.scrollProgressivize) {
- targetDoc.scrollProgressivize = true;
- this.activeItem.scrollProgressivize = true;
- }
- targetDoc.editScrollProgressivize = true;
- } else {
- targetDoc.editScrollProgressivize = false;
- }
- };
-
- //Progressivize Zoom
- @action
- progressivizeScroll = (e: React.MouseEvent) => {
- e.stopPropagation();
- this.activeItem.scrollProgressivize = !this.activeItem.scrollProgressivize;
- const targetDoc: Doc = this.targetDoc;
- targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize;
- // CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc._currentFrame));
- if (targetDoc.editScrollProgressivize) {
- targetDoc.editScrollProgressivize = false;
- targetDoc._currentFrame = 0;
- targetDoc.lastFrame = 0;
- }
- };
-
- //Progressivize Zoom
- @action
- progressivizeZoom = (e: React.MouseEvent) => {
- e.stopPropagation();
- const activeItem: Doc = this.activeItem;
- activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
- const targetDoc: Doc = this.targetDoc;
- targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
- CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc);
- if (activeItem.editZoomProgressivize) {
- activeItem.editZoomProgressivize = false;
- targetDoc._currentFrame = 0;
- targetDoc.lastFrame = 0;
- }
- };
-
- //Progressivize Child Docs
- @action
- editProgressivize = (e: React.MouseEvent) => {
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- targetDoc._currentFrame = targetDoc.lastFrame;
- if (!targetDoc.editProgressivize) {
- if (!activeItem.presProgressivize) {
- activeItem.presProgressivize = true;
- targetDoc.presProgressivize = true;
- }
- targetDoc.editProgressivize = true;
- } else {
- targetDoc.editProgressivize = false;
- }
- };
-
- @action
- progressivizeChild = (e: React.MouseEvent) => {
- e.stopPropagation();
- const activeItem: Doc = this.activeItem;
- const targetDoc: Doc = this.targetDoc;
- const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
- if (!activeItem.presProgressivize) {
- targetDoc.keyFrameEditing = false;
- activeItem.presProgressivize = true;
- targetDoc.presProgressivize = true;
- targetDoc._currentFrame = 0;
- docs.forEach((doc, i) => CollectionFreeFormDocumentView.setupKeyframes([doc], i, true));
- targetDoc.lastFrame = targetDoc.lastFrame ? NumCast(targetDoc.lastFrame) : docs.length - 1;
- } else {
- // targetDoc.editProgressivize = false;
- activeItem.presProgressivize = false;
- targetDoc.presProgressivize = false;
- targetDoc._currentFrame = 0;
- targetDoc.keyFrameEditing = true;
- }
- };
-
- @action
- checkMovementLists = (doc: Doc, xlist: any, ylist: any) => {
- const x: List<number> = xlist;
- const y: List<number> = ylist;
- const tags: JSX.Element[] = [];
- let pathPoints = ''; //List of all of the pathpoints that need to be added
- for (let i = 0; i < x.length - 1; i++) {
- if (y[i] || x[i]) {
- if (i === 0) pathPoints = x[i] - 11 + ',' + (y[i] + 33);
- else pathPoints = pathPoints + ' ' + (x[i] - 11) + ',' + (y[i] + 33);
- tags.push(
- <div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>
- {i}
- </div>
- );
- }
- }
- tags.push(
- <svg style={{ overflow: 'visible', position: 'absolute' }}>
- <polyline
- points={pathPoints}
- style={{
- position: 'absolute',
- opacity: 1,
- stroke: '#000000',
- strokeWidth: 2,
- strokeDasharray: '10 5',
- }}
- fill="none"
- />
- </svg>
- );
- return tags;
- };
-
- @observable
- toggleDisplayMovement = (doc: Doc) => (doc.displayMovement = !doc.displayMovement);
-
- @action
- checkList = (doc: Doc, list: any): number => {
- const x: List<number> = list;
- if (x?.length >= NumCast(doc._currentFrame) + 1) {
- return x[NumCast(doc._currentFrame)];
- } else if (x) {
- x.length = NumCast(doc._currentFrame) + 1;
- x[NumCast(doc._currentFrame)] = x[NumCast(doc._currentFrame) - 1];
- return x[NumCast(doc._currentFrame)];
- }
- return 100;
- };
-
- @computed get progressivizeChildDocs() {
- const targetDoc: Doc = this.targetDoc;
- const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
- const tags: JSX.Element[] = [];
- docs.forEach((doc, index) => {
- if (doc['x-indexed'] && doc['y-indexed']) {
- tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? 'block' : 'none' }}>{this.checkMovementLists(doc, doc['x-indexed'], doc['y-indexed'])}</div>);
- }
- tags.push(
- <div
- className="progressivizeButton"
- key={index}
- onPointerLeave={() => {
- if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0;
- }}
- onPointerOver={() => {
- if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5;
- }}
- onClick={e => {
- this.toggleDisplayMovement(doc);
- e.stopPropagation();
- }}
- style={{ backgroundColor: doc.displayMovement ? Colors.LIGHT_BLUE : '#c8c8c8', top: NumCast(doc.y), left: NumCast(doc.x) }}>
- <div className="progressivizeButton-prev">
- <FontAwesomeIcon
- icon={'caret-left'}
- size={'lg'}
- onClick={e => {
- e.stopPropagation();
- this.prevAppearFrame(doc, index);
- }}
- />
- </div>
- <div className="progressivizeButton-frame">{NumCast(doc.appearFrame)}</div>
- <div className="progressivizeButton-next">
- <FontAwesomeIcon
- icon={'caret-right'}
- size={'lg'}
- onClick={e => {
- e.stopPropagation();
- this.nextAppearFrame(doc, index);
- }}
- />
- </div>
- </div>
- );
- });
- return tags;
- }
-
- @action
- nextAppearFrame = (doc: Doc, i: number) => {
- doc.appearFrame = (Cast(doc.appearFrame, 'number', null) ?? 0) + 1;
- this.updateOpacityList(doc['opacity-indexed'], NumCast(doc.appearFrame));
- };
-
- @action
- prevAppearFrame = (doc: Doc, i: number) => {
- doc.appearFrame = Math.max(0, (Cast(doc.appearFrame, 'number', null) ?? 0) - 1);
- this.updateOpacityList(doc['opacity-indexed'], NumCast(doc.appearFrame));
- };
-
- @action
- updateOpacityList = (list: any, frame: number) => {
- const x: List<number> = list;
- if (x && x.length >= frame) {
- for (let i = 0; i < x.length; i++) {
- if (i < frame) {
- x[i] = 0;
- } else if (i >= frame) {
- x[i] = 1;
- }
- }
- list = x;
- } else {
- x.length = frame + 1;
- for (let i = 0; i < x.length; i++) {
- if (i < frame) {
- x[i] = 0;
- } else if (i >= frame) {
- x[i] = 1;
- }
- }
- list = x;
- }
- };
+ turnOffEdit = (paths?: boolean) => paths && this.togglePath(true); // Turn off paths
@computed
get toolbarWidth(): number {
@@ -2289,11 +1941,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<FontAwesomeIcon icon={"plus"} />
<FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
</div></Tooltip> */}
- <Tooltip title={<div className="dash-tooltip">{'View paths'}</div>}>
+ <Tooltip title={<div className="dash-tooltip">View paths</div>}>
<div
- style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? '100%' : undefined }}
+ style={{ opacity: this.childDocs.length > 1 ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? '100%' : undefined }}
className={'toolbar-button'}
- onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}>
+ onClick={this.childDocs.length > 1 ? () => this.togglePath() : undefined}>
<FontAwesomeIcon icon={'exchange-alt'} />
</div>
</Tooltip>
@@ -2332,8 +1984,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get topPanel() {
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
const isMini: boolean = this.toolbarWidth <= 100;
+ const inOverlay = DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc);
return (
- <div className="presBox-buttons" style={{ background: Doc.ActivePresentation === this.rootDoc ? Colors.LIGHT_BLUE : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
+ <div className={`presBox-buttons${inOverlay ? ' inOverlay' : ''}`} style={{ background: Doc.ActivePresentation === this.rootDoc ? Colors.LIGHT_BLUE : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
{isMini ? null : (
<select className="presBox-viewPicker" style={{ display: this.layoutDoc.presStatus === 'edit' ? 'block' : 'none' }} onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}>
<option onPointerDown={StopEvent} value={CollectionViewType.Stacking}>
@@ -2350,7 +2003,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</select>
)}
<div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}>
- <span className={`presBox-button ${this.layoutDoc.presStatus === 'edit' ? 'present' : ''}`}>
+ <span className={`presBox-button ${this.layoutDoc.presStatus === PresStatus.Edit ? 'present' : ''}`}>
<div
className="presBox-button-left"
onClick={undoBatch(() => {
@@ -2379,89 +2032,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
);
}
- @action
- getList = (list: any): List<number> => list;
-
- @action
- updateList = (list: any): List<number> => {
- const targetDoc: Doc = this.targetDoc;
- const x: List<number> = list;
- x[x.length - 1] = NumCast(targetDoc._scrollY);
- return x;
- };
-
- @action
- newFrame = () => {
- const activeItem: Doc = this.activeItem;
- const type: string = StrCast(this.targetDoc.type);
- if (!activeItem.frameList) activeItem.frameList = new List<number>();
- switch (type) {
- case DocumentType.PDF || DocumentType.RTF || DocumentType.WEB:
- this.updateList(activeItem.frameList);
- break;
- }
- };
-
- @computed get frameListHeader() {
- return (
- <div className="frameList-header">
- &nbsp; Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : null}
- <div className={'frameList-headerButtons'}>
- <Tooltip title={<div className="dash-tooltip">{'Add frame by example'}</div>}>
- <div
- className={'headerButton'}
- onClick={e => {
- e.stopPropagation();
- this.newFrame();
- }}>
- <FontAwesomeIcon icon={'plus'} onPointerDown={e => e.stopPropagation()} />
- </div>
- </Tooltip>
- <Tooltip title={<div className="dash-tooltip">{'Edit in collection'}</div>}>
- <div
- className={'headerButton'}
- onClick={e => {
- e.stopPropagation();
- console.log('New frame');
- }}>
- <FontAwesomeIcon icon={'edit'} onPointerDown={e => e.stopPropagation()} />
- </div>
- </Tooltip>
- </div>
- </div>
- );
- }
-
- @computed get frameList() {
- const frameList: List<number> = this.getList(this.activeItem.frameList);
- return !frameList ? null : (
- <div className="frameList-container">
- {frameList.map(value => (
- <div className="framList-item" />
- ))}
- </div>
- );
- }
-
- @computed get playButtonFrames() {
- const targetDoc = this.targetDoc;
- return !this.targetDoc ? null : (
- <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? 'inline-flex' : 'none' }}>
- <div>{NumCast(targetDoc._currentFrame)}</div>
- <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div>
- <div>{NumCast(targetDoc.lastFrame)}</div>
- </div>
- );
- }
-
@computed get playButtons() {
const presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0;
+ const inOverlay = DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc);
// Case 1: There are still other frames and should go through all frames before going to next slide
return (
<div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== 'edit' ? 'inline-flex' : 'none' }}>
<Tooltip title={<div className="dash-tooltip">{'Loop'}</div>}>
- <div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }} onClick={() => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop)}>
+ <div
+ className="presPanel-button"
+ style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }}
+ onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => (this.layoutDoc.presLoop = !this.layoutDoc.presLoop), false, false)}>
<FontAwesomeIcon icon={'redo-alt'} />
</div>
</Tooltip>
@@ -2469,43 +2051,77 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div
className="presPanel-button"
style={{ opacity: presStart ? 0.4 : 1 }}
- onClick={e => {
- this.back();
- if (this._presTimer) {
- clearTimeout(this._presTimer);
- this.layoutDoc.presStatus = PresStatus.Manual;
- }
- e.stopPropagation();
- }}>
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.back();
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
+ e.stopPropagation();
+ },
+ false,
+ false
+ )
+ }>
<FontAwesomeIcon icon={'arrow-left'} />
</div>
<Tooltip title={<div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>}>
- <div className="presPanel-button" onClick={e => this.startOrPause(true)}>
+ <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.startOrPause(true), false, false)}>
<FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} />
</div>
</Tooltip>
<div
className="presPanel-button"
style={{ opacity: presEnd ? 0.4 : 1 }}
- onClick={e => {
- this.next();
- if (this._presTimer) {
- clearTimeout(this._presTimer);
- this.layoutDoc.presStatus = PresStatus.Manual;
- }
- e.stopPropagation();
- }}>
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.next();
+ if (this._presTimer) {
+ clearTimeout(this._presTimer);
+ this.layoutDoc.presStatus = PresStatus.Manual;
+ }
+ e.stopPropagation();
+ },
+ false,
+ false
+ )
+ }>
<FontAwesomeIcon icon={'arrow-right'} />
</div>
<div className="presPanel-divider"></div>
<Tooltip title={<div className="dash-tooltip">{'Click to return to 1st slide'}</div>}>
- <div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.nextSlide(0)}>
+ <div
+ className="presPanel-button"
+ style={{ border: 'solid 1px white' }}
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ () => {
+ this.nextSlide(0);
+ },
+ false,
+ false
+ )
+ }>
<b>1</b>
</div>
</Tooltip>
- <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: this.props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}>
- Slide {this.itemIndex + 1} / {this.childDocs.length}
- {this.playButtonFrames}
+ <div className="presPanel-button-text" onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: inOverlay || this.props.PanelWidth() > 250 ? 'inline-flex' : 'none' }}>
+ {`${inOverlay ? '' : 'Slide'} ${this.itemIndex + 1} / ${this.childDocs.length}`}
</div>
<div className="presPanel-divider"></div>
{this.props.PanelWidth() > 250 ? (
@@ -2513,14 +2129,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
className="presPanel-button-text"
onClick={undoBatch(
action(() => {
- this.layoutDoc.presStatus = 'edit';
+ this.layoutDoc.presStatus = PresStatus.Edit;
clearTimeout(this._presTimer);
})
)}>
EXIT
</div>
) : (
- <div className="presPanel-button" onClick={undoBatch(action(() => (this.layoutDoc.presStatus = 'edit')))}>
+ <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.exitClicked, false, false)}>
<FontAwesomeIcon icon={'times'} />
</div>
)}
@@ -2531,7 +2147,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
startOrPause = (makeActive = true) => {
makeActive && this.updateCurrentPresentation();
- if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex);
+ if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startPresentation(this.itemIndex);
else this.pauseAutoPres();
};
@@ -2554,15 +2170,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@undoBatch
@action
- exitClicked = (e: PointerEvent) => {
- this.updateMinimize();
- this.layoutDoc.presStatus = PresStatus.Edit;
+ exitClicked = () => {
+ this.layoutDoc.presStatus = this._exitTrail?.() ?? this.exitMinimize();
clearTimeout(this._presTimer);
};
- @action
- startMarqueeCreateSlide = () => (PresBox.startMarquee = true);
-
AddToMap = (treeViewDoc: Doc, index: number[]): Doc[] => {
var indexNum = 0;
for (let i = 0; i < index.length; i++) {
@@ -2594,8 +2206,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// needed to ensure that the childDocs are loaded for looking up fields
this.childDocs.slice();
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
- const presEnd: boolean = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
- const presStart: boolean = !this.layoutDoc.presLoop && this.itemIndex === 0;
+ const presEnd = !this.layoutDoc.presLoop && this.itemIndex === this.childDocs.length - 1;
+ const presStart = !this.layoutDoc.presLoop && this.itemIndex === 0;
+ const inOverlay = DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc);
return this.props.addDocTab === returnFalse ? ( // bcz: hack!! - addDocTab === returnFalse only when this is being rendered by the OverlayView which means the doc is a mini player
<div className="miniPres" onClick={e => e.stopPropagation()} onPointerEnter={action(e => (this._forceKeyEvents = true))}>
<div
@@ -2629,7 +2242,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</Tooltip>
<div className="presPanel-button-text">
Slide {this.itemIndex + 1} / {this.childDocs.length}
- {this.playButtonFrames}
</div>
<div className="presPanel-divider" />
<div className="presPanel-button-text" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, returnFalse, this.exitClicked, false, false)}>
@@ -2638,7 +2250,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
) : (
- <div className="presBox-cont" style={{ minWidth: DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc) ? 240 : undefined }}>
+ <div className="presBox-cont" style={{ minWidth: inOverlay ? PresBox.minimizedWidth : undefined }}>
{this.topPanel}
{this.toolbar}
{this.newDocumentToolbarDropdown}
@@ -2652,6 +2264,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
PanelHeight={this.panelHeight}
childIgnoreNativeSize={true}
moveDocument={returnFalse}
+ ignoreUnrendered={true}
//childFitWidth={returnTrue}
childOpacity={returnOne}
childLayoutTemplate={this.childLayoutTemplate}
@@ -2664,7 +2277,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
ScreenToLocalTransform={this.getTransform}
AddToMap={this.AddToMap}
RemFromMap={this.RemFromMap}
- hierarchyIndex={[]}
+ hierarchyIndex={emptyPath}
/>
) : null}
</div>
@@ -2684,7 +2297,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
static NavigateToDoc(bestTarget: Doc, activeItem: Doc) {
const srcContext = Cast(bestTarget.context, Doc, null) ?? Cast(Cast(bestTarget.annotationOn, Doc, null)?.context, Doc, null);
const openInTab = (doc: Doc, finished?: () => void) => {
- CollectionDockingView.AddSplit(doc, 'right');
+ CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
finished?.();
};
PresBox.NavigateToTarget(bestTarget, activeItem, openInTab, srcContext);
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 5d14a0e9a..f1c97d26a 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -50,9 +50,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get collapsedHeight() {
return 35;
} // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
- @computed get presStatus() {
- return this.presBox.presStatus;
- }
@computed get selectedArray() {
return this.presBoxView?.selectedArray;
}
@@ -364,14 +361,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
@computed get recordingIsInOverlay() {
- let isInOverlay = false;
- DocListCast(Doc.MyOverlayDocs.data).forEach(doc => {
- if (doc.slides === this.rootDoc) {
- isInOverlay = true;
- // return
- }
- });
- return isInOverlay;
+ return DocListCast(Doc.MyOverlayDocs.data).some(doc => doc.slides === this.rootDoc);
}
// a previously recorded video will have timecode defined
@@ -502,16 +492,17 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
</Tooltip>
);
}
- if (this.indexInPres === 0) {
+ if (this.indexInPres !== 0) {
items.push(
<Tooltip key="arrow" title={<div className="dash-tooltip">{activeItem.groupWithUp ? 'Ungroup' : 'Group with up'}</div>}>
<div
className="slideButton"
- onClick={() => (activeItem.groupWithUp = !activeItem.groupWithUp)}
+ onClick={() => (activeItem.groupWithUp = (NumCast(activeItem.groupWithUp) + 1) % 3)}
style={{
zIndex: 1000 - this.indexInPres,
fontWeight: 700,
backgroundColor: activeItem.groupWithUp ? (presColorBool ? presBoxColor : Colors.MEDIUM_BLUE) : undefined,
+ outline: NumCast(activeItem.groupWithUp) > 1 ? 'solid black 1px' : undefined,
height: activeItem.groupWithUp ? 53 : 18,
transform: activeItem.groupWithUp ? 'translate(0, -17px)' : undefined,
}}>
diff --git a/src/client/views/nodes/trails/PresEnums.ts b/src/client/views/nodes/trails/PresEnums.ts
index c6a222c3a..564829d54 100644
--- a/src/client/views/nodes/trails/PresEnums.ts
+++ b/src/client/views/nodes/trails/PresEnums.ts
@@ -1,6 +1,7 @@
export enum PresMovement {
Zoom = 'zoom',
Pan = 'pan',
+ Center = 'center',
Jump = 'jump',
None = 'none',
}
@@ -14,11 +15,15 @@ export enum PresEffect {
Bounce = 'Bounce',
Roll = 'Roll',
None = 'None',
+}
+
+export enum PresEffectDirection {
Left = 'Enter from left',
Right = 'Enter from right',
Center = 'Enter from center',
Top = 'Enter from Top',
Bottom = 'Enter from bottom',
+ None = 'None',
}
export enum PresStatus {