aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DocumentView.tsx')
-rw-r--r--src/client/views/nodes/DocumentView.tsx114
1 files changed, 25 insertions, 89 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c217c9d86..d8a1841b1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -40,6 +40,7 @@ import SharingManager from '../../util/SharingManager';
import { Scripting } from '../../util/Scripting';
import { DictationOverlay } from '../DictationOverlay';
import { CollectionViewType } from '../collections/CollectionBaseView';
+import { DocuLinkView } from './DocuLinkView';
library.add(fa.faEdit);
library.add(fa.faTrash);
@@ -241,6 +242,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onPointerDown = (e: React.PointerEvent): void => {
if (e.nativeEvent.cancelBubble && e.button === 0) return;
+ runInAction(() => this._selectedLink = -1);
this._downX = e.clientX;
this._downY = e.clientY;
this._hitTemplateDrag = false;
@@ -626,6 +628,25 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
layoutKey="layout"
DataDoc={this.props.DataDoc} />);
}
+ linkEndpoint = (linkDoc: Doc) => Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? "anchor1" : "anchor2";
+ linkOtherEndpoint = (linkDoc: Doc) => Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? "anchor2" : "anchor1";
+ public setBackround(color: string) {
+ let selLink = this._selectedLink !== -1 && DocListCast(this.Document.links)[this._selectedLink];
+ if (selLink) {
+ let both = selLink["anchor1_background"] === selLink["anchor2_background"];
+ selLink[this.linkEndpoint(selLink) + "_background"] = color;
+ both && (selLink[this.linkOtherEndpoint(selLink) + "_background"] = color);
+ } else {
+ this.Document.backgroundColor = color;
+ }
+ }
+ @observable _selectedLink = -1;
+ selectLink = action((which: number) => {
+ SelectionManager.SelectDoc(this, false);
+ this._selectedLink = which;
+ })
+ selectedLink = () => this._selectedLink;
+
render() {
if (!this.props.Document) return (null);
let animDims = this.props.Document.animateToDimensions ? Array.from(Cast(this.props.Document.animateToDimensions, listSpec("number"))!) : undefined;
@@ -696,7 +717,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
onPointerEnter={() => Doc.BrushDoc(this.props.Document)} onPointerLeave={() => Doc.UnBrushDoc(this.props.Document)}
>
- {this.props.Document.links && DocListCast(this.props.Document.links).map((d, i) => <DocuLink view={this} link={d} index={i} />)}
+ {this.props.Document.links && DocListCast(this.props.Document.links).map((d, i) =>
+ <DocuLinkView Document={this.props.Document} blacklist={this.props.ContainingCollectionDoc} anchor={this.linkEndpoint(d)} otherAnchor={this.linkOtherEndpoint(d)} addDocTab={this.props.addDocTab} contentDiv={this.ContentDiv}
+ scale={this.props.ContentScaling}
+ isSelected={this.isSelected} link={d} index={i} selectLink={this.selectLink} selectedLink={this.selectedLink} />)}
{!showTitle && !showCaption ?
this.Document.searchFields ?
(<div className="documentView-searchWrapper">
@@ -720,94 +744,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
}
-
-interface DocuLinkProps {
- view: DocumentView;
- link: Doc;
- index: number;
-}
-
-@observer
-export class DocuLink extends React.Component<DocuLinkProps> {
- _downx = 0;
- _downy = 0;
- @observable _x = 0;
- @observable _y = 0;
-
- constructor(props: DocuLinkProps) {
- super(props);
- }
-
- clamp(n: number, lower: number, upper: number) {
- return Math.max(lower, Math.min(upper, n));
- }
-
- getNearestPointInPerimeter(l: number, t: number, w: number, h: number, x: number, y: number) {
- var r = l + w,
- b = t + h;
-
- var x = this.clamp(x, l, r),
- y = this.clamp(y, t, b);
-
- var dl = Math.abs(x - l),
- dr = Math.abs(x - r),
- dt = Math.abs(y - t),
- db = Math.abs(y - b);
-
- var m = Math.min(dl, dr, dt, db);
-
- return (m === dt) ? [x, t] :
- (m === db) ? [x, b] :
- (m === dl) ? [l, y] : [r, y];
- }
-
- get linkEndpoint() {
- return Doc.AreProtosEqual(this.props.view.props.Document, Cast(this.props.link.anchor1, Doc) as Doc) ?
- "anchor1" : "anchor2";
- }
- get linkOtherEndpoint() {
- return !Doc.AreProtosEqual(this.props.view.props.Document, Cast(this.props.link.anchor1, Doc) as Doc) ?
- "anchor1" : "anchor2";
- }
-
- onPointerDown = (e: React.PointerEvent) => {
- this._downx = e.clientX;
- this._downy = e.clientY;
- document.removeEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- document.addEventListener("pointermove", this.onPointerMove);
- document.addEventListener("pointerup", this.onPointerUp);
- e.stopPropagation();
- }
- onPointerMove = action((e: PointerEvent) => {
- if (this.props.view.ContentDiv && (Math.abs(e.clientX - this._downx) > 3 || Math.abs(e.clientY - this._downy) > 3)) {
- let bounds = this.props.view.ContentDiv.getBoundingClientRect();
- let pt = this.getNearestPointInPerimeter(bounds.left - 25, bounds.top - 25, bounds.width, bounds.height, e.clientX, e.clientY);
- this.props.link[this.linkEndpoint + "_x"] = (pt[0] - bounds.left) / bounds.width * 100;
- this.props.link[this.linkEndpoint + "_y"] = (pt[1] - bounds.top) / bounds.height * 100;
- }
- })
- onPointerUp = (e: PointerEvent) => {
- document.removeEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- }
- onClick = (e: React.MouseEvent) => {
- if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3) {
- DocumentManager.Instance.FollowLink(this.props.link, this.props.view.props.Document, document => this.props.view.props.addDocTab(document, undefined, "inTab"), false);
- }
- e.stopPropagation();
- }
- render() {
- return <div onPointerDown={this.onPointerDown} title={StrCast((this.props.link[this.linkOtherEndpoint]! as Doc).title)} style={{
- position: "absolute", background: "lightblue", width: "25px", height: "25px", borderRadius: "20px",
- left: `${NumCast(this.props.link[this.linkEndpoint + "_x"], 100)}%`, top: `${NumCast(this.props.link[this.linkEndpoint + "_y"], 100)}%`
- }} >
- {this.props.index}
- </div>
- }
-}
-
-
export async function swapViews(doc: Doc, newLayoutField: string, oldLayoutField: string, oldLayout?: Doc) {
let oldLayoutExt = oldLayout || await Cast(doc[oldLayoutField], Doc);
if (oldLayoutExt) {