diff options
Diffstat (limited to 'src/client/views/nodes/trails')
| -rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 199 |
1 files changed, 100 insertions, 99 deletions
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 383b400c8..3d7c68bcd 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -3,7 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { Doc, DocListCast, FieldResult, Opt, StrListCast } from '../../../../fields/Doc'; +import { Doc, DocListCast, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; import { Animation } from '../../../../fields/DocSymbols'; import { Copy, Id } from '../../../../fields/FieldSymbols'; import { InkField } from '../../../../fields/InkField'; @@ -518,13 +518,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { changed = true; } } + if (pinDataTypes?.temporal || (!pinDataTypes && activeItem.timecodeToShow !== undefined)) { + if (bestTarget._layout_currentTimecode !== activeItem.timecodeToShow) { + bestTarget._layout_currentTimecode = activeItem.timecodeToShow; + changed = true; + } + } if (pinDataTypes?.inkable || (!pinDataTypes && (activeItem.config_fillColor !== undefined || activeItem.color !== undefined))) { if (bestTarget.fillColor !== activeItem.config_fillColor) { - Doc.GetProto(bestTarget).fillColor = activeItem.config_fillColor; + Doc.GetProto(bestTarget).fillColor = StrCast(activeItem.config_fillColor, StrCast(bestTarget.fillColor)); changed = true; } if (bestTarget.color !== activeItem.config_color) { - Doc.GetProto(bestTarget).color = activeItem.config_color; + Doc.GetProto(bestTarget).color = StrCast(activeItem.config_color, StrCast(bestTarget.color)); changed = true; } if (bestTarget.width !== activeItem.width) { @@ -565,11 +571,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (bestTarget._layout_scrollTop !== activeItem.config_scrollTop) { bestTarget._layout_scrollTop = activeItem.config_scrollTop; changed = true; - const contentBounds = Cast(activeItem.config_viewBounds, 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] }, transTime); - } } } if (pinDataTypes?.dataannos || (!pinDataTypes && activeItem.config_annotations !== undefined)) { @@ -830,7 +831,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { this.childDocs.forEach((doc, index) => { const curDoc = Cast(doc, Doc, null); const tagDoc = PresBox.targetRenderedDoc(curDoc); - const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc); + const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, curDoc); let opacity: Opt<number> = index === this.itemIndex ? 1 : undefined; if (curDoc.presentation_hide) { if (index !== this.itemIndex) { @@ -864,7 +865,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { opacity = 0; } } - opacity !== undefined && (tagDoc.opacity = opacity); + opacity !== undefined && (tagDoc.opacity = opacity === 1 ? undefined : opacity); }); }; @@ -1301,71 +1302,55 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { 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 - @computed get order() { + orderedPathLabels = (collection: Doc) => { const order: JSX.Element[] = []; - const docs: Doc[] = []; - const presCollection = DocumentManager.GetContextPath(this.activeItem).reverse().lastElement(); + const docs = new Set<Doc>(); + const presCollection = collection; const dv = DocumentManager.Instance.getDocumentView(presCollection); - this.childDocs - .filter(doc => Cast(doc.presentation_targetDoc, Doc, null)) - .forEach((doc, index) => { - const tagDoc = Cast(doc.presentation_targetDoc, Doc, null); - const srcContext = Cast(tagDoc.embedContainer, Doc, null); + this.childDocs.forEach((doc, index) => { + const tagDoc = PresBox.targetRenderedDoc(doc); + const srcContext = Cast(tagDoc.embedContainer, Doc, null); + const labelCreator = (top: number, left: number, edge: number, fontSize: number) => ( + <div className="pathOrder" key={tagDoc.id + 'pres' + index} style={{ top, left, width: edge, height: edge, fontSize }} onClick={() => this.selectElement(doc)}> + <div className="pathOrder-frame">{index + 1}</div> + </div> + ); + if (presCollection === srcContext) { + const gap = 2; const width = NumCast(tagDoc._width) / 10; const height = Math.max(NumCast(tagDoc._height) / 10, 15); const edge = Math.max(width, height); const fontSize = edge * 0.8; - const gap = 2; - 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); - order.push( - <div - className="pathOrder" - key={tagDoc.id + 'pres' + index} - style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - edge / 2), left: NumCast(tagDoc.x) - edge / 2, width: edge, height: edge, fontSize: fontSize }} - onClick={() => this.selectElement(doc)}> - <div className="pathOrder-frame">{index + 1}</div> - </div> - ); - } else { - docs.push(tagDoc); - order.push( - <div - className="pathOrder" - key={tagDoc.id + 'pres' + index} - style={{ top: NumCast(tagDoc.y) - edge / 2, left: NumCast(tagDoc.x) - edge / 2, width: edge, height: edge, fontSize: fontSize }} - onClick={() => this.selectElement(doc)}> - <div className="pathOrder-frame">{index + 1}</div> - </div> - ); - } - } else if (doc.config_pinView && presCollection === tagDoc && dv) { - // Case B: Document is presPinView and is presCollection - const scale: number = 1 / NumCast(doc.config_viewScale); - 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.config_panX) - width / 2; - const yLoc: number = NumCast(doc.config_panY) - height / 2; - docs.push(tagDoc); - order.push( - <> - <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> - </> - ); + // Case A: Document is contained within the collection + if (docs.has(tagDoc)) { + const prevOccurences = this.getAllIndexes(Array.from(docs), tagDoc).length; + order.push(labelCreator(NumCast(tagDoc.y) + (prevOccurences * (edge + gap) - edge / 2), NumCast(tagDoc.x) - edge / 2, edge, fontSize)); + } else { + order.push(labelCreator(NumCast(tagDoc.y) - edge / 2, NumCast(tagDoc.x) - edge / 2, edge, fontSize)); } - }); + } else if (doc.config_pinView && presCollection === tagDoc && dv) { + // Case B: Document is presPinView and is presCollection + const scale = 1 / NumCast(doc.config_viewScale); + const viewBounds = NumListCast(doc.config_viewBounds, [0, 0, dv.props.PanelWidth(), dv.props.PanelHeight()]); + const height = (viewBounds[3] - viewBounds[1]) * scale; + const width = (viewBounds[2] - viewBounds[0]) * scale; + const indWidth = width / 10; + const indHeight = Math.max(height / 10, 15); + const indEdge = Math.max(indWidth, indHeight); + const indFontSize = indEdge * 0.8; + const left = NumCast(doc.config_panX) - width / 2; + const top = NumCast(doc.config_panY) - height / 2; + order.push( + <> + {labelCreator(top - indEdge / 2, left - indEdge / 2, indEdge, indFontSize)} + <div className="pathOrder-presPinView" style={{ top, left, width, height, borderWidth: indEdge / 10 }}></div> + </> + ); + } + docs.add(tagDoc); + }); return order; - } + }; /** * Method called for viewing paths which adds a single line with @@ -1375,41 +1360,57 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { * (Design needed for when documents in presentation trail are in another * collection) */ - @computed get paths() { + pathLines = (collection: Doc) => { let pathPoints = ''; - this.childDocs.forEach((doc, index) => { - const tagDoc = PresBox.targetRenderedDoc(doc); - 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.config_pinView) { - const n1x = NumCast(doc.config_panX); - const n1y = NumCast(doc.config_panY); - if ((index = 0)) pathPoints = n1x + ',' + n1y; - else pathPoints = pathPoints + ' ' + n1x + ',' + n1y; - } - }); + this.childDocs + .filter(doc => PresBox.targetRenderedDoc(doc)?.embedContainer === collection) + .forEach((doc, index) => { + const tagDoc = PresBox.targetRenderedDoc(doc); + 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.config_pinView) { + const n1x = NumCast(doc.config_panX); + const n1y = NumCast(doc.config_panY); + if ((index = 0)) pathPoints = n1x + ',' + n1y; + else pathPoints = pathPoints + ' ' + n1x + ',' + n1y; + } + }); return ( - <polyline - points={pathPoints} - style={{ - opacity: 1, - stroke: '#69a6db', - strokeWidth: 5, - strokeDasharray: '10 5', - boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)', - }} - fill="none" - markerStart="url(#markerArrow)" - markerMid="url(#markerSquare)" - markerEnd="url(#markerSquareFilled)" - /> + <> + <div className="presPathLabels">{PresBox.Instance?.orderedPathLabels(collection)}</div> + <svg key="svg" className="presPaths"> + <defs> + <marker id="markerSquare" markerWidth="3" markerHeight="3" refX="1.5" refY="1.5" orient="auto" overflow="visible"> + <rect x="0" y="0" width="3" height="3" stroke="#69a6db" strokeWidth="1" fill="white" fillOpacity="0.8" /> + </marker> + <marker id="markerSquareFilled" markerWidth="3" markerHeight="3" refX="1.5" refY="1.5" orient="auto" overflow="visible"> + <rect x="0" y="0" width="3" height="3" stroke="#69a6db" strokeWidth="1" fill="#69a6db" /> + </marker> + <marker id="markerArrow" markerWidth="3" markerHeight="3" refX="2" refY="4" orient="auto" overflow="visible"> + <path d="M2,2 L2,6 L6,4 L2,2 Z" stroke="#69a6db" strokeLinejoin="round" strokeWidth="1" fill="white" fillOpacity="0.8" /> + </marker> + </defs> + <polyline + points={pathPoints} + style={{ + opacity: 1, + stroke: '#69a6db', + strokeWidth: 5, + strokeDasharray: '10 5', + boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)', + }} + fill="none" + markerStart="url(#markerArrow)" + markerMid="url(#markerSquare)" + markerEnd="url(#markerSquareFilled)" + /> + </svg> + </> ); - } - 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 presentation_transition public static SetTransitionTime = (number: String, setter: (timeInMS: number) => void, change?: number) => { let timeInMS = Number(number) * 1000; |
