From 69d822d6c68b69e5bfeeff03942ea9bab71cecc3 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 15 Oct 2019 00:36:35 -0400 Subject: tweak to linearView layouts with onClick items --- src/client/documents/DocumentTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 432e53825..03178bbdb 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -17,7 +17,7 @@ export enum DocumentType { TEMPLATE = "template", EXTENSION = "extension", YOUTUBE = "youtube", - FONTICONBOX = "fonticonbox", + FONTICON = "fonticonbox", PRES = "presentation", LINKFOLLOW = "linkfollow", PRESELEMENT = "preselement", -- cgit v1.2.3-70-g09d2 From fca8d503610f799ca0e4afcec114075456d411e0 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 17 Oct 2019 16:48:39 -0400 Subject: switched links over to be a document --- src/Utils.ts | 2 + src/client/documents/DocumentTypes.ts | 1 + src/client/documents/Documents.ts | 5 ++ src/client/views/DocumentDecorations.tsx | 3 +- src/client/views/InkingControl.tsx | 2 +- src/client/views/nodes/DocuLinkBox.tsx | 77 ++++++++++++++++++++++ src/client/views/nodes/DocuLinkView.tsx | 85 ------------------------- src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 31 ++------- 9 files changed, 94 insertions(+), 115 deletions(-) create mode 100644 src/client/views/nodes/DocuLinkBox.tsx delete mode 100644 src/client/views/nodes/DocuLinkView.tsx (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/Utils.ts b/src/Utils.ts index 66ed8be5d..7bb025e49 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -289,6 +289,8 @@ export function percent2frac(percent: string) { export function numberRange(num: number) { return Array.from(Array(num)).map((v, i) => i); } +export function returnTransparent() { return "transparent"; } + export function returnTrue() { return true; } export function returnFalse() { return false; } diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 03178bbdb..ea37fc2f1 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -23,4 +23,5 @@ export enum DocumentType { PRESELEMENT = "preselement", QUERY = "search", COLOR = "color", + DOCULINK = "doculink" } \ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 62175cbe3..edc2ac653 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -47,6 +47,7 @@ import { LinkFollowBox } from "../views/linking/LinkFollowBox"; import { PresElementBox } from "../views/presentationview/PresElementBox"; import { QueryBox } from "../views/nodes/QueryBox"; import { ColorBox } from "../views/nodes/ColorBox"; +import { DocuLinkBox } from "../views/nodes/DocuLinkBox"; var requestImageSize = require('../util/request-image-size'); var path = require('path'); @@ -719,6 +720,10 @@ export namespace DocUtils { linkDocProto.anchor2Context = target.ctx; linkDocProto.anchor2Groups = new List([]); linkDocProto.anchor2Timecode = target.doc.currentTimecode; + linkDocProto.layoutKey1 = DocuLinkBox.LayoutString("anchor1"); + linkDocProto.layoutKey2 = DocuLinkBox.LayoutString("anchor2"); + linkDocProto.width = linkDocProto.height = 0; + linkDocProto.isBackground = true; LinkManager.Instance.addLink(linkDocProto); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 927729487..6e8ba2d3d 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -167,8 +167,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> get Bounds(): { x: number, y: number, b: number, r: number } { let x = this._forceUpdate; this._lastBox = SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { - if (documentView._selectedLink !== -1 || - documentView.props.renderDepth === 0 || + if (documentView.props.renderDepth === 0 || Doc.AreProtosEqual(documentView.props.Document, CurrentUserUtils.UserDocument)) { return bounds; } diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index 1aacdc8ec..c3a617ffe 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -81,7 +81,7 @@ export class InkingControl { ruleProvider = (view.props.Document.heading && ruleProvider) ? ruleProvider : undefined; ruleProvider && ((Doc.GetProto(ruleProvider)["ruleColor_" + NumCast(view.props.Document.heading)] = Utils.toRGBAstr(color.rgb))); } - (!ruleProvider && targetDoc) && (view.setBackround(matchedColor)); + (!ruleProvider && targetDoc) && (view.props.Document.backgroundColor = matchedColor); return { target: targetDoc, diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx new file mode 100644 index 000000000..2e968a9f6 --- /dev/null +++ b/src/client/views/nodes/DocuLinkBox.tsx @@ -0,0 +1,77 @@ +import { action, observable } from "mobx"; +import { observer } from "mobx-react"; +import { Doc } from "../../../new_fields/Doc"; +import { makeInterface } from "../../../new_fields/Schema"; +import { NumCast, StrCast } from "../../../new_fields/Types"; +import { Utils } from '../../../Utils'; +import { DocumentManager } from "../../util/DocumentManager"; +import { DragLinksAsDocuments } from "../../util/DragManager"; +import { DocComponent } from "../DocComponent"; +import { documentSchema } from "./DocumentView"; +import "./DocumentView.scss"; +import { FieldView, FieldViewProps } from "./FieldView"; +import React = require("react"); + +type DocLinkSchema = makeInterface<[typeof documentSchema]>; +const DocLinkDocument = makeInterface(documentSchema); + +@observer +export class DocuLinkBox extends DocComponent(DocLinkDocument) { + public static LayoutString(fieldKey: string, fieldExt?: string) { return FieldView.LayoutString(DocuLinkBox, fieldKey, fieldExt); } + _downx = 0; + _downy = 0; + @observable _x = 0; + @observable _y = 0; + @observable _selected = false; + _ref = React.createRef(); + + 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) => { + let cdiv = this._ref.current!.parentElement; + if (cdiv && (Math.abs(e.clientX - this._downx) > 5 || Math.abs(e.clientY - this._downy) > 5)) { + let bounds = cdiv.getBoundingClientRect(); + let pt = Utils.getNearestPointInPerimeter(bounds.left, bounds.top, bounds.width, bounds.height, e.clientX, e.clientY); + let separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY)); + let dragdist = Math.sqrt((pt[0] - this._downx) * (pt[0] - this._downx) + (pt[1] - this._downy) * (pt[1] - this._downy)) + if (separation > 100) { + DragLinksAsDocuments(this._ref.current!, pt[0], pt[1], this.props.ContainingCollectionDoc as Doc, this.props.Document); // Containging collection is the document, not a collection... hack. + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + } else if (dragdist > separation) { + this.props.Document[this.props.fieldKey + "_x"] = (pt[0] - bounds.left) / bounds.width * 100; + this.props.Document[this.props.fieldKey + "_y"] = (pt[1] - bounds.top) / bounds.height * 100; + } + } + }) + onPointerUp = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button === 2 || e.ctrlKey)) { + this.props.select(false); + } + } + onClick = (e: React.MouseEvent) => { + if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button !== 2 && !e.ctrlKey)) { + DocumentManager.Instance.FollowLink(this.props.Document, this.props.Document[this.props.fieldKey] as Doc, document => this.props.addDocTab(document, undefined, "inTab"), false); + } + e.stopPropagation(); + } + render() { + let y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100); + let x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100); + let c = StrCast(this.props.Document.backgroundColor, "lightblue"); + return
+ } +} diff --git a/src/client/views/nodes/DocuLinkView.tsx b/src/client/views/nodes/DocuLinkView.tsx deleted file mode 100644 index 622d41047..000000000 --- a/src/client/views/nodes/DocuLinkView.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { action, observable } from "mobx"; -import { observer } from "mobx-react"; -import { Doc, Opt } from "../../../new_fields/Doc"; -import { NumCast, StrCast } from "../../../new_fields/Types"; -import { Utils } from '../../../Utils'; -import { DocumentManager } from "../../util/DocumentManager"; -import "./DocumentView.scss"; -import React = require("react"); -import { DragManager, DragLinksAsDocuments } from "../../util/DragManager"; -import { UndoManager } from "../../util/UndoManager"; - - -interface DocuLinkViewProps { - Document: Doc; - isSelected: () => boolean; - addDocTab: (doc: Doc, dataDoc: Opt, where: string) => void; - anchor: string; - otherAnchor: string; - scale: () => number; - contentDiv: HTMLDivElement | null; - link: Doc; - index: number; - selectedLink: () => number; - selectLink: (id: number) => void; - blacklist: Opt -} - -@observer -export class DocuLinkView extends React.Component { - _downx = 0; - _downy = 0; - @observable _x = 0; - @observable _y = 0; - @observable _selected = false; - _ref = React.createRef(); - - 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.contentDiv && (Math.abs(e.clientX - this._downx) > 5 || Math.abs(e.clientY - this._downy) > 5)) { - let bounds = this.props.contentDiv.getBoundingClientRect(); - let pt = Utils.getNearestPointInPerimeter(bounds.left, bounds.top, bounds.width, bounds.height, e.clientX, e.clientY); - let separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY)); - let dragdist = Math.sqrt((pt[0] - this._downx) * (pt[0] - this._downx) + (pt[1] - this._downy) * (pt[1] - this._downy)) - if (separation > 100) { - DragLinksAsDocuments(this._ref.current!, pt[0], pt[1], this.props.Document, this.props.link); - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - } else if (dragdist > separation) { - this.props.link[this.props.anchor + "_x"] = (pt[0] - bounds.left) / bounds.width * 100; - this.props.link[this.props.anchor + "_y"] = (pt[1] - bounds.top) / bounds.height * 100; - } - } - }) - onPointerUp = (e: PointerEvent) => { - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button === 2 || e.ctrlKey)) { - this.props.selectLink(this.props.selectedLink() === this.props.index ? -1 : this.props.index); - } - } - onClick = (e: React.MouseEvent) => { - if (Math.abs(e.clientX - this._downx) < 3 && Math.abs(e.clientY - this._downy) < 3 && (e.button !== 2 && !e.ctrlKey)) { - DocumentManager.Instance.FollowLink(this.props.link, this.props.link[this.props.anchor] as Doc, document => this.props.addDocTab(document, undefined, "inTab"), false); - } - e.stopPropagation(); - } - render() { - let y = NumCast(this.props.link[this.props.anchor + "_y"], 100); - let x = NumCast(this.props.link[this.props.anchor + "_x"], 100); - let c = StrCast(this.props.link[this.props.anchor + "_background"], "lightblue"); - return
- } -} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 19ffdf0cd..4971e6ce5 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -26,6 +26,7 @@ import { PDFBox } from "./PDFBox"; import { PresBox } from "./PresBox"; import { QueryBox } from "./QueryBox"; import { ColorBox } from "./ColorBox"; +import { DocuLinkBox } from "./DocuLinkBox"; import { PresElementBox } from "../presentationview/PresElementBox"; import { VideoBox } from "./VideoBox"; import { WebBox } from "./WebBox"; @@ -104,7 +105,7 @@ export class DocumentContentsView extends React.Component number; animateBetweenIcon?: (maximize: boolean, target: number[]) => void; ChromeHeight?: () => number; + layoutKey?: string; } export const documentSchema = createSchema({ @@ -242,7 +242,6 @@ export class DocumentView extends DocComponent(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; @@ -625,27 +624,10 @@ export class DocumentView extends DocComponent(Docu isSelected={this.isSelected} select={this.select} onClick={this.onClickHandler} - layoutKey="layout" + layoutKey={this.props.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; + linkEndpoint = (linkDoc: Doc) => Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; render() { if (!this.props.Document) return (null); @@ -717,10 +699,7 @@ export class DocumentView extends DocComponent(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) => - )} + {this.props.Document.links && DocListCast(this.props.Document.links).map((d, i) => )} {!showTitle && !showCaption ? this.Document.searchFields ? (
-- cgit v1.2.3-70-g09d2 From 11537da75c76fba79a2709d2ad175dfa16a25256 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 18 Oct 2019 14:00:25 -0400 Subject: fixes for drawing link anchors to pdf text selections. --- src/client/documents/DocumentTypes.ts | 3 ++- src/client/util/DocumentManager.ts | 9 +++++---- src/client/util/LinkManager.ts | 19 +++++++------------ src/client/views/MainView.tsx | 3 ++- src/client/views/nodes/DocuLinkBox.tsx | 7 +++++-- src/client/views/nodes/DocumentView.scss | 3 --- src/client/views/nodes/DocumentView.tsx | 2 ++ src/client/views/pdf/Annotation.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 6 ++++++ 9 files changed, 30 insertions(+), 24 deletions(-) (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index ea37fc2f1..12501065a 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -23,5 +23,6 @@ export enum DocumentType { PRESELEMENT = "preselement", QUERY = "search", COLOR = "color", - DOCULINK = "doculink" + DOCULINK = "doculink", + PDFANNO = "pdfanno" } \ No newline at end of file diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ee6772f8f..0f2a47dd0 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -100,10 +100,11 @@ export class DocumentManager { @computed public get LinkedDocumentViews() { - let pairs = DocumentManager.Instance.DocumentViews.filter(dv => dv.isSelected() || Doc.IsBrushed(dv.props.Document) - || DocumentManager.Instance.DocumentViews.some(dv2 => { - let init = dv2.isSelected() || Doc.IsBrushed(dv2.props.Document); - let rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document)); + let pairs = DocumentManager.Instance.DocumentViews.filter(dv => + dv.isSelected() || Doc.IsBrushed(dv.props.Document) // draw links from DocumentViews that are selected or brushed OR + || DocumentManager.Instance.DocumentViews.some(dv2 => { // Documentviews which + let rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document));// are link doc anchors + let init = dv2.isSelected() || Doc.IsBrushed(dv2.props.Document); // on a view that is selected or brushed return init && rest; }) ).reduce((pairs, dv) => { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 35c0f023f..ee2f2dadc 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -1,10 +1,7 @@ -import { observable, action } from "mobx"; -import { StrCast, Cast, FieldValue } from "../../new_fields/Types"; import { Doc, DocListCast } from "../../new_fields/Doc"; -import { listSpec } from "../../new_fields/Schema"; import { List } from "../../new_fields/List"; -import { Id } from "../../new_fields/FieldSymbols"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { listSpec } from "../../new_fields/Schema"; +import { Cast, StrCast } from "../../new_fields/Types"; import { Docs } from "../documents/Documents"; import { Scripting } from "./Scripting"; @@ -242,13 +239,11 @@ export class LinkManager { //TODO This should probably return undefined if there isn't an opposite anchor //TODO This should also await the return value of the anchor so we don't filter out promises public getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined { - if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) { - return Cast(linkDoc.anchor2, Doc, null); - } else if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor2, Doc, null))) { - return Cast(linkDoc.anchor1, Doc, null); - } else if (Doc.AreProtosEqual(anchor, linkDoc)) { - return linkDoc; - } + let a1 = Cast(linkDoc.anchor1, Doc, null); + let a2 = Cast(linkDoc.anchor2, Doc, null); + if (Doc.AreProtosEqual(anchor, a1)) return a2; + if (Doc.AreProtosEqual(anchor, a2)) return a1; + if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc; } } Scripting.addGlobal(function links(doc: any) { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 9304f4bef..4c2b6f262 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -183,7 +183,8 @@ export class MainView extends React.Component { y: 400, width: this._panelWidth * .7, height: this._panelHeight, - title: "My Blank Collection" + title: "My Blank Collection", + backgroundColor: "white" }; let workspaces: FieldResult; let freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx index f56bf4ad3..3294a5aa2 100644 --- a/src/client/views/nodes/DocuLinkBox.tsx +++ b/src/client/views/nodes/DocuLinkBox.tsx @@ -2,7 +2,7 @@ import { action, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../new_fields/Doc"; import { makeInterface } from "../../../new_fields/Schema"; -import { NumCast, StrCast } from "../../../new_fields/Types"; +import { NumCast, StrCast, Cast } from "../../../new_fields/Types"; import { Utils } from '../../../Utils'; import { DocumentManager } from "../../util/DocumentManager"; import { DragLinksAsDocuments } from "../../util/DragManager"; @@ -11,6 +11,7 @@ import { documentSchema } from "./DocumentView"; import "./DocuLinkBox.scss"; import { FieldView, FieldViewProps } from "./FieldView"; import React = require("react"); +import { DocumentType } from "../../documents/DocumentTypes"; type DocLinkSchema = makeInterface<[typeof documentSchema]>; const DocLinkDocument = makeInterface(documentSchema); @@ -65,13 +66,15 @@ export class DocuLinkBox extends DocComponent(Doc e.stopPropagation(); } render() { + let anchorDoc = Cast(this.props.Document[this.props.fieldKey], Doc); + let hasAnchor = anchorDoc instanceof Doc && anchorDoc.type === DocumentType.PDFANNO; let y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100); let x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100); let c = StrCast(this.props.Document.backgroundColor, "lightblue"); return
; } } diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 69eb1a843..a0bf74990 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -47,9 +47,6 @@ } } } -.documentView-node-topmost { - background: white; -} .documentView-styleWrapper { position: absolute; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 48ad7a632..8bf698391 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -629,6 +629,7 @@ export class DocumentView extends DocComponent(Docu DataDoc={this.props.DataDoc} />); } linkEndpoint = (linkDoc: Doc) => Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; + linkEndpointDoc = (linkDoc: Doc) => Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? Cast(linkDoc.anchor1, Doc) as Doc : Cast(linkDoc.anchor2, Doc) as Doc; render() { if (!this.props.Document) return (null); @@ -701,6 +702,7 @@ export class DocumentView extends DocComponent(Docu onPointerEnter={() => Doc.BrushDoc(this.props.Document)} onPointerLeave={() => Doc.UnBrushDoc(this.props.Document)} > {this.props.Document.links && DocListCast(this.props.Document.links).map((d, i) => + //this.linkEndpointDoc(d).type === DocumentType.PDFANNO ? (null) :
)} diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index ad6240c70..e0a3b9171 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -100,7 +100,7 @@ class RegionAnnotation extends React.Component { let annoGroup = await Cast(this.props.document.group, Doc); if (annoGroup) { DocumentManager.Instance.FollowLink(undefined, annoGroup, - (doc: Doc, maxLocation: string) => this.props.addDocTab(doc, undefined, e.ctrlKey ? "onRight" : "inTab"), + (doc: Doc, maxLocation: string) => this.props.addDocTab(doc, undefined, e.ctrlKey ? "inTab" : "onRight"), false, false, undefined); } } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 1bae6128c..6e5f1a981 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -25,6 +25,7 @@ import { SelectionManager } from "../../util/SelectionManager"; import { undoBatch } from "../../util/UndoManager"; import { DocAnnotatableComponent } from "../DocComponent"; import { documentSchema } from "../nodes/DocumentView"; +import { DocumentType } from "../../documents/DocumentTypes"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); @@ -249,6 +250,7 @@ export class PDFViewer extends DocAnnotatableComponent(annoDocs); } mainAnnoDocProto.title = "Annotation on " + StrCast(this.props.Document.title); -- cgit v1.2.3-70-g09d2 From 563a8926c0646e9907c8a4eec2e648ab5ae79e02 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sat, 9 Nov 2019 16:27:07 -0500 Subject: hey, Sam's pushing these changes --- src/client/documents/DocumentTypes.ts | 3 +- src/client/documents/Documents.ts | 4 ++ src/client/views/InkingCanvas.tsx | 64 +++++++++++----------- src/client/views/InkingStroke.tsx | 13 +++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 45 ++++++++++----- src/client/views/nodes/DocumentContentsView.tsx | 2 +- 6 files changed, 79 insertions(+), 52 deletions(-) (limited to 'src/client/documents/DocumentTypes.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 12501065a..f6dd0c346 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -24,5 +24,6 @@ export enum DocumentType { QUERY = "search", COLOR = "color", DOCULINK = "doculink", - PDFANNO = "pdfanno" + PDFANNO = "pdfanno", + INK = "ink" } \ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d1fcabc4a..2c6b40cb9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -411,6 +411,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.TEXT), "", options); } + export function InkDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.INK), "", options); + } + export function IconDocument(icon: string, options: DocumentOptions = {}) { return InstanceFromProto(Prototypes.get(DocumentType.ICON), new IconField(icon), options); } diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 5c17696c8..a0ea37300 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -170,37 +170,37 @@ export class InkingCanvas extends Touchable { this.inkData = data; } - @computed - get drawnPaths() { - let curTimecode = NumCast(this.props.Document.currentTimecode, -1); - let paths = Array.from(this.inkData).reduce((paths, [id, strokeData]) => { - if (strokeData.displayTimecode === -1 || (Math.abs(Math.round(strokeData.displayTimecode) - Math.round(curTimecode)) < 3)) { - paths.push(); - } - return paths; - }, [] as JSX.Element[]); - let markerPaths = paths.filter(path => path.props.tool === InkTool.Highlighter); - let penPaths = paths.filter(path => path.props.tool !== InkTool.Highlighter); - return [!penPaths.length ? (null) : - - {penPaths} - , - !markerPaths.length ? (null) : - - {markerPaths} - ]; - } + // @computed + // get drawnPaths() { + // let curTimecode = NumCast(this.props.Document.currentTimecode, -1); + // let paths = Array.from(this.inkData).reduce((paths, [id, strokeData]) => { + // if (strokeData.displayTimecode === -1 || (Math.abs(Math.round(strokeData.displayTimecode) - Math.round(curTimecode)) < 3)) { + // paths.push(); + // } + // return paths; + // }, [] as JSX.Element[]); + // let markerPaths = paths.filter(path => path.props.tool === InkTool.Highlighter); + // let penPaths = paths.filter(path => path.props.tool !== InkTool.Highlighter); + // return [!penPaths.length ? (null) : + // + // {penPaths} + // , + // !markerPaths.length ? (null) : + // + // {markerPaths} + // ]; + // } render() { let svgCanvasStyle = InkingControl.Instance.selectedTool !== InkTool.None && !this.props.Document.isBackground ? "canSelect" : "noSelect"; @@ -210,7 +210,7 @@ export class InkingCanvas extends Touchable {
{this.props.children()} - {this.drawnPaths} + {/* {this.drawnPaths} */}
); } diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index a097a7991..824f40b1f 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -6,6 +6,10 @@ import { InkTool } from "../../new_fields/InkField"; import "./InkingStroke.scss"; import { AudioBox } from "./nodes/AudioBox"; import { Doc } from "../../new_fields/Doc"; +import { createSchema, makeInterface } from "../../new_fields/Schema"; +import { documentSchema } from "../../new_fields/documentSchemas"; +import { DocExtendableComponent } from "./DocComponent"; +import { FieldViewProps, FieldView } from "./nodes/FieldView"; interface StrokeProps { @@ -21,13 +25,12 @@ interface StrokeProps { deleteCallback: (index: string) => void; } -export type InkDocAndStroke = { - Document: Doc; - Ink: Map; -}; +type InkDocument = makeInterface<[typeof documentSchema]>; +const InkDocument = makeInterface(documentSchema); @observer -export class InkingStroke extends React.Component { +export class InkingStroke extends DocExtendableComponent(InkDocument) { + public static LayoutString(fieldStr: string) { return FieldView.LayoutString(InkingStroke, fieldStr); } @observable private _strokeTool: InkTool = this.props.tool; @observable private _strokeColor: string = this.props.color; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9acffc952..8294eaaec 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -5,7 +5,7 @@ import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc"; import { Id } from "../../../../new_fields/FieldSymbols"; -import { InkField, StrokeData } from "../../../../new_fields/InkField"; +import { InkField, StrokeData, InkTool } from "../../../../new_fields/InkField"; import { createSchema, makeInterface } from "../../../../new_fields/Schema"; import { ScriptField } from "../../../../new_fields/ScriptField"; import { BoolCast, Cast, DateCast, NumCast, StrCast } from "../../../../new_fields/Types"; @@ -39,6 +39,7 @@ import { InteractionUtils } from "../../../util/InteractionUtils"; import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import PDFMenu from "../../pdf/PDFMenu"; import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas"; +import { InkingControl } from "../../InkingControl"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -263,6 +264,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return clusterColor; } + @observable private _points: { x: number, y: number }[] = []; + @action onPointerDown = (e: React.PointerEvent): void => { if (e.nativeEvent.cancelBubble) return; @@ -272,8 +275,18 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointermove", this.onPointerMove); document.addEventListener("pointerup", this.onPointerUp); - this._lastX = e.pageX; - this._lastY = e.pageY; + if (InkingControl.Instance.selectedTool === InkTool.None) { + this._lastX = e.pageX; + this._lastY = e.pageY; + } + else { + e.stopPropagation(); + e.preventDefault(); + + if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) { + this._points.push({ x: e.pageX, y: e.pageY }); + } + } } } @@ -340,14 +353,19 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return; } if (!e.cancelBubble) { - if (this._hitCluster && this.tryDragCluster(e)) { - e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers - e.preventDefault(); - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - return; + if (InkingControl.Instance.selectedTool === InkTool.None) { + if (this._hitCluster && this.tryDragCluster(e)) { + e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers + e.preventDefault(); + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + return; + } + this.pan(e); + } + if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) { + this._points.push({ x: e.clientX, y: e.clientY }); } - this.pan(e); e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers e.preventDefault(); } @@ -789,9 +807,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { {!this.extensionDoc ? (null) : - - {this.childViews} - } + // + this.childViews + // + } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 96271cfe1..12ae5b6e5 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -99,7 +99,7 @@ export class DocumentContentsView extends React.Component