aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx115
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx136
3 files changed, 95 insertions, 160 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index c90fdf013..250760bd5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -54,10 +54,14 @@
}
}
+ .presPathLabels {
+ pointer-events: none;
+ }
svg.presPaths {
position: absolute;
z-index: 100000;
overflow: visible;
+ pointer-events: none;
}
svg.presPaths-hidden {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 10d0117ef..079f1b9d6 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -128,7 +128,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _marqueeRef: HTMLDivElement | null = null;
@observable _marqueeViewRef = React.createRef<MarqueeView>();
@observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
- @observable _brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 }; // highlighted region of freeform canvas used by presentations to indicate a region
+ @observable _brushedView: { width: number; height: number; panX: number; panY: number } | undefined; // highlighted region of freeform canvas used by presentations to indicate a region
@computed get views() {
const viewsMask = this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z && ele.inkMask !== -1 && ele.inkMask !== undefined).map(ele => ele.ele);
@@ -729,9 +729,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (this._inkToTextStartX && this._inkToTextStartY) {
const end = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y)));
const setDocs = this.getActiveDocuments().filter(s => DocCast(s.proto)?.type === DocumentType.RTF && s.color);
- const sets = setDocs.map(sd => {
- return Cast(sd.text, RichTextField)?.Text as string;
- });
+ const sets = setDocs.map(sd => Cast(sd.text, RichTextField)?.Text as string);
if (sets.length && sets[0]) {
this._wordPalette.clear();
const colors = setDocs.map(sd => FieldValue(sd.color) as string);
@@ -1919,12 +1917,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
showPresPaths = () => (CollectionFreeFormView.ShowPresPaths ? PresBox.Instance.getPaths(this.rootDoc) : null);
-
brushedView = () => this._brushedView;
- gridColor = () => {
- const backColor = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor + ':box');
- return lightOrDark(backColor);
- };
+ gridColor = () => lightOrDark(this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor + ':box'));
@computed get marqueeView() {
TraceMobx();
return (
@@ -1952,7 +1946,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
style={{ opacity: this.props.dontRenderDocuments ? 0.7 : undefined }}>
{this.layoutDoc._freeform_backgroundGrid ? (
<div>
- <CollectionFreeFormBackgroundGrid // bcz : UGHH don't know why, but if we don't wrap in a div, then PDF's don't render whenn taking snapshot of a dashboard and the background grid is on!!?
+ <CollectionFreeFormBackgroundGrid // bcz : UGHH don't know why, but if we don't wrap in a div, then PDF's don't render when taking snapshot of a dashboard and the background grid is on!!?
PanelWidth={this.props.PanelWidth}
PanelHeight={this.props.PanelHeight}
panX={this.panX}
@@ -1968,13 +1962,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
</div>
) : null}
<CollectionFreeFormViewPannableContents
+ rootDoc={this.rootDoc}
brushedView={this.brushedView}
isAnnotationOverlay={this.isAnnotationOverlay}
- isAnnotationOverlayScrollable={this.props.isAnnotationOverlayScrollable}
transform={this.contentTransform}
- zoomScaling={this.zoomScaling}
presPaths={this.showPresPaths}
- presPinView={BoolCast(this.Document.config_pinView)}
transition={this._panZoomTransition ? `transform ${this._panZoomTransition}ms` : Cast(this.layoutDoc._viewTransition, 'string', Cast(this.props.DocumentView?.()?.rootDoc._viewTransition, 'string', null))}
viewDefDivClick={this.props.viewDefDivClick}>
{this.children}
@@ -1999,12 +1991,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
brushView = (viewport: { width: number; height: number; panX: number; panY: number }, transTime: number) => {
this._brushtimer1 && clearTimeout(this._brushtimer1);
this._brushtimer && clearTimeout(this._brushtimer);
- this._brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 };
+ this._brushedView = undefined;
this._brushtimer1 = setTimeout(
action(() => {
- this._brushedView = { ...viewport, panX: viewport.panX - viewport.width / 2, panY: viewport.panY - viewport.height / 2, opacity: 1 };
+ this._brushedView = { ...viewport, panX: viewport.panX - viewport.width / 2, panY: viewport.panY - viewport.height / 2 };
this._brushtimer = setTimeout(
- action(() => (this._brushedView.opacity = 0)),
+ action(() => (this._brushedView = undefined)),
2500
);
}),
@@ -2076,7 +2068,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
{this._firstRender ? this.placeholder : this.marqueeView}
{this.props.noOverlay ? null : <CollectionFreeFormOverlayView elements={this.elementFunc} />}
- {/* // uncomment to show snap lines */}
<div className="snapLines" style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
<svg style={{ width: '100%', height: '100%' }}>
{(this._hLines ?? [])
@@ -2108,69 +2099,22 @@ class CollectionFreeFormOverlayView extends React.Component<CollectionFreeFormOv
}
interface CollectionFreeFormViewPannableContentsProps {
- transform: () => string;
- zoomScaling: () => number;
+ rootDoc: Doc;
viewDefDivClick?: ScriptField;
children?: React.ReactNode | undefined;
- //children: () => JSX.Element[];
transition?: string;
- presPaths: () => JSX.Element | null;
- presPinView?: boolean;
isAnnotationOverlay: boolean | undefined;
- isAnnotationOverlayScrollable: boolean | undefined;
- brushedView: () => { panX: number; panY: number; width: number; height: number; opacity: number };
+ presPaths: () => JSX.Element | null;
+ transform: () => string;
+ brushedView: () => { panX: number; panY: number; width: number; height: number } | undefined;
}
@observer
class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps> {
- @observable _drag: string = '';
-
- //Adds event listener so knows pointer is down and moving
- onPointerDown = (e: React.PointerEvent): void => {
- e.stopPropagation();
- e.preventDefault();
- this._drag = (e.target as any)?.id ?? '';
- document.getElementById(this._drag) && setupMoveUpEvents(e.target, e, this.onPointerMove, emptyFunction, emptyFunction);
- };
-
- //Adjusts the value in NodeStore
- @action
- onPointerMove = (e: PointerEvent) => {
- const doc = document.getElementById('resizable');
- const toNumber = (original: number, delta: number) => original + delta * this.props.zoomScaling();
- if (doc) {
- switch (this._drag) {
- case 'resizer-br':
- doc.style.width = toNumber(doc.offsetWidth, e.movementX) + 'px';
- doc.style.height = toNumber(doc.offsetHeight, e.movementY) + 'px';
- break;
- case 'resizer-bl':
- doc.style.width = toNumber(doc.offsetWidth, -e.movementX) + 'px';
- doc.style.height = toNumber(doc.offsetHeight, e.movementY) + 'px';
- doc.style.left = toNumber(doc.offsetLeft, e.movementX) + 'px';
- break;
- case 'resizer-tr':
- doc.style.width = toNumber(doc.offsetWidth, -e.movementX) + 'px';
- doc.style.height = toNumber(doc.offsetHeight, -e.movementY) + 'px';
- doc.style.top = toNumber(doc.offsetTop, e.movementY) + 'px';
- case 'resizer-tl':
- doc.style.width = toNumber(doc.offsetWidth, -e.movementX) + 'px';
- doc.style.height = toNumber(doc.offsetHeight, -e.movementY) + 'px';
- doc.style.top = toNumber(doc.offsetTop, e.movementY) + 'px';
- doc.style.left = toNumber(doc.offsetLeft, e.movementX) + 'px';
- case 'resizable':
- doc.style.top = toNumber(doc.offsetTop, e.movementY) + 'px';
- doc.style.left = toNumber(doc.offsetLeft, e.movementX) + 'px';
- }
- return false;
- }
- return true;
- };
-
@computed get presPaths() {
return !this.props.presPaths() ? null : (
<>
- <div key="presorder">{PresBox.Instance?.order}</div>
+ <div className="presPathLabels">{PresBox.Instance?.orderedPathLabels(this.props.rootDoc)}</div>
<svg key="svg" className="presPaths">
<defs>
<marker id="markerSquare" markerWidth="3" markerHeight="3" refX="1.5" refY="1.5" orient="auto" overflow="visible">
@@ -2188,39 +2132,40 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
</>
);
}
+ // rectangle highlight used when following trail/link to a region of a collection that isn't a document
+ @computed get brushedView() {
+ const brushedView = this.props.brushedView();
+ return !brushedView ? null : (
+ <div
+ className="collectionFreeFormView-brushView"
+ style={{
+ transform: `translate(${brushedView.panX}px, ${brushedView.panY}px)`,
+ width: brushedView.width,
+ height: brushedView.height,
+ border: `orange solid ${brushedView.width * 0.005}px`,
+ }}
+ />
+ );
+ }
render() {
- const brushedView = this.props.brushedView();
return (
<div
className={'collectionfreeformview' + (this.props.viewDefDivClick ? '-viewDef' : '-none')}
onScroll={e => {
const target = e.target as any;
if (getComputedStyle(target)?.overflow === 'visible') {
- // if collection is visible, then scrolling will mess things up since there are no scroll bars
- target.scrollTop = target.scrollLeft = 0;
+ target.scrollTop = target.scrollLeft = 0; // if collection is visible, scrolling messes things up since there are no scroll bars
}
}}
style={{
transform: this.props.transform(),
transition: this.props.transition,
width: this.props.isAnnotationOverlay ? undefined : 0, // if not an overlay, then this will be the size of the collection, but panning and zooming will move it outside the visible border of the collection and make it selectable. This problem shows up after zooming/panning on a background collection -- you can drag the collection by clicking on apparently empty space outside the collection
- //willChange: "transform"
}}>
{this.props.children}
- {
- <div
- className="collectionFreeFormView-brushView"
- style={{
- opacity: brushedView.opacity,
- transform: `translate(${brushedView.panX}px, ${brushedView.panY}px)`,
- width: brushedView.width,
- height: brushedView.height,
- border: `orange solid ${brushedView.width * 0.005}px`,
- }}
- />
- }
{this.presPaths}
+ {this.brushedView}
</div>
);
}
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 6bbf3208c..6493117b0 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';
@@ -1307,71 +1307,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
@@ -1381,22 +1365,24 @@ 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}
@@ -1413,8 +1399,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
markerEnd="url(#markerSquareFilled)"
/>
);
- }
- 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
+ };
+ getPaths = (collection: Doc) => this.pathLines(collection); // 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) => {