aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss36
-rw-r--r--src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx274
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx126
4 files changed, 426 insertions, 12 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c753a703d..fb7784b58 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -458,7 +458,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
case GestureUtils.Gestures.Stroke:
const points = ge.points;
const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
- const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, InkingControl.Instance.selectedWidth, points, { title: "ink stroke", x: B.x, y: B.y, _width: B.width, _height: B.height });
+ const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, InkingControl.Instance.selectedWidth, InkingControl.Instance.selectedBezier, points, { title: "ink stroke", x: B.x, y: B.y, _width: B.width, _height: B.height });
this.addDocument(inkDoc);
e.stopPropagation();
break;
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
new file mode 100644
index 000000000..a7f4d4e53
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
@@ -0,0 +1,36 @@
+.antimodeMenu-button {
+ .color-preview {
+ width: 100%;
+ height: 100%;
+ }
+
+
+}
+
+.sketch-picker {
+ background: #323232;
+
+ .flexbox-fit {
+ background: #323232;
+ }
+}
+
+.btn-group {
+ display: grid;
+ grid-template-columns: auto auto auto auto;
+ /* Make the buttons appear below each other */
+}
+
+.btn2-group {
+ display: block;
+ background: #323232;
+ grid-template-columns: auto;
+
+ /* Make the buttons appear below each other */
+ .antimodeMenu-button {
+ background: #323232;
+ display: block;
+
+
+ }
+} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
new file mode 100644
index 000000000..44488cbcf
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -0,0 +1,274 @@
+import React = require("react");
+import AntimodeMenu from "../../AntimodeMenu";
+import { observer } from "mobx-react";
+import { unimplementedFunction } from "../../../../Utils";
+import { observable, action } from "mobx";
+import "./InkOptionsMenu.scss";
+
+
+@observer
+export default class InkOptionsMenu extends AntimodeMenu {
+ static Instance: InkOptionsMenu;
+ public changeColor: (color: string) => void = unimplementedFunction;
+ public changeBezier: (e: React.PointerEvent) => void = unimplementedFunction;
+ public changeWidth: (color: string) => void = unimplementedFunction;
+
+ private _palette: (string)[];
+ private _width: (string)[];
+
+
+ public _circle: boolean;
+ public _triangle: boolean;
+ public _rectangle: boolean;
+ public _arrow: boolean;
+ public _line: boolean;
+ public _widthSelected: string;
+
+ @observable public _circleBt: boolean;
+ @observable public _triangleBt: boolean;
+ @observable public _rectangleBt: boolean;
+ @observable public _arrowBt: boolean;
+ @observable public _lineBt: boolean;
+ @observable public _colorBt: boolean;
+ @observable public _color: string;
+ @observable public _bezierBt: boolean;
+ @observable public _widthBt: boolean;
+
+
+
+ constructor(props: Readonly<{}>) {
+ super(props);
+ InkOptionsMenu.Instance = this;
+ this._canFade = false;
+
+ this._circle = false;
+ this._triangle = false;
+ this._rectangle = false;
+ this._arrow = false;
+ this._line = false;
+ this._circleBt = false;
+ this._triangleBt = false;
+ this._rectangleBt = false;
+ this._arrowBt = false;
+ this._lineBt = false;
+ this._colorBt = false;
+ this._bezierBt = false;
+ this._widthBt = false;
+
+ this._color = "";
+ this._widthSelected = "";
+
+
+ this._palette = [
+ "D0021B", "F5A623", "F8E71C", "8B572A", "7ED321", "417505", "9013FE", "4A90E2", "50E3C2", "B8E986", "000000", "4A4A4A", "9B9B9B", "FFFFFF",
+ ];
+
+ this._width = [
+ "1", "5", "10", "100", "200", "300"
+ ];
+
+ }
+
+
+
+ drag = (e: React.PointerEvent) => {
+ this.dragStart(e);
+ }
+
+
+
+
+
+ @action
+ toggleCircle = (e: React.PointerEvent) => {
+ const curr = this._circle;
+ this.allFalse();
+ curr ? this._circle = false : this._circle = true;
+ this._circleBt = this._circle;
+ }
+ @action
+ toggleTriangle = (e: React.PointerEvent) => {
+ const curr = this._triangle;
+ this.allFalse();
+ curr ? this._triangle = false : this._triangle = true;
+ this._triangleBt = this._triangle;
+ }
+ @action
+ toggleRectangle = (e: React.PointerEvent) => {
+ const curr = this._rectangle;
+ this.allFalse();
+ curr ? this._rectangle = false : this._rectangle = true;
+ this._rectangleBt = this._rectangle;
+ }
+ @action
+ toggleArrow = (e: React.PointerEvent) => {
+ const curr = this._arrow;
+ this.allFalse();
+ curr ? this._arrow = false : this._arrow = true;
+ this._arrowBt = this._arrow;
+ }
+ @action
+ toggleLine = (e: React.PointerEvent) => {
+ const curr = this._line;
+ this.allFalse();
+ curr ? this._line = false : this._line = true;
+ this._lineBt = this._line;
+ }
+
+ @action
+ changeBezierClick = (e: React.PointerEvent) => {
+ const curr = this._bezierBt;
+ this.allFalse();
+ curr ? this._bezierBt = false : this._bezierBt = true;
+ this.changeBezier(e);
+ }
+
+ @action
+ changeWidthClick = (e: React.PointerEvent) => {
+ this._widthBt ? this._widthBt = false : this._widthBt = true;
+ }
+ @action
+ changeColorClick = (e: React.PointerEvent) => {
+ this._colorBt ? this._colorBt = false : this._colorBt = true;
+ }
+
+ allFalse = () => {
+ this._circle = false;
+ this._triangle = false;
+ this._rectangle = false;
+ this._arrow = false;
+ this._line = false;
+ this._circleBt = false;
+ this._triangleBt = false;
+ this._rectangleBt = false;
+ this._arrowBt = false;
+ this._lineBt = false;
+ this._bezierBt = false;
+ }
+
+ render() {
+ var widthPicker;
+ if (this._widthBt) {
+ widthPicker = <div className="btn2-group">
+ <button
+ className="antimodeMenu-button"
+ key="width"
+ onPointerDown={this.changeWidthClick}
+ style={this._widthBt ? { backgroundColor: "121212" } : {}}>
+ W
+ </button>
+ {this._width.map(wid => {
+ return <button
+ className="antimodeMenu-button"
+ key={wid}
+ onPointerDown={() => this.changeWidth(wid)}
+ style={this._colorBt ? { backgroundColor: "121212" } : {}}>
+ {wid}
+ </button>;
+
+ })}
+ </div>;
+ } else {
+ widthPicker = <button
+ className="antimodeMenu-button"
+ key="width"
+ onPointerDown={this.changeWidthClick}
+ style={this._widthBt ? { backgroundColor: "121212" } : {}}>
+ W
+ </button>;
+ }
+
+ var colorPicker;
+ if (this._colorBt) {
+ colorPicker = <div className="btn-group">
+ <button
+ className="antimodeMenu-button"
+ key="color"
+ onPointerDown={this.changeColorClick}
+ style={this._colorBt ? { backgroundColor: "121212" } : {}}>
+ <div className="color-preview" style={this._color === "" ? { backgroundColor: "121212" } : { backgroundColor: this._color }}></div>
+ </button>
+ {this._palette.map(color => {
+ return <button
+ className="antimodeMenu-button"
+ key={color}
+ onPointerDown={() => this.changeColor(color)}
+ style={this._colorBt ? { backgroundColor: "121212" } : {}}>
+ <div className="color-preview" style={{ backgroundColor: color }}></div>
+ </button>;
+ })}
+ </div>;
+ } else {
+ colorPicker = <button
+ className="antimodeMenu-button"
+ title="colorChanger"
+ key="color"
+ onPointerDown={this.changeColorClick}
+ style={this._colorBt ? { backgroundColor: "121212" } : {}}>
+ <div className="color-preview" style={this._color === "" ? { backgroundColor: "121212" } : { backgroundColor: this._color }}></div>
+ </button>;
+ }
+
+
+ const buttons = [
+ <button
+ className="antimodeMenu-button"
+ title="Drag"
+ key="drag"
+ onPointerDown={this.drag}>
+ ✜
+ </button>,
+ <button
+ className="antimodeMenu-button"
+ title="Draw Circle"
+ key="circle"
+ onPointerDown={this.toggleCircle}
+ style={this._circleBt ? { backgroundColor: "121212" } : {}}>
+ O
+ </button>,
+ <button
+ className="antimodeMenu-button"
+ title="Draw Traingle"
+ key="triangle"
+ onPointerDown={this.toggleTriangle}
+ style={this._triangleBt ? { backgroundColor: "121212" } : {}}>
+ ∆
+ </button>,
+ <button
+ className="antimodeMenu-button"
+ title="Draw Rectangle"
+ key="rectangle"
+ onPointerDown={this.toggleRectangle}
+ style={this._rectangleBt ? { backgroundColor: "121212" } : {}}>
+ ロ
+ </button>,
+ <button
+ className="antimodeMenu-button"
+ title="Draw Arrow"
+ key="arrow"
+ onPointerDown={this.toggleArrow}
+ style={this._arrowBt ? { backgroundColor: "121212" } : {}}>
+ ➜
+ </button>,
+ <button
+ className="antimodeMenu-button"
+ title="Draw Line"
+ key="line"
+ onPointerDown={this.toggleLine}
+ style={this._lineBt ? { backgroundColor: "121212" } : {}}>
+ –
+ </button>,
+ <button
+ className="antimodeMenu-button"
+ title="Bezier changer"
+ key="bezier"
+ onPointerDown={this.changeBezierClick}
+ style={this._bezierBt ? { backgroundColor: "121212" } : {}}>
+ B
+ </button>,
+ widthPicker,
+ colorPicker,
+ ];
+ return this.getElement(buttons);
+ }
+} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index cdfeeaa6b..97244ed06 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -42,6 +42,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
@observable _downY: number = 0;
@observable _visible: boolean = false;
_commandExecuted = false;
+ @observable _pointsX: number[] = [];
+ @observable _pointsY: number[] = [];
+ @observable _freeHand: boolean = false;
componentDidMount() {
this.props.setPreviewCursor?.(this.setPreviewCursor);
@@ -57,6 +60,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
if (hideMarquee) {
this._visible = false;
}
+ this._pointsX = [];
+ this._pointsY = [];
+ this._freeHand = false;
}
@undoBatch
@@ -191,6 +197,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
onPointerMove = (e: PointerEvent): void => {
this._lastX = e.pageX;
this._lastY = e.pageY;
+ this._pointsX.push(e.clientX);
+ this._pointsY.push(e.clientY);
if (!e.cancelBubble) {
if (Math.abs(this._lastX - this._downX) > Utils.DRAG_THRESHOLD ||
Math.abs(this._lastY - this._downY) > Utils.DRAG_THRESHOLD) {
@@ -519,6 +527,17 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
this.cleanupInteractions(false);
}
+ if (e.key === "r") {
+ this._commandExecuted = true;
+ e.stopPropagation();
+ e.preventDefault();
+ this.changeFreeHand(true);
+ }
+ }
+
+ @action
+ changeFreeHand = (x: boolean) => {
+ this._freeHand = x;
}
// @action
// marqueeInkSelect(ink: Map<any, any>) {
@@ -559,7 +578,51 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
// this.ink = new InkField(idata);
// }
// }
+ touchesLine(r1: { left: number, top: number, width: number, height: number }) {
+ for (var i = 0; i < this._pointsX.length; i++) {
+ const topLeft = this.props.getTransform().transformPoint(this._pointsX[i], this._pointsY[i]);
+ if (topLeft[0] > r1.left &&
+ topLeft[0] < r1.left + r1.width &&
+ topLeft[1] > r1.top &&
+ topLeft[1] < r1.top + r1.height) {
+ return true;
+ }
+ }
+ return false;
+ }
+ boundingShape(r1: { left: number, top: number, width: number, height: number }) {
+ const trueLeft = this.props.getTransform().transformPoint(Math.min(...this._pointsX), Math.min(...this._pointsY))[0];
+ const trueTop = this.props.getTransform().transformPoint(Math.min(...this._pointsX), Math.min(...this._pointsY))[1];
+ const trueRight = this.props.getTransform().transformPoint(Math.max(...this._pointsX), Math.max(...this._pointsY))[0];
+ const trueBottom = this.props.getTransform().transformPoint(Math.max(...this._pointsX), Math.max(...this._pointsY))[1];
+
+ if (r1.left > trueLeft && r1.top > trueTop && r1.left + r1.width < trueRight && r1.top + r1.height < trueBottom) {
+ var hasTop = false;
+ var hasLeft = false;
+ var hasBottom = false;
+ var hasRight = false;
+ for (var i = 0; i < this._pointsX.length; i++) {
+ const truePoint = this.props.getTransform().transformPoint(this._pointsX[i], this._pointsY[i]);
+ if (!hasLeft && (truePoint[0] > trueLeft && truePoint[0] < r1.left) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height)) {
+ hasLeft = true;
+ }
+ if (!hasTop && (truePoint[1] > trueTop && truePoint[1] < r1.top) && (truePoint[0] > r1.left && truePoint[0] < r1.left + r1.width)) {
+ hasTop = true;
+ }
+ if (!hasRight && (truePoint[0] < trueRight && truePoint[0] > r1.left + r1.width) && (truePoint[1] > r1.top && truePoint[1] < r1.top + r1.height)) {
+ hasRight = true;
+ }
+ if (!hasBottom && (truePoint[1] < trueBottom && truePoint[1] > r1.top + r1.height) && (truePoint[0] > r1.left && truePoint[0] < r1.left + r1.width)) {
+ hasBottom = true;
+ }
+ if (hasTop && hasLeft && hasBottom && hasRight) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
marqueeSelect(selectBackgrounds: boolean = true) {
const selRect = this.Bounds;
const selection: Doc[] = [];
@@ -569,8 +632,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const y = NumCast(doc.y);
const w = NumCast(layoutDoc._width);
const h = NumCast(layoutDoc._height);
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
- selection.push(doc);
+ if (this._freeHand === false) {
+ if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
+ selection.push(doc);
+ }
+ } else {
+ if (this.touchesLine({ left: x, top: y, width: w, height: h }) ||
+ this.boundingShape({ left: x, top: y, width: w, height: h })) {
+ selection.push(doc);
+ }
}
});
if (!selection.length && selectBackgrounds) {
@@ -597,8 +667,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const y = NumCast(doc.y);
const w = NumCast(layoutDoc._width);
const h = NumCast(layoutDoc._height);
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, otherBounds)) {
- selection.push(doc);
+ if (this._freeHand === false) {
+ if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
+ selection.push(doc);
+ }
+ } else {
+ if (this.touchesLine({ left: x, top: y, width: w, height: h }) ||
+ this.boundingShape({ left: x, top: y, width: w, height: h })) {
+ selection.push(doc);
+ }
}
});
}
@@ -614,13 +691,40 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
* This contains the "C for collection, ..." text on marquees.
* Commented out by syip2 when the marquee menu was added.
*/
- return <div className="marquee" style={{
- transform: `translate(${p[0]}px, ${p[1]}px)`,
- width: `${Math.abs(v[0])}`,
- height: `${Math.abs(v[1])}`, zIndex: 2000
- }} >
- {/* <span className="marquee-legend" /> */}
- </div>;
+ if (!this._freeHand) {
+ return <div className="marquee" style={{
+ transform: `translate(${p[0]}px, ${p[1]}px)`,
+ width: `${Math.abs(v[0])}`,
+ height: `${Math.abs(v[1])}`, zIndex: 2000
+ }} >
+ {/* <span className="marquee-legend" /> */}
+ </div>;
+
+ } else {
+ //subtracted 250 for offset
+ var str: string = "";
+ for (var i = 0; i < this._pointsX.length; i++) {
+ var x = 0;
+ x = this._pointsX[i] - 250;
+ str += x.toString();
+ str += ",";
+ str += this._pointsY[i].toString();
+ str += (" ");
+ }
+
+ //hardcoded height and width.
+ return <div className="marquee" style={{ zIndex: 2000 }}>
+ <svg height={2000} width={2000}>
+ <polyline
+ points={str}
+ fill="none"
+ stroke="black"
+ strokeWidth="1"
+ strokeDasharray="3"
+ />
+ </svg>
+ </div>;
+ }
}
render() {