aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-03-14 22:21:16 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-03-14 22:21:16 -0400
commitf089e10dfd42edc395729a6b71e42385745f364e (patch)
treecb416d37585bb086c836b2882b03d720308fafc5
parent05b23c6b94b47393ba4d34a393e5080f20aff099 (diff)
marquees can now delete ink or move it to a new collection.
-rw-r--r--src/client/documents/Documents.ts3
-rw-r--r--src/client/views/InkingCanvas.scss3
-rw-r--r--src/client/views/InkingCanvas.tsx22
-rw-r--r--src/client/views/InkingStroke.tsx2
-rw-r--r--src/client/views/Main.tsx2
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx4
-rw-r--r--src/client/views/collections/CollectionVideoView.tsx6
-rw-r--r--src/client/views/collections/MarqueeView.tsx47
8 files changed, 63 insertions, 26 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 4e0eefcc6..8402118b8 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -24,10 +24,12 @@ import { PDFBox } from "../views/nodes/PDFBox";
import { CollectionPDFView } from "../views/collections/CollectionPDFView";
import { RichTextField } from "../../fields/RichTextField";
import { CollectionVideoView } from "../views/collections/CollectionVideoView";
+import { StrokeData, InkField } from "../../fields/InkField";
export interface DocumentOptions {
x?: number;
y?: number;
+ ink?: Map<string, StrokeData>;
width?: number;
height?: number;
nativeWidth?: number;
@@ -87,6 +89,7 @@ export namespace Documents {
if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
+ if (options.ink !== undefined) { doc.Set(KeyStore.Ink, new InkField(options.ink)); }
return doc;
}
function setupPrototypeOptions(protoId: string, title: string, layout: string, options: DocumentOptions): Document {
diff --git a/src/client/views/InkingCanvas.scss b/src/client/views/InkingCanvas.scss
index f654b194b..37fa3143d 100644
--- a/src/client/views/InkingCanvas.scss
+++ b/src/client/views/InkingCanvas.scss
@@ -1,8 +1,9 @@
.inking-canvas {
- position: fixed;
+ position: absolute;
top: -50000px;
left: -50000px; // z-index: 99; //overlays ink on top of everything
svg {
+ position:absolute;
width: 100000px;
height: 100000px;
.highlight {
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx
index 064d1cba2..84c47f616 100644
--- a/src/client/views/InkingCanvas.tsx
+++ b/src/client/views/InkingCanvas.tsx
@@ -1,4 +1,5 @@
import { observer } from "mobx-react";
+import { observable } from "mobx";
import { action, computed } from "mobx";
import { InkingControl } from "./InkingControl";
import React = require("react");
@@ -6,14 +7,10 @@ import { Transform } from "../util/Transform";
import { Document } from "../../fields/Document";
import { KeyStore } from "../../fields/KeyStore";
import { InkField, InkTool, StrokeData, StrokeMap } from "../../fields/InkField";
-import { JsxArgs } from "./nodes/DocumentView";
import { InkingStroke } from "./InkingStroke";
import "./InkingCanvas.scss"
-import { CollectionDockingView } from "./collections/CollectionDockingView";
import { Utils } from "../../Utils";
import { FieldWaiting } from "../../fields/Field";
-import { getMapLikeKeys } from "mobx/lib/internal";
-
interface InkCanvasProps {
getScreenTransform: () => Transform;
@@ -22,7 +19,16 @@ interface InkCanvasProps {
@observer
export class InkingCanvas extends React.Component<InkCanvasProps> {
-
+ static InkOffset: number = 50000;
+ public static IntersectStrokeRect(stroke: StrokeData, selRect: { left: number, top: number, width: number, height: number }): boolean {
+ let inside = false;
+ stroke.pathData.map(val => {
+ if (selRect.left < val.x - InkingCanvas.InkOffset && selRect.left + selRect.width > val.x - InkingCanvas.InkOffset &&
+ selRect.top < val.y - InkingCanvas.InkOffset && selRect.top + selRect.height > val.y - InkingCanvas.InkOffset)
+ inside = true;
+ });
+ return inside
+ }
private _isDrawing: boolean = false;
private _idGenerator: string = "";
@@ -51,7 +57,6 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
document.removeEventListener("mouseup", this.handleMouseUp);
}
-
@action
handleMouseDown = (e: React.PointerEvent): void => {
if (e.button != 0 ||
@@ -62,7 +67,6 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
if (InkingControl.Instance.selectedTool === InkTool.Eraser) {
return
}
- e.stopPropagation()
const point = this.relativeCoordinatesForEvent(e);
// start the new line, saves a uuid to represent the field of the stroke
@@ -110,8 +114,8 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
relativeCoordinatesForEvent = (e: React.MouseEvent): { x: number, y: number } => {
let [x, y] = this.props.getScreenTransform().transformPoint(e.clientX, e.clientY);
- x += 50000
- y += 50000
+ x += InkingCanvas.InkOffset;
+ y += InkingCanvas.InkOffset;
return { x, y };
}
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index d724421d3..87b5c43d8 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -21,8 +21,6 @@ export class InkingStroke extends React.Component<StrokeProps> {
@observable private _strokeColor: string = this.props.color;
@observable private _strokeWidth: string = this.props.width;
- private _canvasColor: string = "#cdcdcd";
-
deleteStroke = (e: React.MouseEvent): void => {
if (InkingControl.Instance.selectedTool === InkTool.Eraser && e.buttons === 1) {
this.props.deleteCallback(this.props.id);
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 8ee028076..d73e9b8fe 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -58,7 +58,7 @@ Documents.initProtos(mainDocId, (res?: Document) => {
let videourl = "http://techslides.com/demos/sample-videos/small.mp4";
let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {}))
let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
- let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, backgroundColor: "Transparent", title: "a freeform collection" }));
+ let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" }));
let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, title: "video node" }));
let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, title: "a schema collection" }));
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 98fb23fa4..c8b745254 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -338,7 +338,9 @@ export class CollectionFreeFormView extends CollectionViewBase {
<PreviewCursor container={this} addLiveTextDocument={this.addLiveTextBox} getTransform={this.getTransform} />
{this.views}
</div>
- <MarqueeView container={this} activeDocuemnts={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} getMarqueeTransform={this.getMarqueeTransform} getTransform={this.getTransform} />
+ <MarqueeView container={this} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments}
+ addDocument={this.props.addDocument} removeDocument={this.props.removeDocument}
+ getMarqueeTransform={this.getMarqueeTransform} getTransform={this.getTransform} />
{this.overlayView}
</div>
);
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 0e2d250aa..b64ef3c07 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -24,14 +24,14 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
private get uIButtons() {
let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().transformDirection(1, 1)[0]);
return ([
- <div className="collectionVideoView-time" onPointerDown={this.onResetDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+ <div className="collectionVideoView-time" key="time" onPointerDown={this.onResetDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
<span>{"" + Math.round(this.ctime)}</span>
<span style={{ fontSize: 8 }}>{" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)}</span>
</div>,
- <div className="collectionVideoView-play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+ <div className="collectionVideoView-play" key="play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
{this.playing ? "\"" : ">"}
</div>,
- <div className="collectionVideoView-full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+ <div className="collectionVideoView-full" key="full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
F
</div>
]);
diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx
index d9e4df1e9..67716f99a 100644
--- a/src/client/views/collections/MarqueeView.tsx
+++ b/src/client/views/collections/MarqueeView.tsx
@@ -3,21 +3,22 @@ import { observer } from "mobx-react";
import { Document } from "../../../fields/Document";
import { FieldWaiting, Opt } from "../../../fields/Field";
import { KeyStore } from "../../../fields/KeyStore";
-import { ListField } from "../../../fields/ListField";
import { Documents } from "../../documents/Documents";
import { SelectionManager } from "../../util/SelectionManager";
import { Transform } from "../../util/Transform";
import { CollectionFreeFormView } from "./CollectionFreeFormView";
import "./MarqueeView.scss";
import React = require("react");
-
+import { InkField, StrokeData } from "../../../fields/InkField";
+import { Utils } from "../../../Utils";
+import { InkingCanvas } from "../InkingCanvas";
interface MarqueeViewProps {
getMarqueeTransform: () => Transform;
getTransform: () => Transform;
container: CollectionFreeFormView;
addDocument: (doc: Document) => void;
- activeDocuemnts: () => Document[];
+ activeDocuments: () => Document[];
selectDocuments: (docs: Document[]) => void;
removeDocument: (doc: Document) => boolean;
}
@@ -94,29 +95,57 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
marqueeCommand = (e: KeyboardEvent) => {
if (e.key == "Backspace") {
this.marqueeSelect().map(d => this.props.removeDocument(d));
+ this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField);
this.cleanupInteractions();
}
if (e.key == "c") {
let bounds = this.Bounds;
- let selected = this.marqueeSelect().map(m => m);
- this.marqueeSelect().map(d => this.props.removeDocument(d));
- //setTimeout(() => {
- this.props.addDocument(Documents.FreeformDocument(selected.map(d => {
+ let selected = this.marqueeSelect().map(d => {
+ this.props.removeDocument(d);
d.SetNumber(KeyStore.X, d.GetNumber(KeyStore.X, 0) - bounds.left - bounds.width / 2);
d.SetNumber(KeyStore.Y, d.GetNumber(KeyStore.Y, 0) - bounds.top - bounds.height / 2);
d.SetNumber(KeyStore.Page, 0);
d.SetText(KeyStore.Title, "" + d.GetNumber(KeyStore.Width, 0) + " " + d.GetNumber(KeyStore.Height, 0));
return d;
- }), { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, height: bounds.height, title: "a nested collection" }));
+ });
+ let liftedInk = this.marqueeInkSelect(true);
+ this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField);
+ //setTimeout(() => {
+ this.props.addDocument(Documents.FreeformDocument(selected, { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, backgroundColor: "Transparent", height: bounds.height, ink: liftedInk, title: "a nested collection" }));
// }, 100);
this.cleanupInteractions();
}
}
+ marqueeInkSelect(select: boolean) {
+ let selRect = this.Bounds;
+ let centerShiftX = 0 - (selRect.left + selRect.width / 2); // moves each point by the offset that shifts the selection's center to the origin.
+ let centerShiftY = 0 - (selRect.top + selRect.height / 2);
+ let ink = this.props.container.props.Document.GetT(KeyStore.Ink, InkField);
+ if (ink && ink != FieldWaiting) {
+ let idata = new Map();
+ ink.Data.forEach((value: StrokeData, key: string, map: any) => {
+ let inside = InkingCanvas.IntersectStrokeRect(value, selRect);
+ if (inside && select) {
+ idata.set(key,
+ {
+ pathData: value.pathData.map(val => { return { x: val.x + centerShiftX, y: val.y + centerShiftY } }),
+ color: value.color,
+ width: value.width,
+ tool: value.tool,
+ page: -1
+ });
+ } else if (!inside && !select) {
+ idata.set(key, value);
+ }
+ })
+ return idata;
+ }
+ }
marqueeSelect() {
let selRect = this.Bounds;
let selection: Document[] = [];
- this.props.activeDocuemnts().map(doc => {
+ this.props.activeDocuments().map(doc => {
var x = doc.GetNumber(KeyStore.X, 0);
var y = doc.GetNumber(KeyStore.Y, 0);
var w = doc.GetNumber(KeyStore.Width, 0);