aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/collections/CollectionPDFView.scss26
-rw-r--r--src/client/views/collections/CollectionPDFView.tsx34
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx8
-rw-r--r--src/client/views/nodes/FieldView.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.scss12
-rw-r--r--src/client/views/nodes/PDFBox.tsx215
-rw-r--r--src/client/views/nodes/Sticky.tsx83
7 files changed, 95 insertions, 285 deletions
diff --git a/src/client/views/collections/CollectionPDFView.scss b/src/client/views/collections/CollectionPDFView.scss
index 0eca3f1cd..f6fb79582 100644
--- a/src/client/views/collections/CollectionPDFView.scss
+++ b/src/client/views/collections/CollectionPDFView.scss
@@ -1,20 +1,39 @@
.collectionPdfView-buttonTray {
- top : 25px;
+ top : 15px;
left : 20px;
position: relative;
transform-origin: left top;
position: absolute;
}
+.collectionPdfView-thumb {
+ width:25px;
+ height:25px;
+ transform-origin: left top;
+ position: absolute;
+ background: darkgray;
+}
+.collectionPdfView-slider {
+ width:25px;
+ height:25px;
+ transform-origin: left top;
+ position: absolute;
+ background: lightgray;
+}
.collectionPdfView-cont{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left:0;
-
+}
+.collectionPdfView-cont-dragging {
+ span {
+ user-select: none;
+ }
}
.collectionPdfView-backward {
color : white;
+ font-size: 24px;
top :0px;
left : 0px;
position: absolute;
@@ -22,8 +41,9 @@
}
.collectionPdfView-forward {
color : white;
+ font-size: 24px;
top :0px;
- left : 35px;
+ left : 45px;
position: absolute;
background-color: rgba(50, 50, 50, 0.2);
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index 229bc4059..497c3ee3c 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -1,4 +1,4 @@
-import { action } from "mobx";
+import { action, observable } from "mobx";
import { observer } from "mobx-react";
import { KeyStore } from "../../../fields/KeyStore";
import { ContextMenu } from "../ContextMenu";
@@ -16,18 +16,44 @@ export class CollectionPDFView extends React.Component<FieldViewProps> {
public static LayoutString(fieldKey: string = "DataKey") {
return FieldView.LayoutString(CollectionPDFView, fieldKey);
}
+ @observable _inThumb = false;
private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, -1); }
+ private set curPage(value: number) { this.props.Document.SetNumber(KeyStore.CurPage, value); }
private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
@action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : -1;
@action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : -1;
+ @action
+ onThumbDown = (e: React.PointerEvent) => {
+ document.addEventListener("pointermove", this.onThumbMove, false);
+ document.addEventListener("pointerup", this.onThumbUp, false);
+ e.stopPropagation();
+ this._inThumb = true;
+ }
+ @action
+ onThumbMove = (e: PointerEvent) => {
+ let pso = (e.clientY - (e as any).target.parentElement.getBoundingClientRect().top) / (e as any).target.parentElement.getBoundingClientRect().height;
+ this.curPage = Math.trunc(Math.min(this.numPages, pso * this.numPages + 1));
+ e.stopPropagation();
+ }
+ @action
+ onThumbUp = (e: PointerEvent) => {
+ this._inThumb = false;
+ document.removeEventListener("pointermove", this.onThumbMove);
+ document.removeEventListener("pointerup", this.onThumbUp);
+ }
+ nativeWidth = () => this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
+ nativeHeight = () => this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
private get uIButtons() {
- let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale);
+ let ratio = (this.curPage - 1) / this.numPages * 100;
return (
- <div className="collectionPdfView-buttonTray" key="tray" style={{ transform: `scale(${scaling}, ${scaling})` }}>
+ <div className="collectionPdfView-buttonTray" key="tray" style={{ height: "100%" }}>
<button className="collectionPdfView-backward" onClick={this.onPageBack}>{"<"}</button>
<button className="collectionPdfView-forward" onClick={this.onPageForward}>{">"}</button>
+ <div className="collectionPdfView-slider" onPointerDown={this.onThumbDown} style={{ top: 60, left: -20, width: 50, height: `calc(100% - 80px)` }} >
+ <div className="collectionPdfView-thumb" onPointerDown={this.onThumbDown} style={{ top: `${ratio}%`, width: 50, height: 50 }} />
+ </div>
</div>
);
}
@@ -50,7 +76,7 @@ export class CollectionPDFView extends React.Component<FieldViewProps> {
render() {
return (
- <CollectionBaseView {...this.props} className="collectionPdfView-cont" onContextMenu={this.onContextMenu}>
+ <CollectionBaseView {...this.props} className={`collectionPdfView-cont${this._inThumb ? "-dragging" : ""}`} onContextMenu={this.onContextMenu}>
{this.subView}
</CollectionBaseView>
);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 56342c84c..405594eb1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -283,7 +283,7 @@ export class CollectionFreeFormView extends CollectionSubView {
super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
}
- private childViews = () => [...this.views, <CollectionFreeFormBackgroundView key="backgroundView" {...this.getDocumentViewProps(this.props.Document)} />];
+ private childViews = () => [...this.views, <CollectionFreeFormBackgroundView key="backgroundView" {...this.props} {...this.getDocumentViewProps(this.props.Document)} />];
render() {
const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`;
return (
@@ -307,7 +307,7 @@ export class CollectionFreeFormView extends CollectionSubView {
</CollectionFreeFormLinksView>
<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />
</CollectionFreeFormViewPannableContents>
- <CollectionFreeFormOverlayView {...this.getDocumentViewProps(this.props.Document)} />
+ <CollectionFreeFormOverlayView {...this.getDocumentViewProps(this.props.Document)} {...this.props} />
</MarqueeView>
</div>
);
@@ -328,12 +328,12 @@ class CollectionFreeFormOverlayView extends React.Component<DocumentViewProps> {
}
@observer
-class CollectionFreeFormBackgroundView extends React.Component<DocumentViewProps> {
+class CollectionFreeFormBackgroundView extends React.Component<DocumentViewProps & { isSelected: () => boolean }> {
@computed get backgroundView() {
let backgroundLayout = this.props.Document.GetText(KeyStore.BackgroundLayout, "");
return !backgroundLayout ? (null) :
(<DocumentContentsView {...this.props} layoutKey={KeyStore.BackgroundLayout}
- isTopMost={this.props.isTopMost} isSelected={returnFalse} select={emptyFunction} />);
+ isTopMost={this.props.isTopMost} isSelected={this.props.isSelected} select={emptyFunction} />);
}
render() {
return this.backgroundView;
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 8f360754e..9e175b0d1 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -97,7 +97,7 @@ export class FieldView extends React.Component<FieldViewProps> {
isTopMost={true} //TODO Why is this top most?
selectOnLoad={false}
focus={emptyDocFunction}
- isSelected={returnFalse}
+ isSelected={this.props.isSelected}
select={returnFalse}
layoutKey={KeyStore.Layout}
ContainingCollectionView={this.props.ContainingCollectionView}
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 830dfe6c6..87fdd720a 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -12,6 +12,18 @@
top: 0;
left:0;
z-index: 25;
+ pointer-events: all;
+}
+.pdfButton {
+ pointer-events: all;
+ width: 100px;
+ height:100px;
+}
+.pdfBox-cont {
+ pointer-events: none;
+}
+.pdfBox-cont-interactive {
+ pointer-events: all;
}
.pdfBox-contentContainer {
position: absolute;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 81ceb37f6..0525d353e 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -1,5 +1,5 @@
import * as htmlToImage from "html-to-image";
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, Reaction, trace } from 'mobx';
import { observer } from "mobx-react";
import 'react-image-lightbox/style.css';
import Measure from "react-measure";
@@ -14,9 +14,7 @@ import { RouteStore } from "../../../server/RouteStore";
import { Utils } from '../../../Utils';
import { Annotation } from './Annotation';
import { FieldView, FieldViewProps } from './FieldView';
-import "./ImageBox.scss";
import "./PDFBox.scss";
-import { Sticky } from './Sticky'; //you should look at sticky and annotation, because they are used here
import React = require("react");
import { SelectionManager } from "../../util/SelectionManager";
@@ -40,15 +38,6 @@ import { SelectionManager } from "../../util/SelectionManager";
* 4) another method: click on highlight first and then drag on your desired text
* 5) To make another highlight, you need to reclick on the button
*
- * Draw:
- * 1) click draw and select color. then just draw like there's no tomorrow.
- * 2) once you finish drawing your masterpiece, just reclick on the draw button to end your drawing session.
- *
- * Pagination:
- * 1) click on arrows. You'll notice that stickies will stay in those page. But... highlights won't.
- * 2) to test this out, make few area/stickies and then click on next page then come back. You'll see that they are all saved.
- *
- *
* written by: Andrew Kim
*/
@observer
@@ -56,30 +45,9 @@ export class PDFBox extends React.Component<FieldViewProps> {
public static LayoutString() { return FieldView.LayoutString(PDFBox); }
private _mainDiv = React.createRef<HTMLDivElement>();
- private _pdf = React.createRef<HTMLCanvasElement>();
@observable private _renderAsSvg = true;
- //very useful for keeping track of X and y position throughout the PDF Canvas
- private initX: number = 0;
- private initY: number = 0;
-
- //checks if tool is on
- private _toolOn: boolean = false; //checks if tool is on
- private _pdfContext: any = null; //gets pdf context
- private bool: Boolean = false; //general boolean debounce
- private currSpan: any;//keeps track of current span (for highlighting)
-
- private _currTool: any; //keeps track of current tool button reference
- private _drawToolOn: boolean = false; //boolean that keeps track of the drawing tool
- private _drawTool = React.createRef<HTMLButtonElement>();//drawing tool button reference
-
- private _colorTool = React.createRef<HTMLButtonElement>(); //color button reference
- private _currColor: string = "black"; //current color that user selected (for ink/pen)
-
- private _highlightTool = React.createRef<HTMLButtonElement>(); //highlighter button reference
- private _highlightToolOn: boolean = false;
- private _pdfCanvas: any;
private _reactionDisposer: Opt<IReactionDisposer>;
@observable private _perPageInfo: Object[] = []; //stores pageInfo
@@ -112,43 +80,6 @@ export class PDFBox extends React.Component<FieldViewProps> {
}
/**
- * selection tool used for area highlighting (stickies). Kinda temporary
- */
- selectionTool = () => {
- this._toolOn = true;
- }
- /**
- * when user draws on the canvas. When mouse pointer is down
- */
- drawDown = (e: PointerEvent) => {
- this.initX = e.offsetX;
- this.initY = e.offsetY;
- this._pdfContext.beginPath();
- this._pdfContext.lineTo(this.initX, this.initY);
- this._pdfContext.strokeStyle = this._currColor;
- this._pdfCanvas.addEventListener("pointermove", this.drawMove);
- this._pdfCanvas.addEventListener("pointerup", this.drawUp);
-
- }
- //when user drags
- drawMove = (e: PointerEvent): void => {
- //x and y mouse movement
- let x = this.initX += e.movementX,
- y = this.initY += e.movementY;
- //connects the point
- this._pdfContext.lineTo(x, y);
- this._pdfContext.stroke();
- }
-
- drawUp = (e: PointerEvent) => {
- this._pdfContext.closePath();
- this._pdfCanvas.removeEventListener("pointermove", this.drawMove);
- this._pdfCanvas.removeEventListener("pointerdown", this.drawDown);
- this._pdfCanvas.addEventListener("pointerdown", this.drawDown);
- }
-
-
- /**
* highlighting helper function
*/
makeEditableAndHighlight = (colour: string) => {
@@ -272,11 +203,8 @@ export class PDFBox extends React.Component<FieldViewProps> {
* controls the area highlighting (stickies) Kinda temporary
*/
onPointerDown = (e: React.PointerEvent) => {
- if (this._toolOn) {
- let mouse = e.nativeEvent;
- this.initX = mouse.offsetX;
- this.initY = mouse.offsetY;
-
+ if (this.props.isSelected()) {
+ e.stopPropagation();
}
}
@@ -285,95 +213,12 @@ export class PDFBox extends React.Component<FieldViewProps> {
*/
@action
onPointerUp = (e: React.PointerEvent) => {
- if (this._highlightToolOn) {
+ if (this.props.isSelected()) {
this.highlight("rgba(76, 175, 80, 0.3)"); //highlights to this default color.
- this._highlightToolOn = false;
- }
- if (this._toolOn) {
- let mouse = e.nativeEvent;
- let finalX = mouse.offsetX;
- let finalY = mouse.offsetY;
- let width = Math.abs(finalX - this.initX); //width
- let height = Math.abs(finalY - this.initY); //height
-
- //these two if statements are bidirectional dragging. You can drag from any point to another point and generate sticky
- if (finalX < this.initX) {
- this.initX = finalX;
- }
- if (finalY < this.initY) {
- this.initY = finalY;
- }
-
- if (this._mainDiv.current) {
- let sticky = <Sticky key={Utils.GenerateGuid()} Height={height} Width={width} X={this.initX} Y={this.initY} />;
- this._pageInfo.area.push(sticky);
- }
- this._toolOn = false;
}
this._interactive = true;
}
- /**
- * starts drawing the line when user presses down.
- */
- onDraw = () => {
- if (this._currTool !== null) {
- this._currTool.style.backgroundColor = "grey";
- }
-
- if (this._drawTool.current) {
- this._currTool = this._drawTool.current;
- if (this._drawToolOn) {
- this._drawToolOn = false;
- this._pdfCanvas.removeEventListener("pointerdown", this.drawDown);
- this._pdfCanvas.removeEventListener("pointerup", this.drawUp);
- this._pdfCanvas.removeEventListener("pointermove", this.drawMove);
- this._drawTool.current.style.backgroundColor = "grey";
- } else {
- this._drawToolOn = true;
- this._pdfCanvas.addEventListener("pointerdown", this.drawDown);
- this._drawTool.current.style.backgroundColor = "cyan";
- }
- }
- }
-
-
- /**
- * for changing color (for ink/pen)
- */
- onColorChange = (e: React.PointerEvent) => {
- if (e.currentTarget.innerHTML === "Red") {
- this._currColor = "red";
- } else if (e.currentTarget.innerHTML === "Blue") {
- this._currColor = "blue";
- } else if (e.currentTarget.innerHTML === "Green") {
- this._currColor = "green";
- } else if (e.currentTarget.innerHTML === "Black") {
- this._currColor = "black";
- }
-
- }
-
-
- /**
- * For highlighting (text drag highlighting)
- */
- onHighlight = () => {
- this._drawToolOn = false;
- if (this._currTool !== null) {
- this._currTool.style.backgroundColor = "grey";
- }
- if (this._highlightTool.current) {
- this._currTool = this._drawTool.current;
- if (this._highlightToolOn) {
- this._highlightToolOn = false;
- this._highlightTool.current.style.backgroundColor = "grey";
- } else {
- this._highlightToolOn = true;
- this._highlightTool.current.style.backgroundColor = "orange";
- }
- }
- }
@action
@@ -397,22 +242,6 @@ export class PDFBox extends React.Component<FieldViewProps> {
@action
onLoaded = (page: any) => {
- if (this._mainDiv.current) {
- this._mainDiv.current.childNodes.forEach((element) => {
- if (element.nodeName === "DIV") {
- element.childNodes[0].childNodes.forEach((e) => {
-
- if (e instanceof HTMLCanvasElement) {
- this._pdfCanvas = e;
- this._pdfContext = e.getContext("2d");
-
- }
-
- });
- }
- });
- }
-
// bcz: the number of pages should really be set when the document is imported.
this.props.Document.SetNumber(KeyStore.NumPages, page._transport.numPages);
if (this._perPageInfo.length === 0) { //Makes sure it only runs once
@@ -424,7 +253,7 @@ export class PDFBox extends React.Component<FieldViewProps> {
@action
setScaling = (r: any) => {
// bcz: the nativeHeight should really be set when the document is imported.
- // also, the native dimensions could be different for different pages of the PDF
+ // also, the native dimensions could be different for different pages of the canvas
// so this design is flawed.
var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
if (!this.props.Document.GetNumber(KeyStore.NativeHeight, 0)) {
@@ -433,22 +262,27 @@ export class PDFBox extends React.Component<FieldViewProps> {
this.props.Document.SetNumber(KeyStore.NativeHeight, nativeHeight);
}
}
-
+ renderHeight = 2400;
+ @computed
+ get pdfPage() {
+ return <Page height={this.renderHeight} pageNumber={this.curPage} onLoadSuccess={this.onLoaded} />
+ }
@computed
get pdfContent() {
- let page = this.curPage;
- const renderHeight = 2400;
let pdfUrl = this.props.Document.GetT(this.props.fieldKey, PDFField);
- let xf = this.props.Document.GetNumber(KeyStore.NativeHeight, 0) / renderHeight;
+ let xf = this.props.Document.GetNumber(KeyStore.NativeHeight, 0) / this.renderHeight;
+ let body = (this.props.Document.GetNumber(KeyStore.NativeHeight, 0)) ?
+ this.pdfPage :
+ <Measure onResize={this.setScaling}>
+ {({ measureRef }) =>
+ <div className="pdfBox-page" ref={measureRef}>
+ {this.pdfPage}
+ </div>
+ }
+ </Measure>;
return <div className="pdfBox-contentContainer" key="container" style={{ transform: `scale(${xf}, ${xf})` }}>
- <Document file={window.origin + RouteStore.corsProxy + `/${pdfUrl}`} renderMode={this._renderAsSvg ? "svg" : ""}>
- <Measure onResize={this.setScaling}>
- {({ measureRef }) =>
- <div className="pdfBox-page" ref={measureRef}>
- <Page height={renderHeight} pageNumber={page} onLoadSuccess={this.onLoaded} />
- </div>
- }
- </Measure>
+ <Document file={window.origin + RouteStore.corsProxy + `/${pdfUrl}`} renderMode={this._renderAsSvg ? "svg" : "canvas"}>
+ {body}
</Document>
</div >;
}
@@ -478,10 +312,11 @@ export class PDFBox extends React.Component<FieldViewProps> {
}
return (null);
}
-
render() {
+ trace();
+ let classname = "pdfBox-cont" + (this.props.isSelected() ? "-interactive" : "");
return (
- <div className="pdfBox-cont" ref={this._mainDiv} onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} >
+ <div className={classname} ref={this._mainDiv} onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} >
{this.pdfRenderer}
</div >
);
diff --git a/src/client/views/nodes/Sticky.tsx b/src/client/views/nodes/Sticky.tsx
deleted file mode 100644
index 11719831b..000000000
--- a/src/client/views/nodes/Sticky.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import "react-image-lightbox/style.css"; // This only needs to be imported once in your app
-import React = require("react");
-import { observer } from "mobx-react";
-import "react-pdf/dist/Page/AnnotationLayer.css";
-
-interface IProps {
- Height: number;
- Width: number;
- X: number;
- Y: number;
-}
-
-/**
- * Sticky, also known as area highlighting, is used to highlight large selection of the PDF file.
- * Improvements that could be made: maybe store line array and store that somewhere for future rerendering.
- *
- * Written By: Andrew Kim
- */
-@observer
-export class Sticky extends React.Component<IProps> {
- private initX: number = 0;
- private initY: number = 0;
-
- private _ref = React.createRef<HTMLCanvasElement>();
- private ctx: any; //context that keeps track of sticky canvas
-
- /**
- * drawing. Registers the first point that user clicks when mouse button is pressed down on canvas
- */
- drawDown = (e: React.PointerEvent) => {
- if (this._ref.current) {
- this.ctx = this._ref.current.getContext("2d");
- let mouse = e.nativeEvent;
- this.initX = mouse.offsetX;
- this.initY = mouse.offsetY;
- this.ctx.beginPath();
- this.ctx.lineTo(this.initX, this.initY);
- this.ctx.strokeStyle = "black";
- document.addEventListener("pointermove", this.drawMove);
- document.addEventListener("pointerup", this.drawUp);
- }
- }
-
- //when user drags
- drawMove = (e: PointerEvent): void => {
- //x and y mouse movement
- let x = (this.initX += e.movementX),
- y = (this.initY += e.movementY);
- //connects the point
- this.ctx.lineTo(x, y);
- this.ctx.stroke();
- }
-
- /**
- * when user lifts the mouse, the drawing ends
- */
- drawUp = (e: PointerEvent) => {
- this.ctx.closePath();
- console.log(this.ctx);
- document.removeEventListener("pointermove", this.drawMove);
- }
-
- render() {
- return (
- <div onPointerDown={this.drawDown}>
- <canvas
- ref={this._ref}
- height={this.props.Height}
- width={this.props.Width}
- style={{
- position: "absolute",
- top: "20px",
- left: "0px",
- zIndex: 1,
- background: "yellow",
- transform: `translate(${this.props.X}px, ${this.props.Y}px)`,
- opacity: 0.4
- }}
- />
- </div>
- );
- }
-}