diff options
-rw-r--r-- | src/client/views/PropertiesButtons.tsx | 51 | ||||
-rw-r--r-- | src/client/views/collections/CollectionMenu.scss | 1 | ||||
-rw-r--r-- | src/client/views/collections/CollectionMenu.tsx | 104 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/PresBox.tsx | 10 |
6 files changed, 103 insertions, 71 deletions
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index d303495a4..7a83295c7 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -82,6 +82,9 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get autoHeightButton() { return this.propertyToggleBtn("Auto\xA0Size", "_autoHeight", on => `Automatical vertical sizing to show all content`, on => "arrows-alt-v"); } + @computed get gridButton() { + return this.propertyToggleBtn("Grid", "_backgroundGrid-show", on => `Display background grid in collection`, on => "border-all"); + } @computed get onClickButton() { @@ -98,6 +101,27 @@ export class PropertiesButtons extends React.Component<{}, {}> { </div> </Tooltip>; } + @computed + get perspectiveButton() { + return !this.selectedDoc ? (null) : <Tooltip title={<div className="dash-tooltip">Choose view perspective</div>} placement="top"> + <div> + <div className="propertiesButtons-linkFlyout"> + <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onPerspectiveFlyout}> + <div className={"propertiesButtons-linkButton-empty"} onPointerDown={e => e.stopPropagation()} > + <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" /> + </div> + </Flyout> + </div> + <div className="propertiesButtons-title"> Perspective </div> + </div> + </Tooltip>; + } + + @undoBatch + handlePerspectiveChange = (e: any) => { + this.selectedDoc && (this.selectedDoc._viewType = e.target.value); + SelectionManager.Views().filter(dv => dv.docView).map(dv => dv.docView!).forEach(docView => docView.layoutDoc._viewType = e.target.value); + } @undoBatch @action @@ -139,6 +163,21 @@ export class PropertiesButtons extends React.Component<{}, {}> { {Doc.UserDoc().noviceMode ? (null) : <div onPointerDown={this.editOnClickScript} className="onClickFlyout-editScript"> Edit onClick Script</div>} </div>; } + @computed + get onPerspectiveFlyout() { + const excludedViewTypes = Doc.UserDoc().noviceMode ? [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Stacking, CollectionViewType.Map, CollectionViewType.Linear] : + [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear]; + + const makeLabel = (value: string, label: string) => <div className="radio"> + <label> + <input type="radio" value={value} checked={(this.selectedDoc?._viewType ?? "invalid") === value} onChange={this.handlePerspectiveChange} /> + {label} + </label> + </div>; + return <form> + {Object.values(CollectionViewType).filter(type => !excludedViewTypes.includes(type)).map(type => makeLabel(type, type))} + </form>; + } render() { const layoutField = this.selectedDoc?.[Doc.LayoutFieldKey(this.selectedDoc)]; @@ -153,16 +192,18 @@ export class PropertiesButtons extends React.Component<{}, {}> { <div className="propertiesButtons"> {toggle(this.titleButton)} {toggle(this.captionButton)} - {toggle(this.chromeButton, { display: isCollection ? "" : "none" })} {toggle(this.lockButton)} {toggle(this.dictationButton)} - {toggle(this.autoHeightButton, { display: !isText && !isStacking ? "none" : "" })} {toggle(this.onClickButton)} - {toggle(this.clustersButton, { display: !isFreeForm ? "none" : "" })} - {toggle(this.panButton, { display: !isFreeForm ? "none" : "" })} - {toggle(this.fitContentButton, { display: !isFreeForm && !isText ? "none" : "" })} {toggle(this.fitWidthButton)} + {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })} + {toggle(this.autoHeightButton, { display: !isText && !isStacking ? "none" : "" })} {toggle(this.maskButton, { display: !isInk ? "none" : "" })} + {toggle(this.chromeButton, { display: isCollection ? "" : "none" })} + {toggle(this.gridButton, { display: isCollection ? "" : "none" })} + {toggle(this.clustersButton, { display: !isFreeForm ? "none" : "" })} + {toggle(this.panButton, { display: !isFreeForm ? "none" : "" })} + {toggle(this.perspectiveButton, { display: !isCollection ? "none" : "" })} </div>; } }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 47adb6a1c..2c81d727e 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -318,7 +318,6 @@ .collectionMenu-webUrlButtons { margin-left: 44; background: lightGray; - width: 100%; display: flex; } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index dd0cb86c2..6a9ad27c0 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -223,7 +223,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp case CollectionViewType.Carousel3D: return this._freeform_commands; } } - private _picker: any; private _commandRef = React.createRef<HTMLInputElement>(); private _viewRef = React.createRef<HTMLInputElement>(); @observable private _currentKey: string = ""; @@ -430,14 +429,13 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp @computed get pinWithViewButton() { 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 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} - </button> - </Tooltip> : (null); + return !this.selectedDoc ? (null) : + <Tooltip title={<div className="dash-tooltip">{"Pin with current view"}</div>} placement="top"> + <button className="antimodeMenu-button" style={{ justifyContent: 'center' }} + onClick={() => this.pinWithView(this.selectedDoc)}> + {presPinWithViewIcon} + </button> + </Tooltip>; } @@ -488,48 +486,40 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp @computed get lightboxButton() { const targetDoc = this.selectedDoc; - return !targetDoc ? (null) : <Tooltip title={<div className="dash-tooltip">{"Show Lightbox of Documents"}</div>} placement="top"> - <button className="antimodeMenu-button" onPointerDown={() => { + return !targetDoc ? (null) : <Tooltip title={<div className="dash-tooltip">{"View in Lightbox"}</div>} placement="top"> + <button className="antimodeMenu-button" style={{ borderRight: "1px solid gray", justifyContent: 'center' }} onPointerDown={() => { const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); - if (docs.length) { - LightboxView.SetLightboxDoc(targetDoc, undefined, docs); - } + LightboxView.SetLightboxDoc(targetDoc, undefined, docs); }}> <FontAwesomeIcon className="documentdecorations-icon" icon="desktop" size="lg" /> </button> </Tooltip>; } - @computed get gridbackgroundButton() { - const targetDoc = this.selectedDoc; - return !targetDoc ? (null) : <Tooltip title={<div className="dash-tooltip">{"Toggle background grid"}</div>} placement="top"> - <button className="antimodeMenu-button" onPointerDown={action(() => targetDoc["_backgroundGrid-show"] = !targetDoc["_backgroundGrid-show"])}> - <FontAwesomeIcon className="documentdecorations-icon" icon={targetDoc["_backgroundGrid-show"] ? "border-all" : ["far", "square"]} size="lg" /> - </button> - </Tooltip>; - } render() { return ( <div className="collectionMenu-cont" > <div className="collectionMenu"> <div className="collectionViewBaseChrome"> - {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes} - {!this._buttonizableCommands ? (null) : this.templateChrome} - {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : - <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom"> - <button className={"antimodeMenu-button"} key="float" - style={{ backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined, borderRight: "1px solid gray" }} - onClick={undoBatch(() => this.props.docView.props.CollectionFreeFormDocumentView?.().float())}> - <FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} /> - </button> - </Tooltip>} - {this.notACollection ? (null) : this.lightboxButton} - {this.notACollection ? (null) : this.gridbackgroundButton} {this.aliasButton} {/* {this.pinButton} */} {this.pinWithViewButton} + {this.lightboxButton} + <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom"> + <button className={"antimodeMenu-button"} key="float" + style={{ + backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined, borderRight: "1px solid gray", + pointerEvents: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "none" : undefined, + color: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "dimgrey" : undefined + }} + onClick={undoBatch(() => this.props.docView.props.CollectionFreeFormDocumentView?.().float())}> + <FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} /> + </button> + </Tooltip> + {this.subChrome} + {/* {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes} */} + {!this._buttonizableCommands ? (null) : this.templateChrome} </div> - {this.subChrome} </div> </div> ); @@ -737,38 +727,36 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu render() { return !this.props.docView.layoutDoc ? (null) : <div className="collectionFreeFormMenu-cont"> - {!Doc.UserDoc().noviceMode && !this.isText && !this.props.isDoc ? - <> - <Tooltip key="back" title={<div className="dash-tooltip">Back Frame</div>} placement="bottom"> - <div className="backKeyframe" onClick={this.prevKeyframe}> - <FontAwesomeIcon icon={"caret-left"} size={"lg"} /> - </div> - </Tooltip> - <Tooltip key="num" title={<div className="dash-tooltip">Toggle View All</div>} placement="bottom"> - <div className="numKeyframe" style={{ color: this.document.editing ? "white" : "black", backgroundColor: this.document.editing ? "#5B9FDD" : "#AEDDF8" }} - onClick={action(() => this.document.editing = !this.document.editing)} > - {NumCast(this.document._currentFrame)} - </div> - </Tooltip> - <Tooltip key="fwd" title={<div className="dash-tooltip">Forward Frame</div>} placement="bottom"> - <div className="fwdKeyframe" onClick={this.nextKeyframe}> - <FontAwesomeIcon icon={"caret-right"} size={"lg"} /> - </div> - </Tooltip> - </> - : null} - {!this.selectedDocumentView?.ComponentView?.menuControls ? (null) : this.selectedDocumentView?.ComponentView?.menuControls?.()} {!this.isText ? <> {this.drawButtons} {this.widthPicker} {this.colorPicker} {this.fillPicker} + {Doc.UserDoc().noviceMode || this.props.isDoc ? (null) : + <> + <Tooltip key="back" title={<div className="dash-tooltip">Back Frame</div>} placement="bottom"> + <div className="backKeyframe" onClick={this.prevKeyframe}> + <FontAwesomeIcon icon={"caret-left"} size={"lg"} /> + </div> + </Tooltip> + <Tooltip key="num" title={<div className="dash-tooltip">Toggle View All</div>} placement="bottom"> + <div className="numKeyframe" style={{ color: this.props.docView.ComponentView?.getKeyFrameEditing?.() ? "white" : "black", backgroundColor: this.props.docView.ComponentView?.getKeyFrameEditing?.() ? "#5B9FDD" : "#AEDDF8" }} + onClick={action(() => this.props.docView.ComponentView?.setKeyFrameEditing?.(!this.props.docView.ComponentView?.getKeyFrameEditing?.()))} > + {NumCast(this.document._currentFrame)} + </div> + </Tooltip> + <Tooltip key="fwd" title={<div className="dash-tooltip">Forward Frame</div>} placement="bottom"> + <div className="fwdKeyframe" onClick={this.nextKeyframe}> + <FontAwesomeIcon icon={"caret-right"} size={"lg"} /> + </div> + </Tooltip> + </>} </> : - (null) + <RichTextMenu /> } - {<div style={{ display: !this.isText ? "none" : undefined }}><RichTextMenu /></div>} + {!this.selectedDocumentView?.ComponentView?.menuControls ? (null) : this.selectedDocumentView?.ComponentView?.menuControls?.()} </div>; } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0ee2fad2e..57dba0f75 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -110,6 +110,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P @observable _clusterSets: (Doc[])[] = []; @observable _timelineRef = React.createRef<Timeline>(); @observable _marqueeRef = React.createRef<HTMLDivElement>(); + @observable _keyframeEditing = false; @observable _focusFilters: Opt<string[]>; // docFilters that are overridden when previewing a link to an anchor which has docFilters set on it @observable _focusRangeFilters: Opt<string[]>; // docRangeFilters that are overridden when previewing a link to an anchor which has docRangeFilters set on it @observable ChildDrag: DocumentView | undefined; // child document view being dragged. needed to update drop areas of groups when a group item is dragged. @@ -147,6 +148,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P return this.getTransformOverlay().translate(- this.cachedCenteringShiftX, - this.cachedCenteringShiftY).transform(this.cachedGetLocalTransform); } + @action setKeyFrameEditing = (set: boolean) => this._keyframeEditing = set; + getKeyFrameEditing = () => this._keyframeEditing; onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false; @@ -1051,7 +1054,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P //fitToBox={this.props.fitToBox || BoolCast(this.props.freezeChildDimensions)} // bcz: check this />; } - addDocTab = action((doc: Doc, where: string) => { if (where === "inParent") { ((doc instanceof Doc) ? [doc] : doc).forEach(doc => { @@ -1076,7 +1078,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document._currentFrame); return { x: NumCast(x), y: NumCast(y), z: Cast(z, "number"), color: StrCast(color), zIndex: Cast(zIndex, "number"), - transition: StrCast(layoutDoc.dataTransition), opacity: this.Document.editing ? 1 : Cast(opacity, "number", null), + transition: StrCast(layoutDoc.dataTransition), opacity: this._keyframeEditing ? 1 : Cast(opacity, "number", null), width: Cast(layoutDoc._width, "number"), height: Cast(layoutDoc._height, "number"), pair: params.pair, replica: "" }; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e9b7d06d6..a1bedcf6e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -83,6 +83,8 @@ export interface DocComponentView { reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height. However, some content views (e.g., FreeFormView w/ fitToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling. shrinkWrap?: () => void; // requests a document to display all of its contents with no white space. currently only implemented (needed?) for freeform views menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected. + getKeyFrameEditing?: () => boolean; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown) + setKeyFrameEditing?: (set: boolean) => void; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown) } export interface DocumentViewSharedProps { renderDepth: number; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 682ec5356..3c1fda465 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -224,7 +224,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> setTimeout(() => targetDoc._viewTransition = undefined, 1010); this.nextKeyframe(targetDoc, activeItem); if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc); - else targetDoc.editing = true; + else targetDoc.keyFrameEditing = true; } _mediaTimer!: [NodeJS.Timeout, Doc]; @@ -1902,8 +1902,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> <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.editing ? "white" : "black", backgroundColor: targetDoc.editing ? PresColor.DarkBlue : PresColor.LightBlue }} - onClick={action(() => targetDoc.editing = !targetDoc.editing)} > + <div key="num" title="toggle view all" className="numKeyframe" style={{ color: targetDoc.keyFrameEditing ? "white" : "black", backgroundColor: targetDoc.keyFrameEditing ? PresColor.DarkBlue : PresColor.LightBlue }} + 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); }}> @@ -2063,7 +2063,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> const targetDoc: Doc = this.targetDoc; const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); if (!activeItem.presProgressivize) { - targetDoc.editing = false; + targetDoc.keyFrameEditing = false; activeItem.presProgressivize = true; targetDoc.presProgressivize = true; targetDoc._currentFrame = 0; @@ -2074,7 +2074,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> activeItem.presProgressivize = false; targetDoc.presProgressivize = false; targetDoc._currentFrame = 0; - targetDoc.editing = true; + targetDoc.keyFrameEditing = true; } } |