aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/MarqueeAnnotator.tsx60
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx73
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx15
-rw-r--r--src/client/views/pdf/PDFViewer.tsx4
4 files changed, 61 insertions, 91 deletions
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 03afbe7bf..6e8f9a2df 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -58,6 +58,36 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
this._height = this._width = 0;
document.addEventListener("pointermove", this.onSelectMove);
document.addEventListener("pointerup", this.onSelectEnd);
+
+ AnchorMenu.Instance.Highlight = this.highlight;
+ /**
+ * This function is used by the AnchorMenu to create an anchor highlight and a new linked text annotation.
+ * It also initiates a Drag/Drop interaction to place the text annotation.
+ */
+ AnchorMenu.Instance.StartDrag = action(async (e: PointerEvent, ele: HTMLElement) => {
+ e.preventDefault();
+ e.stopPropagation();
+ const targetCreator = () => {
+ const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.props.rootDoc.title, 0, 0, 100, 100);
+ FormattedTextBox.SelectOnLoad = target[Id];
+ return target;
+ };
+ const anchorCreator = () => {
+ const annoDoc = this.highlight("rgba(173, 216, 230, 0.75)"); // hyperlink color
+ annoDoc.isLinkButton = true; // prevents link button from showing up --- maybe not a good thing?
+ this.props.addDocument(annoDoc);
+ return annoDoc;
+ };
+ DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.rootDoc, anchorCreator, targetCreator), e.pageX, e.pageY, {
+ dragComplete: e => {
+ if (!e.aborted && e.annoDragData && e.annoDragData.annotationDocument && e.annoDragData.dropDocument && !e.linkDocument) {
+ e.linkDocument = DocUtils.MakeLink({ doc: e.annoDragData.annotationDocument }, { doc: e.annoDragData.dropDocument }, "Annotation");
+ e.annoDragData.annotationDocument.isPushpin = e.annoDragData?.dropDocument.annotationOn === this.props.rootDoc;
+ }
+ e.linkDocument && e.annoDragData?.linkDropCallback?.(e as { linkDocument: Doc });// bcz: typescript can't figure out that this is valid even though we tested e.linkDocument
+ }
+ });
+ });
}
componentWillUnmount() {
document.removeEventListener("pointermove", this.onSelectMove);
@@ -154,36 +184,6 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
AnchorMenu.Instance.Marquee = { left: this._left, top: this._top, width: this._width, height: this._height };
}
- AnchorMenu.Instance.Highlight = this.highlight;
- /**
- * This function is used by the AnchorMenu to create an anchor highlight and a new linked text annotation.
- * It also initiates a Drag/Drop interaction to place the text annotation.
- */
- AnchorMenu.Instance.StartDrag = action(async (e: PointerEvent, ele: HTMLElement) => {
- e.preventDefault();
- e.stopPropagation();
- const targetCreator = () => {
- const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.props.rootDoc.title, 0, 0, 100, 100);
- FormattedTextBox.SelectOnLoad = target[Id];
- return target;
- };
- const anchorCreator = () => {
- const annoDoc = this.highlight("rgba(173, 216, 230, 0.75)"); // hyperlink color
- annoDoc.isLinkButton = true; // prevents link button from showing up --- maybe not a good thing?
- this.props.addDocument(annoDoc);
- return annoDoc;
- };
- DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.rootDoc, anchorCreator, targetCreator), e.pageX, e.pageY, {
- dragComplete: e => {
- if (!e.aborted && e.annoDragData && e.annoDragData.annotationDocument && e.annoDragData.dropDocument && !e.linkDocument) {
- e.linkDocument = DocUtils.MakeLink({ doc: e.annoDragData.annotationDocument }, { doc: e.annoDragData.dropDocument }, "Annotation");
- e.annoDragData.annotationDocument.isPushpin = e.annoDragData?.dropDocument.annotationOn === this.props.rootDoc;
- }
- e.linkDocument && e.annoDragData?.linkDropCallback?.(e as { linkDocument: Doc });// bcz: typescript can't figure out that this is valid even though we tested e.linkDocument
- }
- });
- });
-
if (this._width > 10 || this._height > 10) { // configure and show the annotation/link menu if a the drag region is big enough
const marquees = this.props.mainCont.getElementsByClassName("marqueeAnnotator-dragBox");
if (marquees?.length) { // copy the temporary marquee to allow for multiple selections (not currently available though).
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 9041d9b21..d9cd4fd4e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -175,9 +175,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
addDocument = (newBox: Doc | Doc[]) => {
let retVal = false;
if (newBox instanceof Doc) {
- retVal = this.props.addDocument?.(newBox) || false;
- retVal && this.bringToFront(newBox);
- retVal && this.updateCluster(newBox);
+ if (retVal = this.props.addDocument?.(newBox) || false) {
+ this.bringToFront(newBox);
+ this.updateCluster(newBox);
+ }
} else {
retVal = this.props.addDocument?.(newBox) || false;
// bcz: deal with clusters
@@ -267,11 +268,9 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@undoBatch
internalAnchorAnnoDrop(e: Event, annoDragData: DragManager.AnchorAnnoDragData, xp: number, yp: number) {
- const dragDoc = annoDragData.dropDocument!;
- const dropPos = [NumCast(dragDoc.x), NumCast(dragDoc.y)];
- dragDoc.x = xp - annoDragData.offset[0] + (NumCast(dragDoc.x) - dropPos[0]);
- dragDoc.y = yp - annoDragData.offset[1] + (NumCast(dragDoc.y) - dropPos[1]);
- this.bringToFront(dragDoc);
+ annoDragData.dropDocument!.x = xp - annoDragData.offset[0];
+ annoDragData.dropDocument!.y = yp - annoDragData.offset[1];
+ this.bringToFront(annoDragData.dropDocument!);
return true;
}
@@ -636,26 +635,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@action
onPointerMove = (e: PointerEvent): void => {
+ if (this.props.Document._isGroup) return; // groups don't pan when dragged -- instead let the event go through to allow the group itself to drag
+ if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) return;
if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) {
- if (this.props.active(true)) {
- e.stopPropagation();
- }
- return;
- }
- if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
- return;
- }
- if (!e.cancelBubble) {
- if (this.props.Document._isGroup) return; // groups don't pan when dragged -- instead let the event go through to allow the group itself to drag
+ if (this.props.active(true)) e.stopPropagation();
+ } else if (!e.cancelBubble) {
if (Doc.GetSelectedTool() === InkTool.None) {
if (this.tryDragCluster(e, this._hitCluster)) {
- 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;
}
- (!MarqueeView.DragMarquee || e.altKey) && this.pan(e);
+ else 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();
@@ -821,18 +811,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming
e.stopPropagation();
}
- else if (this.props.active(true)) {
- if (!e.ctrlKey && MarqueeView.DragMarquee) {
- this.setPan(this.panX() + e.deltaX, this.panY() + e.deltaY, "None", true);
- e.stopPropagation();
- e.preventDefault();
- }
- else if (!this.Document._isGroup) {
- e.stopPropagation();
- e.preventDefault();
- this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
- }
-
+ else if (this.props.active(true) && !this.Document._isGroup) {
+ e.stopPropagation();
+ e.preventDefault();
+ this.zoom(e.clientX, e.clientY, e.deltaY); // if (!this.props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
}
this.props.Document.targetScale = NumCast(this.props.Document[this.scaleFieldKey]);
}
@@ -1301,22 +1283,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@undoBatch
layoutDocsInGrid = () => {
- const docs = this.childLayoutPairs;
- const startX = this.Document._panX || 0;
- let x = startX;
- let y = this.Document._panY || 0;
- let i = 0;
- const width = Math.max(...docs.map(doc => NumCast(doc.layout._width)));
- const height = Math.max(...docs.map(doc => NumCast(doc.layout._height)));
- docs.forEach(pair => {
- pair.layout.x = x;
- pair.layout.y = y;
- x += width + 20;
- if (++i === 6) {
- i = 0;
- x = startX;
- y += height + 20;
- }
+ const docs = this.childLayoutPairs.map(pair => pair.layout);
+ const width = Math.max(...docs.map(doc => NumCast(doc._width))) + 20;
+ const height = Math.max(...docs.map(doc => NumCast(doc._height))) + 20;
+ const dim = Math.ceil(Math.sqrt(docs.length));
+ docs.forEach((doc, i) => {
+ doc.x = (this.Document._panX || 0) + (i % dim) * width - width * dim / 2;
+ doc.y = (this.Document._panY || 0) + Math.floor(i / dim) * height - height * dim / 2;
});
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 4008a20b3..e61cf83bb 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -46,7 +46,6 @@ interface MarqueeViewProps {
export class MarqueeView extends React.Component<SubCollectionViewProps & MarqueeViewProps>
{
private _commandExecuted = false;
- @observable public static DragMarquee = false;
@observable _lastX: number = 0;
@observable _lastY: number = 0;
@observable _downX: number = 0;
@@ -220,8 +219,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this._downY = this._lastY = e.clientY;
if (!(e.nativeEvent as any).marqueeHit) {
(e.nativeEvent as any).marqueeHit = true;
- // allow marquee if right click OR alt+left click OR space bar + left click
- if (e.button === 2 || (e.button === 0 && (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))))) {
+ // allow marquee if right click OR alt+left click
+ if (e.button === 2 || (e.button === 0 && e.altKey)) {
// if (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))) {
this.setPreviewCursor(e.clientX, e.clientY, true);
// (!e.altKey) && e.stopPropagation(); // bcz: removed so that you can alt-click on button in a collection to switch link following behaviors.
@@ -251,9 +250,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
} else {
this.cleanupInteractions(true); // stop listening for events if another lower-level handle (e.g. another Marquee) has stopPropagated this
}
- if (e.altKey || MarqueeView.DragMarquee) {
- e.preventDefault();
- }
+ e.altKey && e.preventDefault();
}
@action
@@ -290,9 +287,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
this.cleanupInteractions(true, this._commandExecuted);
- if (e.altKey || MarqueeView.DragMarquee) {
- e.preventDefault();
- }
+ e.altKey && e.preventDefault();
}
clearSelection() {
@@ -659,7 +654,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
style={{
overflow: (!this.props.ContainingCollectionView && this.props.isAnnotationOverlay) ? "visible" :
StrCast(this.props.Document._overflow),
- cursor: MarqueeView.DragMarquee && this ? "crosshair" : "hand"
+ cursor: "hand"
}}
onDragOver={e => e.preventDefault()}
onScroll={(e) => e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0} onClick={this.onClick} onPointerDown={this.onPointerDown}>
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 7687690b2..ca6dc87ae 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -385,10 +385,12 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
this._setPreviewCursor?.(e.clientX, e.clientY, true);
}
if (!e.altKey && e.button === 0 && this.active(true)) {
+ this._marqueeing = [e.clientX, e.clientY];
if (e.target && ((e.target as any).className.includes("endOfContent") || ((e.target as any).parentElement.className !== "textLayer"))) {
- this._marqueeing = [e.clientX, e.clientY]; // if texLayer is hit, then we select text instead of using a marquee
document.addEventListener("pointermove", this.onSelectMove); // need this to prevent document from being dragged if stopPropagation doesn't get called
} else {
+ // if textLayer is hit, then we select text instead of using a marquee so clear out the marquee.
+ setTimeout(action(() => this._marqueeing = undefined), 100); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it.
// clear out old marquees and initialize menu for new selection
AnchorMenu.Instance.Status = "marquee";
this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove()));