From 53713fc7ab10257d1117193941cda2f3e0cabcf5 Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Sun, 19 Jul 2020 04:44:51 +0900
Subject: added control points

---
 .../collectionFreeForm/FormatShapePane.tsx         | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)

(limited to 'src/client/views/collections/collectionFreeForm/FormatShapePane.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index 9d9ce7f36..a2dc241c0 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -28,6 +28,9 @@ export default class FormatShapePane extends AntimodeMenu {
     @observable private _lock = false;
     @observable private _fillBtn = false;
     @observable private _lineBtn = false;
+    @observable _controlBtn = false;
+    @observable private _controlPoints: { X: number, Y: number }[] = [];
+    @observable _currPoint = -1;
 
     getField(key: string) {
         return this.selectedInk?.reduce((p, i) =>
@@ -158,6 +161,51 @@ export default class FormatShapePane extends AntimodeMenu {
         }));
     }
 
+    @undoBatch
+    @action
+    control = (xDiff: number, yDiff: number, controlNum: number) => {
+        this.selectedInk?.forEach(action(inkView => {
+            if (this.selectedInk?.length === 1) {
+                const doc = Document(inkView.rootDoc);
+                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink) {
+
+                        const newPoints: { X: number, Y: number }[] = [];
+                        const order = controlNum % 4;
+                        for (var i = 0; i < ink.length; i++) {
+                            if (controlNum === i ||
+                                (order === 0 && i === controlNum + 1) ||
+                                (order === 0 && controlNum !== 0 && i === controlNum - 2) ||
+                                (order === 0 && controlNum !== 0 && i === controlNum - 1) ||
+                                (order === 3 && i === controlNum - 1) ||
+                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 1) ||
+                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 2)) {
+                                newPoints.push({ X: ink[i].X - (xDiff), Y: ink[i].Y - (yDiff) });
+                            }
+                            else {
+                                newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+                            }
+                        }
+                        const oldx = doc.x;
+                        const oldy = doc.y;
+                        doc.data = new InkField(newPoints);
+                        const xs2 = newPoints.map(p => p.X);
+                        const ys2 = newPoints.map(p => p.Y);
+                        const left2 = Math.min(...xs2);
+                        const top2 = Math.min(...ys2);
+                        const right2 = Math.max(...xs2);
+                        const bottom2 = Math.max(...ys2);
+                        doc._height = (bottom2 - top2) * inkView.props.ScreenToLocalTransform().Scale;
+                        doc._width = (right2 - left2) * inkView.props.ScreenToLocalTransform().Scale;
+                        doc.x = oldx;
+                        doc.y = oldy;
+                    }
+                }
+            }
+        }));
+    }
+
 
     colorPicker(setter: (color: string) => {}) {
         return <div className="btn-group-palette" key="colorpicker" >
@@ -193,6 +241,14 @@ export default class FormatShapePane extends AntimodeMenu {
         </>;
     }
 
+    controlPointsButton() {
+        return <>
+            <button className="antimodeMenu-button" key="fill" onPointerDown={action(() => this._controlBtn = this._controlBtn ? false : true)} style={{ position: "absolute", right: 80, backgroundColor: this._controlBtn ? "black" : "" }}>
+                <FontAwesomeIcon icon="bezier-curve" size="lg" />
+            </button>
+            <br /> <br />
+        </>;
+    }
     @computed get fillButton() { return this.colorButton(this.colorFil, () => this._fillBtn = !this._fillBtn); }
     @computed get lineButton() { return this.colorButton(this.colorStk, () => this._lineBtn = !this._lineBtn); }
 
@@ -206,6 +262,8 @@ export default class FormatShapePane extends AntimodeMenu {
     @computed get XpsInput() { return this.inputBox("Xps", this.shapeXps, (val: string) => this.shapeXps = val); }
     @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); }
 
+    @computed get controlPoints() { return this.controlPointsButton(); }
+
     @computed get propertyGroupItems() {
         const fillCheck = <div key="fill" style={{ display: this._subOpen[0] ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
             <input className="formatShapePane-inputBtn" type="radio" checked={this.unFilled} onChange={undoBatch(action(() => this.unFilled = true))} />
@@ -260,6 +318,7 @@ export default class FormatShapePane extends AntimodeMenu {
             <br />  <br />
                 Rotation {this.rotInput}
             <br /> <br />
+                Edit Points {this.controlPoints}
         </div>;
 
         const positionCheck = <div key="posCheck" style={{ display: this._subOpen[3] ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-- 
cgit v1.2.3-70-g09d2


From 258ad0d8628737e01613341437eb0421359ad168 Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Tue, 28 Jul 2020 00:02:40 +0900
Subject:  rotation/resize fix, changed ui, added sketchpicker etc.

---
 src/client/util/InteractionUtils.tsx               |   7 +-
 src/client/views/DocumentDecorations.tsx           |  54 +++-
 src/client/views/GestureOverlay.tsx                |  16 +-
 src/client/views/InkingStroke.tsx                  |  15 +-
 .../collectionFreeForm/FormatShapePane.scss        |   4 +-
 .../collectionFreeForm/FormatShapePane.tsx         | 333 ++++++++++++++-------
 .../collectionFreeForm/InkOptionsMenu.tsx          | 128 ++------
 src/client/views/nodes/ColorBox.tsx                |  45 +--
 8 files changed, 347 insertions(+), 255 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/FormatShapePane.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 31b2a56e6..69256ce67 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -123,6 +123,12 @@ export namespace InteractionUtils {
         } else {
             pts = points;
         }
+        if (isNaN(scalex)) {
+            scalex = 1;
+        }
+        if (isNaN(scaley)) {
+            scaley = 1;
+        }
         const strpts = pts.reduce((acc: string, pt: { X: number, Y: number }) => acc +
             `${(pt.X - left - width / 2) * scalex + width / 2},
          ${(pt.Y - top - width / 2) * scaley + width / 2} `, "");
@@ -141,7 +147,6 @@ export namespace InteractionUtils {
                     <polygon points={`${2 - arrowDim} ${-Math.max(1, arrowDim / 2)}, ${2 - arrowDim} ${Math.max(1, arrowDim / 2)}, 3 0`} />
                 </marker>}
             </defs>}
-
             <polyline
                 points={strpts}
                 style={{
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 444d2fe50..baf9865fe 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -23,6 +23,8 @@ import { SnappingManager } from '../util/SnappingManager';
 import { HtmlField } from '../../fields/HtmlField';
 import { InkData, InkField, InkTool } from "../../fields/InkField";
 import { Tooltip } from '@material-ui/core';
+import InkOptionsMenu from './collections/collectionFreeForm/InkOptionsMenu';
+import FormatShapePane from './collections/collectionFreeForm/FormatShapePane';
 
 library.add(faCaretUp);
 library.add(faObjectGroup);
@@ -59,6 +61,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     private _prevX = 0;
     private _prevY = 0;
     private _centerPoints: { X: number, Y: number }[] = [];
+    private _inkDocs: { x: number, y: number, width: number, height: number }[] = [];
 
     @observable private _accumulatedTitle = "";
     @observable private _titleControlString: string = "#title";
@@ -309,8 +312,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     const right = Math.max(...xs);
                     const bottom = Math.max(...ys);
 
-                    doc._height = (bottom - top) * element.props.ScreenToLocalTransform().Scale;
-                    doc._width = (right - left) * element.props.ScreenToLocalTransform().Scale;
+                    // doc._height = (bottom - top) * element.props.ScreenToLocalTransform().Scale;
+                    // doc._width = (right - left) * element.props.ScreenToLocalTransform().Scale;
+                    doc._height = (bottom - top);
+                    doc._width = (right - left);
 
                 }
                 index++;
@@ -329,6 +334,16 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     _dragHeights = new Map<Doc, number>();
     @action
     onPointerDown = (e: React.PointerEvent): void => {
+
+        this._inkDocs = [];
+        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
+            const doc = Document(element.rootDoc);
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height) {
+                this._inkDocs.push({ x: doc.x, y: doc.y, width: doc._width, height: doc._height });
+            }
+
+        }));
+
         setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, (e) => { });
         if (e.button === 0) {
             this._resizeHdlId = e.currentTarget.id;
@@ -501,6 +516,28 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         (e.button === 0) && this._resizeUndo?.end();
         this._resizeUndo = undefined;
         SnappingManager.clearSnapLines();
+
+
+        //need to change points for resize, or else rotation/control points will fail.
+        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView, index) => {
+            const doc = Document(element.rootDoc);
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                console.log(doc.x, doc.y, doc._height, doc._width);
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
+                    const newPoints: { X: number, Y: number }[] = [];
+                    for (var i = 0; i < ink.length; i++) {
+                        // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                        const newX = (doc.x - this._inkDocs[index].x) + (ink[i].X * doc._width) / this._inkDocs[index].width;
+                        const newY = (doc.y - this._inkDocs[index].y) + (ink[i].Y * doc._height) / this._inkDocs[index].height;
+                        newPoints.push({ X: newX, Y: newY });
+                    }
+                    doc.data = new InkField(newPoints);
+
+                }
+
+            }
+        }));
     }
 
     @computed
@@ -591,6 +628,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         if (bounds.y > bounds.b) {
             bounds.y = bounds.b - (this._resizeBorderWidth + this._linkBoxHeight + this._titleHeight);
         }
+        var offset = 0;
+        //make offset larger for ink to edit points
+        if (seldoc.rootDoc.type === DocumentType.INK) {
+            offset = 20;
+        }
         return (<div className="documentDecorations" style={{ background: darkScheme }} >
             <div className="documentDecorations-background" style={{
                 width: (bounds.r - bounds.x + this._resizeBorderWidth) + "px",
@@ -603,10 +645,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             </div>
             {bounds.r - bounds.x < 15 && bounds.b - bounds.y < 15 ? (null) : <>
                 <div className="documentDecorations-container" key="container" ref={this.setTextBar} style={{
-                    width: (bounds.r - bounds.x + this._resizeBorderWidth) + "px",
-                    height: (bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight) + "px",
-                    left: bounds.x - this._resizeBorderWidth / 2,
-                    top: bounds.y - this._resizeBorderWidth / 2 - this._titleHeight,
+                    width: (bounds.r - bounds.x + this._resizeBorderWidth + offset) + "px",
+                    height: (bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + offset) + "px",
+                    left: bounds.x - this._resizeBorderWidth / 2 - offset / 2,
+                    top: bounds.y - this._resizeBorderWidth / 2 - this._titleHeight - offset / 2,
                 }}>
                     {maximizeIcon}
                     {titleArea}
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 2eec8ed6a..9faf5e6a5 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -668,6 +668,10 @@ export default class GestureOverlay extends Touchable {
     }
 
     makePolygon = (shape: string, gesture: boolean) => {
+        //take off gesture recognition for now
+        if (gesture) {
+            return false;
+        }
         const xs = this._points.map(p => p.X);
         const ys = this._points.map(p => p.Y);
         var right = Math.max(...xs);
@@ -796,19 +800,7 @@ export default class GestureOverlay extends Touchable {
                 break;
             case "line":
                 this._points.push({ X: left, Y: top });
-
-                this._points.push({ X: left, Y: top });
-
-                // this._points.push({ X: right, Y: bottom });
-                // this._points.push({ X: right, Y: bottom });
-                // this._points.push({ X: right, Y: bottom });
-                // this._points.push({ X: right, Y: bottom });
-
-
-                this._points.push({ X: right, Y: bottom });
                 this._points.push({ X: right, Y: bottom });
-
-                // this._points.push({ X: right, Y: bottom - 1 });
                 break;
             case "arrow":
                 const x1 = left;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 22c89b6da..b03d8e79b 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -105,9 +105,9 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
             StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
             "none", "none", "0", scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
 
-        const controlPoints: { X: number, Y: number, I: number }[] = [];
-        const handlePoints: { X: number, Y: number, I: number, dot1: number, dot2: number }[] = [];
-        const handleLine: { X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, dot1: number, dot2: number }[] = [];
+        var controlPoints: { X: number, Y: number, I: number }[] = [];
+        var handlePoints: { X: number, Y: number, I: number, dot1: number, dot2: number }[] = [];
+        var handleLine: { X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, dot1: number, dot2: number }[] = [];
         if (data.length >= 4) {
             for (var i = 0; i <= data.length - 4; i += 4) {
                 controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
@@ -125,6 +125,15 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
             handleLine.push({ X1: data[data.length - 2].X, Y1: data[data.length - 2].Y, X2: data[data.length - 1].X, Y2: data[data.length - 1].Y, X3: data[data.length - 1].X, Y3: data[data.length - 1].Y, dot1: data.length - 1, dot2: data.length - 1 });
 
 
+        }
+        if (data.length <= 4) {
+            handlePoints = [];
+            handleLine = [];
+            controlPoints = [];
+            for (var i = 0; i < data.length; i++) {
+                controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
+            }
+
         }
         const dotsize = String(Math.min(width * scaleX, height * scaleY) / 40);
 
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
index 88876471c..010beb836 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
@@ -24,11 +24,13 @@
 
 .formatShapePane-inputBtn {
     width: inherit;
-     position: absolute;
+    position: absolute;
 }
 
 .sketch-picker {
     background: #323232;
+    width: 160px !important;
+    height: 80% !important;
 
     .flexbox-fit {
         background: #323232;
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index a2dc241c0..a47430453 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -12,6 +12,8 @@ import { SelectionManager } from "../../../util/SelectionManager";
 import AntimodeMenu from "../../AntimodeMenu";
 import "./FormatShapePane.scss";
 import { undoBatch } from "../../../util/UndoManager";
+import { ColorState, SketchPicker } from 'react-color';
+import { DocumentView } from "../../../views/nodes/DocumentView"
 
 @observer
 export default class FormatShapePane extends AntimodeMenu {
@@ -20,12 +22,11 @@ export default class FormatShapePane extends AntimodeMenu {
     private _lastFill = "#D0021B";
     private _lastLine = "#D0021B";
     private _lastDash = "2";
-    private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF"];
     private _mode = ["fill-drip", "ruler-combined"];
 
-    @observable private _subOpen = [false, false, false, false];
+    @observable private _subOpen = [false, false];
     @observable private _currMode = "fill-drip";
-    @observable private _lock = false;
+    @observable _lock = false;
     @observable private _fillBtn = false;
     @observable private _lineBtn = false;
     @observable _controlBtn = false;
@@ -104,19 +105,58 @@ export default class FormatShapePane extends AntimodeMenu {
     upDownButtons = (dirs: string, field: string) => {
         switch (field) {
             case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break;
+            // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break;
             case "Xps": this.selectedInk?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break;
             case "Yps": this.selectedInk?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break;
             case "stk": this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
             case "wid": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
+                //redraw points
                 const oldWidth = NumCast(i.rootDoc._width);
+                const oldHeight = NumCast(i.rootDoc._height);
+                const oldX = NumCast(i.rootDoc.x);
+                const oldY = NumCast(i.rootDoc.y);
                 i.rootDoc._width = oldWidth + (dirs === "up" ? 10 : - 10);
                 this._lock && (i.rootDoc._height = (i.rootDoc._width / oldWidth * NumCast(i.rootDoc._height)));
+                const doc = Document(i.rootDoc);
+                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                    console.log(doc.x, doc.y, doc._height, doc._width);
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    console.log(ink);
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        for (var j = 0; j < ink.length; j++) {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = (doc.x - oldX) + (ink[j].X * doc._width) / oldWidth;
+                            const newY = (doc.y - oldY) + (ink[j].Y * doc._height) / oldHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        }
+                        doc.data = new InkField(newPoints);
+                    }
+                }
             });
                 break;
             case "hgt": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
+                const oldWidth = NumCast(i.rootDoc._width);
                 const oldHeight = NumCast(i.rootDoc._height);
-                i.rootDoc._height = oldHeight + (dirs === "up" ? 10 : - 10);
+                const oldX = NumCast(i.rootDoc.x);
+                const oldY = NumCast(i.rootDoc.y); i.rootDoc._height = oldHeight + (dirs === "up" ? 10 : - 10);
                 this._lock && (i.rootDoc._width = (i.rootDoc._height / oldHeight * NumCast(i.rootDoc._width)));
+                const doc = Document(i.rootDoc);
+                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                    console.log(doc.x, doc.y, doc._height, doc._width);
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    console.log(ink);
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        for (var j = 0; j < ink.length; j++) {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = (doc.x - oldX) + (ink[j].X * doc._width) / oldWidth;
+                            const newY = (doc.y - oldY) + (ink[j].Y * doc._height) / oldHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        }
+                        doc.data = new InkField(newPoints);
+                    }
+                }
             });
                 break;
         }
@@ -124,12 +164,11 @@ export default class FormatShapePane extends AntimodeMenu {
 
     @undoBatch
     @action
-    rotate = (degrees: number) => {
-        this.selectedInk?.forEach(action(inkView => {
+    rotate = (angle: number) => {
+        const _centerPoints: { X: number, Y: number }[] = [];
+        SelectionManager.SelectedDocuments().forEach(action(inkView => {
             const doc = Document(inkView.rootDoc);
             if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
-                const angle = Number(degrees) - Number(doc.rotation);
-                doc.rotation = Number(degrees);
                 const ink = Cast(doc.data, InkField)?.inkData;
                 if (ink) {
                     const xs = ink.map(p => p.X);
@@ -138,25 +177,37 @@ export default class FormatShapePane extends AntimodeMenu {
                     const top = Math.min(...ys);
                     const right = Math.max(...xs);
                     const bottom = Math.max(...ys);
-                    const _centerPoints: { X: number, Y: number }[] = [];
                     _centerPoints.push({ X: left, Y: top });
+                }
+            }
+        }));
+
+        var index = 0;
+        SelectionManager.SelectedDocuments().forEach(action(inkView => {
+            const doc = Document(inkView.rootDoc);
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                doc.rotation = Number(doc.rotation) + Number(angle);
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
 
                     const newPoints: { X: number, Y: number }[] = [];
                     for (var i = 0; i < ink.length; i++) {
-                        const newX = Math.cos(angle) * (ink[i].X - _centerPoints[0].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[0].Y) + _centerPoints[0].X;
-                        const newY = Math.sin(angle) * (ink[i].X - _centerPoints[0].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[0].Y) + _centerPoints[0].Y;
+                        const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X;
+                        const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y;
                         newPoints.push({ X: newX, Y: newY });
                     }
                     doc.data = new InkField(newPoints);
-                    const xs2 = newPoints.map(p => p.X);
-                    const ys2 = newPoints.map(p => p.Y);
-                    const left2 = Math.min(...xs2);
-                    const top2 = Math.min(...ys2);
-                    const right2 = Math.max(...xs2);
-                    const bottom2 = Math.max(...ys2);
-                    doc._height = (bottom2 - top2) * inkView.props.ScreenToLocalTransform().Scale;
-                    doc._width = (right2 - left2) * inkView.props.ScreenToLocalTransform().Scale;
+                    const xs = newPoints.map(p => p.X);
+                    const ys = newPoints.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+
+                    doc._height = (bottom - top);
+                    doc._width = (right - left);
                 }
+                index++;
             }
         }));
     }
@@ -180,8 +231,10 @@ export default class FormatShapePane extends AntimodeMenu {
                                 (order === 0 && controlNum !== 0 && i === controlNum - 1) ||
                                 (order === 3 && i === controlNum - 1) ||
                                 (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 1) ||
-                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 2)) {
-                                newPoints.push({ X: ink[i].X - (xDiff), Y: ink[i].Y - (yDiff) });
+                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 2)
+                                || ((ink[0].X === ink[ink.length - 1].X) && (ink[0].Y === ink[ink.length - 1].Y) && (i === 0 || i === ink.length - 1) && (controlNum === 0 || controlNum === ink.length - 1))
+                            ) {
+                                newPoints.push({ X: ink[i].X - (xDiff * inkView.props.ScreenToLocalTransform().Scale), Y: ink[i].Y - (yDiff * inkView.props.ScreenToLocalTransform().Scale) });
                             }
                             else {
                                 newPoints.push({ X: ink[i].X, Y: ink[i].Y });
@@ -189,6 +242,10 @@ export default class FormatShapePane extends AntimodeMenu {
                         }
                         const oldx = doc.x;
                         const oldy = doc.y;
+                        const xs = newPoints.map(p => p.X);
+                        const ys = newPoints.map(p => p.Y);
+                        const left = Math.min(...xs);
+                        const top = Math.min(...ys);
                         doc.data = new InkField(newPoints);
                         const xs2 = newPoints.map(p => p.X);
                         const ys2 = newPoints.map(p => p.Y);
@@ -196,141 +253,202 @@ export default class FormatShapePane extends AntimodeMenu {
                         const top2 = Math.min(...ys2);
                         const right2 = Math.max(...xs2);
                         const bottom2 = Math.max(...ys2);
-                        doc._height = (bottom2 - top2) * inkView.props.ScreenToLocalTransform().Scale;
-                        doc._width = (right2 - left2) * inkView.props.ScreenToLocalTransform().Scale;
-                        doc.x = oldx;
-                        doc.y = oldy;
+                        doc._height = (bottom2 - top2);
+                        doc._width = (right2 - left2);
+
+                        doc.x = oldx - (left - left2);
+                        doc.y = oldy - (top - top2);
                     }
                 }
             }
         }));
     }
 
+    @undoBatch
+    @action
+    switchStk = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorStk = val;
+        return true;
+    }
 
-    colorPicker(setter: (color: string) => {}) {
-        return <div className="btn-group-palette" key="colorpicker" >
-            {this._palette.map(color =>
-                <button className="antimodeMenu-button" key={color} onPointerDown={undoBatch(action(() => setter(color)))} style={{ zIndex: 1001, position: "relative" }}>
-                    <div className="color-previewII" style={{ backgroundColor: color }} />
-                </button>)}
+    @undoBatch
+    @action
+    switchFil = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorFil = val;
+        return true;
+    }
+
+
+    colorPicker(setter: (color: string) => {}, type: string) {
+        return <div className="btn-group-palette" key="colorpicker" style={{ width: 160, margin: 10 }}>
+            <SketchPicker onChange={type === "stk" ? this.switchStk : this.switchFil} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
+                color={type === "stk" ? this.colorStk : this.colorFil} />
         </div>;
     }
     inputBox = (key: string, value: any, setter: (val: string) => {}) => {
         return <>
-            <input style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+            <input style={{ color: "black", width: 40, position: "absolute", right: 20 }}
                 type="text" value={value}
-                onChange={e => setter(e.target.value)}
+                onChange={undoBatch(action((e) => setter(e.target.value)))}
                 autoFocus />
-            <button className="antiMenu-Buttonup" key="up" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))}>
+            <button className="antiMenu-Buttonup" key="up1" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))}>
                 ˄
             </button>
             <br />
-            <button className="antiMenu-Buttonup" key="down" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: -8 }}>
+            <button className="antiMenu-Buttonup" key="down1" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: -8 }}>
                 ˅
             </button>
         </>;
     }
 
+    inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
+        return <>
+            {title1}
+            <p style={{ marginTop: -20, right: 70, position: "absolute" }}>{title2}</p>
+
+            <input style={{ color: "black", width: 40, position: "absolute", right: 130 }}
+                type="text" value={value}
+                onChange={e => setter(e.target.value)}
+                autoFocus />
+            <button className="antiMenu-Buttonup" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} style={{ right: 110 }}>
+                ˄
+        </button>
+            <button className="antiMenu-Buttonup" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: 12, right: 110 }}>
+                ˅
+        </button>
+            {title2 === "" ? "" : <>
+                <input style={{ color: "black", width: 40, position: "absolute", right: 20 }}
+                    type="text" value={value2}
+                    onChange={e => setter2(e.target.value)}
+                    autoFocus />
+                <button className="antiMenu-Buttonup" key="up3" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key2)))}>
+                    ˄
+      </button>
+                <br />
+                <button className="antiMenu-Buttonup" key="down3" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key2)))} style={{ marginTop: -8 }}>
+                    ˅
+      </button></>}
+        </>;
+    }
+
+
     colorButton(value: string, setter: () => {}) {
         return <>
-            <button className="antimodeMenu-button" key="fill" onPointerDown={undoBatch(action(e => setter()))} style={{ position: "absolute", right: 80 }}>
-                <FontAwesomeIcon icon="fill-drip" size="lg" />
-                <div className="color-previewI" style={{ backgroundColor: value ?? "121212" }} />
+            <button className="antimodeMenu-button" key="fill" onPointerDown={undoBatch(action(e => setter()))} style={{ position: "relative", marginTop: -5 }}>
+                <div className="color-previewII" style={{ backgroundColor: value ?? "121212" }} />
+                {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -23, position: "fixed" }}>☒</p> : ""}
             </button>
-            <br /> <br />
         </>;
     }
 
     controlPointsButton() {
         return <>
-            <button className="antimodeMenu-button" key="fill" onPointerDown={action(() => this._controlBtn = this._controlBtn ? false : true)} style={{ position: "absolute", right: 80, backgroundColor: this._controlBtn ? "black" : "" }}>
+            <button className="antimodeMenu-button" title="Edit points" key="fill" onPointerDown={action(() => this._controlBtn = this._controlBtn ? false : true)} style={{ position: "relative", marginTop: 10, backgroundColor: this._controlBtn ? "black" : "" }}>
                 <FontAwesomeIcon icon="bezier-curve" size="lg" />
             </button>
+            <button className="antimodeMenu-button" title="Lock ratio" key="fill" onPointerDown={action(() => this._lock = this._lock ? false : true)} style={{ position: "relative", marginTop: 10, backgroundColor: this._lock ? "black" : "" }}>
+                <FontAwesomeIcon icon="lock" size="lg" />
+
+            </button>
+            <button className="antimodeMenu-button" key="fill" title="Rotate 90˚" onPointerDown={action(() => this.rotate(Math.PI / 2))} style={{ position: "relative", marginTop: 10, fontSize: 15 }}>
+                ⟲
+            </button>
+            <br /> <br />
+        </>;
+    }
+
+    lockRatioButton() {
+        return <>
+            <button className="antimodeMenu-button" key="fill" onPointerDown={action(() => this._lock = this._lock ? false : true)} style={{ position: "absolute", right: 80, backgroundColor: this._lock ? "black" : "" }}>
+                {/* <FontAwesomeIcon icon="bezier-curve" size="lg" /> */}
+                <FontAwesomeIcon icon="lock" size="lg" />
+
+            </button>
+            <br /> <br />
+        </>;
+    }
+
+    rotate90Button() {
+        return <>
+            <button className="antimodeMenu-button" key="fill" onPointerDown={action(() => this.rotate(Math.PI / 2))} style={{ position: "absolute", right: 80, }}>
+                {/* <FontAwesomeIcon icon="bezier-curve" size="lg" /> */}
+                ⟲
+
+            </button>
             <br /> <br />
         </>;
     }
-    @computed get fillButton() { return this.colorButton(this.colorFil, () => this._fillBtn = !this._fillBtn); }
-    @computed get lineButton() { return this.colorButton(this.colorStk, () => this._lineBtn = !this._lineBtn); }
+    @computed get fillButton() { return this.colorButton(this.colorFil, () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
+    @computed get lineButton() { return this.colorButton(this.colorStk, () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
 
-    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color); }
-    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color); }
+    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
+    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
 
     @computed get stkInput() { return this.inputBox("stk", this.widthStk, (val: string) => this.widthStk = val); }
-    @computed get hgtInput() { return this.inputBox("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val); }
+    @computed get dashInput() { return this.inputBox("dsh", this.widthStk, (val: string) => this.widthStk = val); }
+
+    @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val, "H:", "wid", this.shapeWid, (val: string) => this.shapeWid = val, "W:"); }
     @computed get widInput() { return this.inputBox("wid", this.shapeWid, (val: string) => this.shapeWid = val); }
-    @computed get rotInput() { return this.inputBox("rot", this.shapeRot, (val: string) => this.shapeRot = val); }
-    @computed get XpsInput() { return this.inputBox("Xps", this.shapeXps, (val: string) => this.shapeXps = val); }
+    @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); }
+
+    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
     @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); }
 
     @computed get controlPoints() { return this.controlPointsButton(); }
+    @computed get lockRatio() { return this.lockRatioButton(); }
+    @computed get rotate90() { return this.rotate90Button(); }
 
-    @computed get propertyGroupItems() {
-        const fillCheck = <div key="fill" style={{ display: this._subOpen[0] ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            <input className="formatShapePane-inputBtn" type="radio" checked={this.unFilled} onChange={undoBatch(action(() => this.unFilled = true))} />
-                No Fill
-            <br />
-            <input className="formatShapePane-inputBtn" type="radio" checked={this.solidFil} onChange={undoBatch(action(() => this.solidFil = true))} />
-                Solid Fill
-            <br /> <br />
-            {this.solidFil ? "Color" : ""}
-            {this.solidFil ? this.fillButton : ""}
-            {this._fillBtn && this.solidFil ? this.fillPicker : ""}
-        </div>;
 
-        const markers = <>
-            <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.markHead !== ""} onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} />
-                Arrow Head
-            <br />
-            <input key="markTail" className="formatShapePane-inputBtn" type="checkbox" checked={this.markTail !== ""} onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} />
-                Arrow End
-            <br />
-        </>;
+    @computed get propertyGroupItems() {
+        const fillCheck = <div key="fill" style={{ display: (this._subOpen[0] && this.selectedInk && this.selectedInk.length >= 1) ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
+            Fill:
+            {this.fillButton}
+            <div style={{ float: "left", width: 100 }} >
+                Stroke:
+            {this.lineButton}
+            </div>
 
-        const lineCheck = <div key="lineCheck" style={{ display: this._subOpen[1] ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            <input className="formatShapePane-inputBtn" type="radio" checked={this.unStrokd} onChange={undoBatch(action(() => this.unStrokd = true))} />
-                No Line
-            <br />
-            <input className="formatShapePane-inputBtn" type="radio" checked={this.solidStk} onChange={undoBatch(action(() => this.solidStk = true))} />
-                Solid Line
-            <br />
-            <input className="formatShapePane-inputBtn" type="radio" checked={this.dashdStk ? true : false} onChange={undoBatch(action(() => this.dashdStk = "2"))} />
-                Dash Line
-            <br />
-            <br />
-            {(this.solidStk || this.dashdStk) ? "Color" : ""}
-            {(this.solidStk || this.dashdStk) ? this.lineButton : ""}
-            {(this.solidStk || this.dashdStk) && this._lineBtn ? this.linePicker : ""}
-            <br />
+            {this._fillBtn ? this.fillPicker : ""}
+            {this._lineBtn ? this.linePicker : ""}
+            {this._fillBtn || this._lineBtn ? "" : <br />}
             {(this.solidStk || this.dashdStk) ? "Width" : ""}
             {(this.solidStk || this.dashdStk) ? this.stkInput : ""}
-            {(this.solidStk || this.dashdStk) ? <input type="range" defaultValue={Number(this.widthStk)} min={1} max={100} onChange={e => this.widthStk = e.target.value} /> : (null)}
-            <br /> <br />
-            {(this.solidStk || this.dashdStk) ? markers : ""}
-        </div>;
 
-        const sizeCheck = <div key="sizeCheck" style={{ display: this._subOpen[2] ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            Height {this.hgtInput}
-            <br /> <br />
-                Width {this.widInput}
-            <br /> <br />
-            <input className="formatShapePane-inputBtn" style={{ right: 0 }} type="checkbox" checked={this._lock} onChange={undoBatch(action(() => this._lock = !this._lock))} />
-                Lock Ratio
-            <br />  <br />
-                Rotation {this.rotInput}
-            <br /> <br />
-                Edit Points {this.controlPoints}
-        </div>;
 
-        const positionCheck = <div key="posCheck" style={{ display: this._subOpen[3] ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            Horizontal {this.XpsInput}
-            <br /> <br />
-            Vertical {this.YpsInput}
-            <br /> <br />
+            {(this.solidStk || this.dashdStk) ? <input type="range" defaultValue={Number(this.widthStk)} min={1} max={100} onChange={undoBatch(action((e) => this.widthStk = e.target.value))} /> : (null)}
+            <br />
+            {(this.solidStk || this.dashdStk) ? <>
+                <p style={{ position: "absolute", fontSize: 12 }}>Arrow Head</p>
+                <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.markHead !== ""} onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} style={{ position: "absolute", right: 110, width: 20 }} />
+                <p style={{ position: "absolute", fontSize: 12, right: 30 }}>Arrow End</p>
+                <input key="markTail" className="formatShapePane-inputBtn" type="checkbox" checked={this.markTail !== ""} onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} style={{ position: "absolute", right: 0, width: 20 }} />
+                <br />
+            </> : ""}
+            Dash:                <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.dashdStk === "2"} onChange={undoBatch(action(() => this.dashdStk = this.dashdStk === "2" ? "0" : "2"))} style={{ position: "absolute", right: 110, width: 20 }} />
+
+
+
         </div>;
 
-        const subMenus = this._currMode === "fill-drip" ? [`fill`, `line`] : [`size`, `position`];
-        const menuItems = this._currMode === "fill-drip" ? [fillCheck, lineCheck] : [sizeCheck, positionCheck];
-        const indexOffset = this._currMode === "fill-drip" ? 0 : 2;
+
+
+        const sizeCheck =
+
+            <div key="sizeCheck" style={{ display: (this._subOpen[1] && this.selectedInk && this.selectedInk.length >= 1) ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
+                {this.controlPoints}
+                {this.hgtInput}
+                {this.XpsInput}
+                {this.rotInput}
+
+            </div>;
+
+
+        const subMenus = this._currMode === "fill-drip" ? [`Appearance`, 'Transform'] : [];
+        const menuItems = this._currMode === "fill-drip" ? [fillCheck, sizeCheck] : [];
+        const indexOffset = 0;
+
         return <div className="antimodeMenu-sub" key="submenu" style={{ position: "absolute", width: "inherit", top: 60 }}>
             {subMenus.map((subMenu, i) =>
                 <div key={subMenu} style={{ width: "inherit" }}>
@@ -361,6 +479,7 @@ export default class FormatShapePane extends AntimodeMenu {
     }
 
     render() {
-        return this.getElementVert([this.closeBtn, this.propertyGroupBtn, this.propertyGroupItems]);
+        return this.getElementVert([this.closeBtn,
+        this.propertyGroupItems]);
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 15707ad9e..80d1264ce 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -16,11 +16,11 @@ import { Document } from "../../../../fields/documentSchemas";
 import { DocumentType } from "../../../documents/DocumentTypes";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
-import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faSleigh, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, } from "@fortawesome/free-solid-svg-icons";
+import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faSleigh, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, faArrowRight, faArrowsAltH, faMinus, faCircle, faExclamationTriangle, faSquare, faLongArrowAltRight, faPenFancy, faCaretSquareRight, faAngleDoubleRight, } from "@fortawesome/free-solid-svg-icons";
 import { Cast, StrCast, BoolCast } from "../../../../fields/Types";
 import FormatShapePane from "./FormatShapePane";
 
-library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve);
+library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, faLongArrowAltRight, faArrowsAltH, faMinus, faCircle, faSquare, faSquare, faPenFancy, faAngleDoubleRight,);
 
 
 
@@ -30,18 +30,13 @@ export default class InkOptionsMenu extends AntimodeMenu {
 
     private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""];
     private _width = ["1", "5", "10", "100"];
-    // private _buttons = ["circle", "triangle", "rectangle", "arrow", "line"];
-    // private _icons = ["O", "∆", "ロ", "➜", "-"];
-    // private _buttons = ["circle", "triangle", "rectangle", "line", "noRec", "",];
-    // private _icons = ["O", "∆", "ロ", "⎯⎯⎯", "✖︎", " "];
-    //arrowStart and arrowEnd must match and defs must exist in Inking Stroke
-    // private _arrowStart = ["arrowStart", "arrowStart", "dot", "dot", "none"];
-    // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"];
-    // private _arrowIcons = ["→", "↔︎", "•", "••", " "];
-    private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"];
-    private _head = ["", "", "arrow", "", "", "arrow", "", "", ""];
-    private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""];
-    private _shape = ["line", "line", "line", "", "", "", "rectangle", "circle", "triangle"];
+    private _dotsize = [10, 20, 30, 40];
+    private _draw = ["∿", "⎯", "→", "↔︎", "ロ", "O"];
+    private _head = ["", "", "", "arrow", "", ""];
+    private _end = ["", "", "arrow", "arrow", "", ""];
+    private _shape = ["", "line", "line", "line", "rectangle", "circle"];
+    private _title = ["pen", "line", "line with arrow", "line with double arrows", "square", "circle",];
+    private _faName = ["pen-fancy", "minus", "long-arrow-alt-right", "arrows-alt-h", "square", "circle"];
 
     @observable _shapesNum = this._shape.length;
     @observable _selected = this._shapesNum;
@@ -154,6 +149,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
                 return <button
                     className="antimodeMenu-button"
                     key={icon}
+                    title={this._title[i]}
                     onPointerDown={action(() => {
                         this._double = "";
 
@@ -202,50 +198,19 @@ export default class InkOptionsMenu extends AntimodeMenu {
 
                     })}
                     style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}>
-                    {this._draw[i]}
+                    <FontAwesomeIcon icon={this._faName[i] as IconProp} size="sm" />
+
                 </button>;
             })}</div>;
         return drawButtons;
     }
 
-    // @computed get arrowPicker() {
-    //     var currIcon;
-    //     for (var i = 0; i < this._arrowStart.length; i++) {
-    //         if (this._arrowStart[i] === ActiveArrowStart() && this._arrowEnd[i] === ActiveArrowEnd()) {
-    //             currIcon = this._arrowIcons[i];
-    //             if (this._arrowIcons[i] === " ") {
-    //                 currIcon = "➤";
-    //             }
-    //         }
-    //     }
-    //     var arrowPicker = <button
-    //         className="antimodeMenu-button"
-    //         key="arrow"
-    //         onPointerDown={action(e => this._arrowBtn = !this._arrowBtn)}
-    //         style={{ backgroundColor: this._arrowBtn ? "121212" : "" }}>
-    //         {currIcon}
-    //     </button>;
-    //     if (this._arrowBtn) {
-    //         arrowPicker = <div className="btn2-group" key="arrows">
-    //             {arrowPicker}
-    //             {this._arrowStart.map((arrowStart, i) => {
-    //                 return <button
-    //                     className="antimodeMenu-button"
-    //                     key={arrowStart}
-    //                     onPointerDown={action(() => { SetActiveArrowStart(arrowStart); SetActiveArrowEnd(this._arrowEnd[i]); this.editProperties(arrowStart, "arrowStart"), this.editProperties(this._arrowEnd[i], "arrowEnd"); this._arrowBtn = false; })}
-    //                     style={{ backgroundColor: this._arrowBtn ? "121212" : "" }}>
-    //                     {this._arrowIcons[i]}
-    //                 </button>;
-    //             })}
-    //         </div>;
-    //     }
-    //     return arrowPicker;
-    // }
 
     @computed get widthPicker() {
         var widthPicker = <button
             className="antimodeMenu-button"
             key="width"
+            title="change width"
             onPointerDown={action(e => this._widthBtn = !this._widthBtn)}
             style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
             <FontAwesomeIcon icon="bars" size="lg" />
@@ -253,13 +218,13 @@ export default class InkOptionsMenu extends AntimodeMenu {
         if (this._widthBtn) {
             widthPicker = <div className="btn2-group" key="width">
                 {widthPicker}
-                {this._width.map(wid => {
+                {this._width.map((wid, i) => {
                     return <button
                         className="antimodeMenu-button"
                         key={wid}
                         onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })}
-                        style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001 }}>
-                        {wid}
+                        style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001, fontSize: this._dotsize[i], padding: 0, textAlign: "center" }}>
+                        •
                     </button>;
                 })}
             </div>;
@@ -273,7 +238,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
         var colorPicker = <button
             className="antimodeMenu-button"
             key="color"
-            title="colorChanger"
+            title="Change Ink Color"
             onPointerDown={action(e => this._colorBtn = !this._colorBtn)}
             style={{ backgroundColor: this._colorBtn ? "121212" : "" }}>
             <FontAwesomeIcon icon="pen-nib" size="lg" />
@@ -302,7 +267,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
             title="toggle foramatting pane"
             onPointerDown={action(e => FormatShapePane.Instance.Pinned = !FormatShapePane.Instance.Pinned)}
             style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
-            <FontAwesomeIcon icon="chevron-right" size="lg" />
+            <FontAwesomeIcon icon="angle-double-right" size="lg" />
         </button>;
     }
 
@@ -310,7 +275,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
         var fillPicker = <button
             className="antimodeMenu-button"
             key="fill"
-            title="fillChanger"
+            title="Change Fill Color"
             onPointerDown={action(e => this._fillBtn = !this._fillBtn)}
             style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
             <FontAwesomeIcon icon="fill-drip" size="lg" />
@@ -334,48 +299,6 @@ export default class InkOptionsMenu extends AntimodeMenu {
         return fillPicker;
     }
 
-    // @computed get shapePicker() {
-    //     var currIcon;
-    //     if (GestureOverlay.Instance.InkShape === "") {
-    //         currIcon = <FontAwesomeIcon icon="shapes" size="lg" />;
-    //     } else {
-    //         for (var i = 0; i < this._icons.length; i++) {
-    //             if (GestureOverlay.Instance.InkShape === this._buttons[i]) {
-    //                 currIcon = this._icons[i];
-    //             }
-    //         }
-    //     }
-    //     var shapePicker = <button
-    //         className="antimodeMenu-button"
-    //         key="shape"
-    //         onPointerDown={action(e => this._shapeBtn = !this._shapeBtn)}
-    //         style={{ backgroundColor: this._shapeBtn ? "121212" : "" }}>
-    //         {currIcon}
-    //     </button>;
-    //     if (this._shapeBtn) {
-    //         shapePicker = <div className="btn2-group" key="shape">
-    //             {shapePicker}
-    //             {this._buttons.map((btn, i) => {
-    //                 var ttl = btn;
-    //                 if (btn === "") {
-    //                     ttl = "no shape";
-    //                 }
-    //                 if (btn === "noRec") {
-    //                     ttl = "disable shape recognition";
-    //                 }
-    //                 return <button
-    //                     className="antimodeMenu-button"
-    //                     title={`Draw ${btn}`}
-    //                     key={ttl}
-    //                     onPointerDown={action((e) => { GestureOverlay.Instance.InkShape = btn; this._shapeBtn = false; })}
-    //                     style={{ backgroundColor: this._shapeBtn ? "121212" : "", fontSize: "20" }}>
-    //                     {this._icons[i]}
-    //                 </button>;
-    //             })}
-    //         </div>;
-    //     }
-    //     return shapePicker;
-    // }
 
     @computed get bezierButton() {
         return <button
@@ -403,18 +326,15 @@ export default class InkOptionsMenu extends AntimodeMenu {
 
     render() {
         const buttons = [
-            // <button className="antimodeMenu-button" title="Drag" key="drag" onPointerDown={e => this.dragStart(e)}>
-            //     <FontAwesomeIcon icon="arrows-alt" size="lg" />
-            // </button>,
-            // this.shapePicker,
-            // this.bezierButton,
+
+            this.drawButtons,
             this.widthPicker,
             this.colorPicker,
             this.fillPicker,
-            this.drawButtons,
+
+
             this.formatPane,
-            // this.arrowPicker,
-            // this.dashButton,
+
             <button className="antimodeMenu-button" key="pin menu" title="Pin menu" onClick={this.toggleMenuPin} style={{ backgroundColor: this.Pinned ? "#121212" : "", display: this.collapsed ? "none" : undefined }}>
                 <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
             </button>
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 57028b0ca..b186d9ffc 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -54,27 +54,30 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps, ColorDocument
     }
     render() {
         const selDoc = SelectionManager.SelectedDocuments()?.[0]?.rootDoc;
-        return <div className={`colorBox-container${this.active() ? "-interactive" : ""}`}
-            onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()}
-            style={{ transform: `scale(${this.props.ContentScaling()})`, width: `${100 / this.props.ContentScaling()}%`, height: `${100 / this.props.ContentScaling()}%` }} >
+        // return <div className={`colorBox-container${this.active() ? "-interactive" : ""}`}
+        //     onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()}
+        //     style={{ transform: `scale(${this.props.ContentScaling()})`, width: `${100 / this.props.ContentScaling()}%`, height: `${100 / this.props.ContentScaling()}%` }} >
 
-            <SketchPicker onChange={ColorBox.switchColor} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
-                color={StrCast(ActiveInkPen()?.backgroundColor,
-                    StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} />
-            <div style={{ display: "grid", gridTemplateColumns: "20% 80%", paddingTop: "10px" }}>
-                <div> {ActiveInkWidth() ?? 2}</div>
-                <input type="range" defaultValue={ActiveInkWidth() ?? 2} min={1} max={100} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                    SetActiveInkWidth(e.target.value);
-                    SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value));
-                }} />
-                <div> {ActiveInkBezierApprox() ?? 2}</div>
-                <input type="range" defaultValue={ActiveInkBezierApprox() ?? 2} min={0} max={300} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                    SetActiveBezierApprox(e.target.value);
-                    SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeBezier = e.target.value);
-                }} />
-                <br />
-                <br />
-            </div>
-        </div>;
+        //     <SketchPicker onChange={ColorBox.switchColor} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
+        //         color={StrCast(ActiveInkPen()?.backgroundColor,
+        //             StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} />
+
+        //     <div style={{ display: "grid", gridTemplateColumns: "20% 80%", paddingTop: "10px" }}>
+        //         <div> {ActiveInkWidth() ?? 2}</div>
+        //         <input type="range" defaultValue={ActiveInkWidth() ?? 2} min={1} max={100} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
+        //             SetActiveInkWidth(e.target.value);
+        //             SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value));
+        //         }} />
+        //         <div> {ActiveInkBezierApprox() ?? 2}</div>
+        //         <input type="range" defaultValue={ActiveInkBezierApprox() ?? 2} min={0} max={300} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
+        //             SetActiveBezierApprox(e.target.value);
+        //             SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeBezier = e.target.value);
+        //         }} />
+        //         <br />
+        //         <br />
+        //     </div>
+        // </div>
+        //     ;
+        return <></>;
     }
 }
-- 
cgit v1.2.3-70-g09d2


From 65d3c9672fc3cf0dc981588f220dad269beb4aeb Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Tue, 28 Jul 2020 00:10:22 +0900
Subject:  fixed control points from moving

---
 .../views/collections/collectionFreeForm/FormatShapePane.tsx      | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/FormatShapePane.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index a47430453..adb71c6aa 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -242,8 +242,8 @@ export default class FormatShapePane extends AntimodeMenu {
                         }
                         const oldx = doc.x;
                         const oldy = doc.y;
-                        const xs = newPoints.map(p => p.X);
-                        const ys = newPoints.map(p => p.Y);
+                        const xs = ink.map(p => p.X);
+                        const ys = ink.map(p => p.Y);
                         const left = Math.min(...xs);
                         const top = Math.min(...ys);
                         doc.data = new InkField(newPoints);
@@ -255,9 +255,11 @@ export default class FormatShapePane extends AntimodeMenu {
                         const bottom2 = Math.max(...ys2);
                         doc._height = (bottom2 - top2);
                         doc._width = (right2 - left2);
-
+                        //if points move out of bounds
+                        console.log(doc.x);
                         doc.x = oldx - (left - left2);
                         doc.y = oldy - (top - top2);
+                        console.log(doc.x);
                     }
                 }
             }
-- 
cgit v1.2.3-70-g09d2


From f3a331573be09115f9a92b8e927081f8f743c478 Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Tue, 28 Jul 2020 01:28:22 +0900
Subject: delete console.log

---
 src/client/views/collections/collectionFreeForm/FormatShapePane.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/FormatShapePane.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index adb71c6aa..a2600a2b3 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -256,10 +256,10 @@ export default class FormatShapePane extends AntimodeMenu {
                         doc._height = (bottom2 - top2);
                         doc._width = (right2 - left2);
                         //if points move out of bounds
-                        console.log(doc.x);
+
                         doc.x = oldx - (left - left2);
                         doc.y = oldy - (top - top2);
-                        console.log(doc.x);
+
                     }
                 }
             }
-- 
cgit v1.2.3-70-g09d2

