aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-11-01 10:34:29 -0500
committerGitHub <noreply@github.com>2020-11-01 10:34:29 -0500
commitc8a8f569eefb4daad6da25d9be2a939589ccb704 (patch)
tree3d80acb0fbe028d8c8f1fed3d002c93f4be61ecb
parent7b96bc4770bd275db0ddd664bb6e8ff33bbbcb78 (diff)
parent35de050c423edba2be6833492438a5e02f45f938 (diff)
Merge pull request #922 from browngraphicslab/presentation_v1
Presentation v1
-rw-r--r--src/client/views/DocumentButtonBar.tsx6
-rw-r--r--src/client/views/PropertiesView.tsx4
-rw-r--r--src/client/views/collections/CollectionMenu.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss9
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx2
-rw-r--r--src/client/views/nodes/PresBox.scss1
-rw-r--r--src/client/views/nodes/PresBox.tsx95
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx4
8 files changed, 76 insertions, 47 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 3b22cf51c..fa0b9a238 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -201,13 +201,15 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
if (targetDoc) {
TabDocView.PinDoc(targetDoc, false);
const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1];
- if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
+ const scrollable: boolean = (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking);
+ const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG);
+ if (scrollable) {
const scroll = targetDoc._scrollTop;
activeDoc.presPinView = true;
activeDoc.presPinViewScroll = scroll;
} else if (targetDoc.type === DocumentType.VID) {
activeDoc.presPinTimecode = targetDoc._currentTimecode;
- } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) {
+ } else if (pannable) {
const x = targetDoc._panX;
const y = targetDoc._panY;
const scale = targetDoc._viewScale;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 42f61f99a..fad2f5284 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1029,7 +1029,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{PresBox.Instance.progressivizeDropdown}
</div> : null}
</div>} */}
- {!selectedItem || (!scrollable && !pannable) ? (null) : <div className="propertiesView-presTrails">
+ {/* {!selectedItem || (!scrollable && !pannable) ? (null) : <div className="propertiesView-presTrails">
<div className="propertiesView-presTrails-title"
onPointerDown={action(() => { this.openSlideOptions = !this.openSlideOptions; })}
style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
@@ -1041,7 +1041,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{this.openSlideOptions ? <div className="propertiesView-presTrails-content">
{PresBox.Instance.optionsDropdown}
</div> : null}
- </div>}
+ </div>} */}
{/* <div className="propertiesView-presTrails">
<div className="propertiesView-presTrails-title"
onPointerDown={action(() => { this.openAddSlide = !this.openAddSlide; })}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index b44b85183..1dbafbd61 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -432,7 +432,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
const presPinWithViewIcon = <img src={`/assets/pinWithView.png`} style={{ margin: "auto", width: 19 }} />;
const targetDoc = this.selectedDoc;
{/* return (!targetDoc || (targetDoc._viewType !== CollectionViewType.Freeform && targetDoc.type !== DocumentType.IMG)) ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin to presentation trail with current view"}</div></>} placement="top"> */ }
- return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ? <Tooltip title={<><div className="dash-tooltip">{"Pin to presentation trail with current view"}</div></>} placement="top">
+ return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ? <Tooltip title={<><div className="dash-tooltip">{"Pin with current view"}</div></>} placement="top">
<button className="antimodeMenu-button" style={{ borderRight: "1px solid gray", borderLeft: "1px solid gray", justifyContent: 'center' }}
onClick={() => this.pinWithView(targetDoc)}>
{presPinWithViewIcon}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 75cbc20ca..e92100c50 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -57,7 +57,7 @@
min-height: 15px;
text-align: center;
background-color: #69a6db;
- border-radius: 5px;
+ border-radius: 10%;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
font-family: Roboto;
font-weight: 500;
@@ -65,6 +65,13 @@
}
}
+.pathOrder-presPinView {
+ position: absolute;
+ z-index: 190000;
+ border-style: dashed;
+ border-color: #69a5db;
+}
+
.progressivizeButton {
position: absolute;
display: grid;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index d8e44e781..cedeb1112 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -54,7 +54,7 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
<FontAwesomeIcon icon="font" size="lg" />
</button>
</Tooltip>,
- <Tooltip key="pinWithView" title={<><div className="dash-tooltip">Pin the selected region to presentation</div></>} placement="bottom">
+ <Tooltip key="pinWithView" title={<><div className="dash-tooltip">Pin with selected region</div></>} placement="bottom">
<button
className="antimodeMenu-button"
onPointerDown={this.pinWithView}>
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 07cf63532..a89bc73c6 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -1000,6 +1000,7 @@ $light-background: #ececec;
transition: all 0.2s;
.presPanel-button-text {
+ cursor: pointer;
display: flex;
height: 20;
width: max-content;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index dd7ba3e26..518d365ed 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -28,6 +28,7 @@ import { AudioBox } from "./AudioBox";
import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
import { FieldView, FieldViewProps } from './FieldView';
import "./PresBox.scss";
+import Color = require("color");
export enum PresMovement {
Zoom = "zoom",
@@ -193,16 +194,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
// No more frames in current doc and next slide is defined, therefore move to next slide
nextSlide = (targetDoc: Doc, activeNext: Doc) => {
const nextSelected = this.itemIndex + 1;
- if (targetDoc.type === DocumentType.AUDIO) { if (AudioBox.Instance._ele) AudioBox.Instance.pause(); }
- // if (targetDoc.type === DocumentType.VID) { if (AudioBox.Instance._ele) VideoBox.Instance.Pause(); }
- const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
- // If next slide is audio / video 'Play automatically' then the next slide should be played
- if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) {
- console.log('play next automatically');
- if (targetNext.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeNext.presStartTime));
- // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() };
- } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); }
this.gotoDocument(nextSelected);
+
+ // const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
+ // If next slide is audio / video 'Play automatically' then the next slide should be played
+ // if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) {
+ // console.log('play next automatically');
+ // if (targetNext.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeNext.presStartTime));
+ // // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() };
+ // } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); }
}
// Called when the user activates 'next' - to move to the next part of the pres. trail
@@ -215,13 +215,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
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 ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== PresStatus.Autoplay) {
- // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
- this.nextAudioVideo(targetDoc, activeItem);
} else if (this.childDocs[this.itemIndex + 1] !== undefined) {
// Case 3: No more frames in current doc and next slide is defined, therefore move to next slide
this.nextSlide(targetDoc, activeNext);
@@ -229,6 +225,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
// Case 4: Last slide and presLoop is toggled ON
this.gotoDocument(0);
}
+ // else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== PresStatus.Autoplay) {
+ // // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
+ // this.nextAudioVideo(targetDoc, activeItem);
+ // }
}
// Called when the user activates 'back' - to move to the previous part of the pres. trail
@@ -240,14 +240,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null);
const lastFrame = Cast(targetDoc.lastFrame, "number", null);
const curFrame = NumCast(targetDoc._currentFrame);
+ let prevSelected = this.itemIndex;
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) {
- let prevSelected = this.itemIndex;
+ } else 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.gotoDocument(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);
}
}
@@ -750,8 +754,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
break;
case "Down": case "ArrowDown":
case "Right": case "ArrowRight":
- if (this.itemIndex >= this.childDocs.length - 1) return;
- if (e.shiftKey) { // TODO: update to work properly
+ if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) { // TODO: update to work properly
this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1;
this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
} else {
@@ -762,8 +765,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
break;
case "Up": case "ArrowUp":
case "Left": case "ArrowLeft":
- if (this.itemIndex === 0) return;
- if (e.shiftKey) { // TODO: update to work properly
+ if (e.shiftKey && this.itemIndex !== 0) { // TODO: update to work properly
this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1;
this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
} else {
@@ -815,6 +817,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@computed get order() {
const order: JSX.Element[] = [];
const docs: Doc[] = [];
+ const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
+ const dv = DocumentManager.Instance.getDocumentView(presCollection);
this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => {
const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
const srcContext = Cast(tagDoc.context, Doc, null);
@@ -823,8 +827,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const edge = Math.max(width, height);
const fontSize = edge * 0.8;
const gap = 2;
- // Case A: Document is contained within the collection
- if (this.rootDoc.presCollection === srcContext) {
+ if (presCollection === srcContext) {
+ // Case A: Document is contained within the collection
if (docs.includes(tagDoc)) {
const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length;
docs.push(tagDoc);
@@ -845,20 +849,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div className="pathOrder-frame">{index + 1}</div>
</div>);
}
+ } else if (doc.presPinView && presCollection === tagDoc && dv) {
// Case B: Document is presPinView and is presCollection
- } else if (doc.pinWithView && this.layoutDoc.presCollection === tagDoc) {
+ const scale: number = 1 / NumCast(doc.presPinViewScale);
+ const height: number = dv.props.PanelHeight() * scale;
+ const width: number = dv.props.PanelWidth() * scale;
+ const indWidth = width / 10;
+ const indHeight = Math.max(height / 10, 15);
+ const indEdge = Math.max(indWidth, indHeight);
+ const indFontSize = indEdge * 0.8;
+ const xLoc: number = NumCast(doc.presPinViewX) - (width / 2);
+ const yLoc: number = NumCast(doc.presPinViewY) - (height / 2);
docs.push(tagDoc);
order.push(
- <div className="pathOrder" key={tagDoc.id + 'pres' + index} style={{ top: 0, left: 0 }}>
- <div className="pathOrder-frame">{index + 1}</div>
- </div>);
- // Case C: Document is not contained within presCollection
- } else {
- docs.push(tagDoc);
- order.push(
- <div className="pathOrder" key={tagDoc.id + 'pres' + index} style={{ position: 'absolute', top: 0, left: 0 }}>
- <div className="pathOrder-frame">{index + 1}</div>
- </div>);
+ <>
+ <div className="pathOrder"
+ key={tagDoc.id + 'pres' + index}
+ style={{ top: yLoc - (indEdge / 2), left: xLoc - (indEdge / 2), width: indEdge, height: indEdge, fontSize: indFontSize }}
+ onClick={() => this.selectElement(doc)}
+ >
+ <div className="pathOrder-frame">{index + 1}</div>
+ </div>
+ <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div>
+ </>);
}
});
return order;
@@ -874,17 +887,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
*/
@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 && this.rootDoc.presCollection === srcContext) {
+ if (tagDoc && presCollection === srcContext) {
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 (index = 0) pathPoints = 0 + "," + 0;
- else pathPoints = pathPoints + " " + 0 + "," + 0;
+ } else if (doc.presPinView && presCollection === tagDoc) {
+ const n1x = NumCast(doc.presPinViewX);
+ const n1y = NumCast(doc.presPinViewY);
+ if (index = 0) pathPoints = n1x + "," + n1y;
+ else pathPoints = pathPoints + " " + n1x + "," + n1y;
}
});
return (<polyline
@@ -2021,7 +2037,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? "pause" : "play"} /></div></Tooltip>
<div className="presPanel-button" onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
<div className="presPanel-divider"></div>
- <div className="presPanel-button-text" style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
+ <div
+ className="presPanel-button-text"
+ onClick={() => this.gotoDocument(0)}
+ style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
Slide {this.itemIndex + 1} / {this.childDocs.length}
{this.playButtonFrames}
</div>
@@ -2055,7 +2074,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div></Tooltip>
<div className="presPanel-button" onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
<div className="presPanel-divider"></div>
- <div className="presPanel-button-text">
+ <div className="presPanel-button-text" onClick={() => this.gotoDocument(0)}>
Slide {this.itemIndex + 1} / {this.childDocs.length}
{this.playButtonFrames}
</div>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 7a28f8bff..b2acad86e 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -120,14 +120,14 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
if (this.rootDoc.type === DocumentType.AUDIO) { durationInS = NumCast(this.rootDoc.presEndTime) - NumCast(this.rootDoc.presStartTime); durationInS = Math.round(durationInS * 10) / 10; }
else if (this.rootDoc.presDuration) durationInS = NumCast(this.rootDoc.presDuration) / 1000;
else durationInS = 2;
- return this.rootDoc.presMovement === PresMovement.Jump ? (null) : "D: " + durationInS + "s";
+ return "D: " + durationInS + "s";
}
@computed get transition() {
let transitionInS: number;
if (this.rootDoc.presTransition) transitionInS = NumCast(this.rootDoc.presTransition) / 1000;
else transitionInS = 0.5;
- return "M: " + transitionInS + "s";
+ return this.rootDoc.presMovement === PresMovement.Jump || this.rootDoc.presMovement === PresMovement.None ? (null) : "M: " + transitionInS + "s";
}
private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();