From 738a56b3c18c06d8290346373eb60a125120caaf Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 18 Jun 2020 15:02:50 -0700
Subject: hopefully fixed new ink

---
 src/client/util/InteractionUtils.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index aeb0f670d..3b42fcaee 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -96,9 +96,9 @@ export namespace InteractionUtils {
         }
         else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) {
             //pointer is up (first and last points are the same)
-            points.pop();
+            //points.pop();
             const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]);
-
+            newPoints.pop();
             const bezierCurves = fitCurve(newPoints, parseInt(bezier));
             for (var i = 0; i < bezierCurves.length; i++) {
                 for (var t = 0; t < 1; t += 0.01) {
-- 
cgit v1.2.3-70-g09d2


From 065a29e87c771b5cd9301b0468fb036e070cad17 Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Fri, 10 Jul 2020 05:08:53 +0900
Subject: added format shape

---
 src/client/documents/Documents.ts                  |   3 +-
 src/client/util/InteractionUtils.tsx               |   8 +
 src/client/util/SelectionManager.ts                |   5 +
 src/client/views/AntimodeMenu.tsx                  |  18 +
 src/client/views/ContextMenu.tsx                   |   1 +
 src/client/views/DocumentDecorations.tsx           |   2 +
 src/client/views/GestureOverlay.tsx                |  17 +-
 src/client/views/InkingStroke.tsx                  |  15 +-
 src/client/views/MainView.tsx                      |  13 +-
 .../collectionFreeForm/FormatShapePane.scss        |  53 ++
 .../collectionFreeForm/FormatShapePane.tsx         | 996 +++++++++++++++++++++
 .../collectionFreeForm/InkOptionsMenu.scss         |   2 +-
 .../collectionFreeForm/InkOptionsMenu.tsx          |  40 +-
 13 files changed, 1152 insertions(+), 21 deletions(-)
 create mode 100644 src/client/views/collections/collectionFreeForm/FormatShapePane.scss
 create mode 100644 src/client/views/collections/collectionFreeForm/FormatShapePane.tsx

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b70971c2d..eb8e04317 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -653,7 +653,7 @@ export namespace Docs {
             I.type = DocumentType.INK;
             I.layout = InkingStroke.LayoutString("data");
             I.color = color;
-            I.strokeWidth = strokeWidth;
+            I.strokeWidth = Number(strokeWidth);
             I.strokeBezier = strokeBezier;
             I.fillColor = fillColor;
             I.arrowStart = arrowStart;
@@ -667,6 +667,7 @@ export namespace Docs {
             I._width = options._width;
             I._height = options._height;
             I.author = Doc.CurrentUserEmail;
+            I.rotation = 0;
             I.data = new InkField(points);
             return I;
             // return I;
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index edeb461e0..2883e2056 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -3,6 +3,7 @@ import * as beziercurve from 'bezier-curve';
 import * as fitCurve from 'fit-curve';
 import "./InteractionUtils.scss";
 import { Utils } from "../../Utils";
+import InkOptionsMenu from "../views/collections/collectionFreeForm/InkOptionsMenu";
 
 export namespace InteractionUtils {
     export const MOUSETYPE = "mouse";
@@ -94,6 +95,13 @@ export namespace InteractionUtils {
     export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number,
         color: string, width: number, strokeWidth: number, bezier: string, fill: string, arrowStart: string, arrowEnd: string,
         dash: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean, nodefs: boolean) {
+
+        // if (InkOptionsMenu.Instance.Pinned) {
+        //     for (var i = 0; i < points.length; i++) {
+        //         points[i].Y -= 35;
+        //     }
+        // }
+
         let pts: { X: number; Y: number; }[] = [];
         if (shape) { //if any of the shape are true
             pts = makePolygon(shape, points);
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 024532f90..aea2c542b 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -5,6 +5,7 @@ import { computedFn } from "mobx-utils";
 import { List } from "../../fields/List";
 import { Scripting } from "./Scripting";
 import { DocumentManager } from "./DocumentManager";
+import FormatShapePane from "../views/collections/collectionFreeForm/FormatShapePane";
 
 export namespace SelectionManager {
 
@@ -14,6 +15,8 @@ export namespace SelectionManager {
         SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
         @action
         SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
+            console.log("select"
+            );
             // if doc is not in SelectedDocuments, add it
             if (!manager.SelectedDocuments.get(docView)) {
                 if (!ctrlPressed) {
@@ -29,6 +32,8 @@ export namespace SelectionManager {
                 manager.SelectedDocuments.set(docView, true);
             }
             Doc.UserDoc().activeSelection = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
+            FormatShapePane.Instance.selected();
+
         }
         @action
         DeselectDoc(docView: DocumentView): void {
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index d83ac434c..cb6de1785 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -1,6 +1,7 @@
 import React = require("react");
 import { observable, action } from "mobx";
 import "./AntimodeMenu.scss";
+import { inherits } from "util";
 
 /**
  * This is an abstract class that serves as the base for a PDF-style or Marquee-style
@@ -147,6 +148,23 @@ export default abstract class AntimodeMenu extends React.Component {
         );
     }
 
+    protected getElementVert(buttons: JSX.Element[]) {
+        return (
+            <div className="antimodeMenu-cont" onPointerLeave={this.pointerLeave} onPointerEnter={this.pointerEntered} ref={this._mainCont} onContextMenu={this.handleContextMenu}
+                style={{
+                    left: this.Pinned ? undefined : this._left,
+                    top: this.Pinned ? 0 : this._top,
+                    right: this.Pinned ? 0 : undefined,
+                    height: "inherit",
+                    width: 200,
+                    opacity: this._opacity, transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay,
+                    position: this.Pinned ? "absolute" : undefined
+                }}>
+                {buttons}
+            </div>
+        );
+    }
+
 
 
     protected getElementWithRows(rows: JSX.Element[], numRows: number, hasDragger: boolean = true) {
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 941d7b44a..1a6b7ab90 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -224,6 +224,7 @@ export class ContextMenu extends React.Component {
     }
 
     render() {
+        console.log("context");
         if (!this._display) {
             return null;
         }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4fda10926..8edd4c4a9 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -293,6 +293,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
             const doc = Document(element.rootDoc);
             if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                doc.rotation = Number(doc.rotation) + Number(angle);
+                console.log(doc.rotation);
                 const ink = Cast(doc.data, InkField)?.inkData;
                 if (ink) {
 
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index bfd659207..26a06090b 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -633,7 +633,8 @@ export default class GestureOverlay extends Touchable {
                 this.makePolygon(this.InkShape, false);
                 this.dispatchGesture(GestureUtils.Gestures.Stroke);
                 this._points = [];
-                if (this.InkShape !== "noRec") {
+                if (InkOptionsMenu.Instance._double === "") {
+
                     this.InkShape = "";
                 }
             }
@@ -687,12 +688,14 @@ export default class GestureOverlay extends Touchable {
         }
         //get out of ink mode after each stroke=
         console.log("now");
-        Doc.SetSelectedTool(InkTool.None);
-        InkOptionsMenu.Instance._selected = InkOptionsMenu.Instance._shapesNum;
-        SetActiveArrowStart("none");
-        GestureOverlay.Instance.SavedArrowStart = ActiveArrowStart();
-        SetActiveArrowEnd("none");
-        GestureOverlay.Instance.SavedArrowEnd = ActiveArrowEnd();
+        if (InkOptionsMenu.Instance._double === "") {
+            Doc.SetSelectedTool(InkTool.None);
+            InkOptionsMenu.Instance._selected = InkOptionsMenu.Instance._shapesNum;
+            SetActiveArrowStart("none");
+            GestureOverlay.Instance.SavedArrowStart = ActiveArrowStart();
+            SetActiveArrowEnd("none");
+            GestureOverlay.Instance.SavedArrowEnd = ActiveArrowEnd();
+        }
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
 
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index c32e76cec..4a7ec40be 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -15,6 +15,8 @@ import { FieldView, FieldViewProps } from "./nodes/FieldView";
 import React = require("react");
 import { Scripting } from "../util/Scripting";
 import { Doc } from "../../fields/Doc";
+import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
+import { action } from "mobx";
 
 library.add(faPaintBrush);
 
@@ -38,10 +40,19 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         this.props.Document.isInkMask = true;
     }
 
+    @action
+    private formatShape = () => {
+        console.log("Clicked");
+        FormatShapePane.Instance.Pinned = true;
+        FormatShapePane.Instance.selected();
+
+    }
+
     render() {
         TraceMobx();
         const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
-        const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth()));
+        // const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth()));
+        const strokeWidth = Number(this.layoutDoc.strokeWidth);
         const xs = data.map(p => p.X);
         const ys = data.map(p => p.Y);
         const left = Math.min(...xs) - strokeWidth / 2;
@@ -74,6 +85,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
                 onContextMenu={() => {
                     ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" });
                     ContextMenu.Instance.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" });
+                    ContextMenu.Instance.addItem({ description: "Format Shape", event: this.formatShape, icon: "paint-brush" });
+
                 }}
             ><defs>
                 </defs>
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index afdff4ed8..3eed44654 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -58,7 +58,7 @@ import { DocumentManager } from '../util/DocumentManager';
 import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { LinkMenu } from './linking/LinkMenu';
 import { LinkDocPreview } from './nodes/LinkDocPreview';
-
+import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
 @observer
 export class MainView extends React.Component {
     public static Instance: MainView;
@@ -453,12 +453,13 @@ export class MainView extends React.Component {
 
     @computed get mainContent() {
         const sidebar = this.userDoc?.["tabs-panelContainer"];
-        console.log(InkOptionsMenu.Instance?.Pinned);
+        console.log('${ ANTIMODEMENU_HEIGHT }');
         return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
             <div className="mainView-mainContent" style={{
                 color: this.darkScheme ? "rgb(205,205,205)" : "black",
-                height: (RichTextMenu.Instance?.Pinned || InkOptionsMenu.Instance?.Pinned) ? `calc(100% - ${ANTIMODEMENU_HEIGHT})` : "100%"
-
+                //change to times 2 for both pinned
+                height: (RichTextMenu.Instance?.Pinned || InkOptionsMenu.Instance?.Pinned) ? (RichTextMenu.Instance?.Pinned && InkOptionsMenu.Instance?.Pinned) ? `calc(100% - 2*${ANTIMODEMENU_HEIGHT})` : `calc(100% - ${ANTIMODEMENU_HEIGHT})` : "100%",
+                width: (FormatShapePane.Instance?.Pinned) ? `calc(100% - 200px)` : "100%"
             }} >
                 <div style={{ display: "contents", flexDirection: "row", position: "relative" }}>
                     <div className="mainView-flyoutContainer" onPointerLeave={this.pointerLeaveDragger} style={{ width: this.flyoutWidth }}>
@@ -597,7 +598,10 @@ export class MainView extends React.Component {
             <DocumentDecorations />
             <InkOptionsMenu />
 
+
             <GestureOverlay >
+                <FormatShapePane />
+
 
                 <RichTextMenu key="rich" />
                 {this.mainContent}
@@ -608,6 +612,7 @@ export class MainView extends React.Component {
                 linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
                 addDocTab={LinkDocPreview.LinkInfo.addDocTab} /> : (null)}
             <ContextMenu />
+            <FormatShapePane />
             <RadialMenu />
             <PDFMenu />
             <MarqueeOptionsMenu />
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
new file mode 100644
index 000000000..5789c6c75
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
@@ -0,0 +1,53 @@
+.antimodeMenu-button {
+    width: 200px;
+
+    .color-previewI {
+        width: 100%;
+        height: 40%;
+    }
+
+    .color-previewII {
+        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 */
+}
+
+.btn-group-palette {
+    display: block;
+    /* Make the buttons appear below each other */
+}
+
+.btn-draw {
+    display: inline;
+    /* 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/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
new file mode 100644
index 000000000..7b47b7ca4
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -0,0 +1,996 @@
+import React = require("react");
+import AntimodeMenu from "../../AntimodeMenu";
+import { observer } from "mobx-react";
+import { observable, action, computed } from "mobx";
+import "./FormatShapePane.scss";
+import { ActiveInkColor, ActiveInkBezierApprox, ActiveFillColor, ActiveArrowStart, ActiveArrowEnd, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke";
+import { Scripting } from "../../../util/Scripting";
+import { InkTool, InkField } from "../../../../fields/InkField";
+import { ColorState } from "react-color";
+import { Utils } from "../../../../Utils";
+import GestureOverlay from "../../GestureOverlay";
+import { Doc } from "../../../../fields/Doc";
+import { SelectionManager } from "../../../util/SelectionManager";
+import { DocumentView } from "../../../views/nodes/DocumentView";
+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 { faRulerCombined, faFillDrip, faPenNib } from "@fortawesome/free-solid-svg-icons";
+import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types";
+import e = require("express");
+import { ChangeEvent } from "mongodb";
+import { black } from "colors";
+
+
+library.add(faRulerCombined, faFillDrip, faPenNib);
+
+@observer
+export default class FormatShapePane extends AntimodeMenu {
+    static Instance: FormatShapePane;
+
+    private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF"];
+    private _width = ["1", "5", "10", "100"];
+    private _mode = ["fill-drip", "ruler-combined"];
+    private _subMenu = ["fill", "line", "size", "position"];
+    private _headIcon = ["⎯", "←"];
+    private _endIcon = ["⎯", "→"];
+    private _head = ["none", "arrowHead"];
+    private _end = ["none", "arrowEnd"];
+
+    @observable private _subOpen = [false, false, false, false];
+
+    @observable private collapsed: boolean = false;
+    @observable private currMode: string = "fill-drip";
+    @observable _fillBtn = false;
+    @observable _lineBtn = false;
+
+    @observable _selectDoc: DocumentView[] = [];
+
+    @observable _noFill = false;
+    @observable _solidFill = false;
+    @observable _noLine = false;
+    @observable _solidLine = false;
+    @observable _dashLine = false;
+    @observable _lock = false;
+
+    @observable _multiple = false;
+
+    @observable _widthBtn = false;
+
+    @observable _currWidth = "10";
+
+    @observable _single = false;
+    @observable _currFill = "#D0021B";
+    @observable _currColor = "#D0021B";
+
+    @observable _arrowHead = false;
+    @observable _arrowEnd = false;
+
+
+    @observable _currSizeHeight = "10";
+    @observable _currSizeWidth = "10";
+    @observable _currRotation = "10";
+
+    @observable _currPositionHorizontal = "10";
+    @observable _currPositionVertical = "10";
+
+
+    constructor(props: Readonly<{}>) {
+        super(props);
+        FormatShapePane.Instance = this;
+        this._canFade = false; // don't let the inking menu fade away
+        this.Pinned = BoolCast(Doc.UserDoc()["formatShapePane-pinned"]);
+
+    }
+
+    @action
+    toggleMenuPin = (e: React.MouseEvent) => {
+        Doc.UserDoc()["formatShapePane-pinned"] = this.Pinned = !this.Pinned;
+        if (!this.Pinned) {
+            // this.fadeOut(true);
+        }
+    }
+
+    @action
+    protected toggleCollapse = (e: React.MouseEvent) => {
+        this.collapsed = !this.collapsed;
+        setTimeout(() => {
+            const x = Math.min(this._left, window.innerWidth - FormatShapePane.Instance.width);
+            FormatShapePane.Instance.jumpTo(x, this._top, true);
+        }, 0);
+    }
+
+    @action
+    closePane = () => {
+        this.jumpTo(-300, -300);
+        this.Pinned = false;
+
+    }
+
+    @action
+    checkSame = () => {
+        const docs = SelectionManager.SelectedDocuments();
+        const inks: DocumentView[] = [];
+        for (var i = 0; i < docs.length; i++) {
+            if (Document(docs[i].rootDoc).type === DocumentType.INK) {
+                inks.push(docs[i]);
+            }
+        }
+        const firstWidth = Document(inks[0].rootDoc).strokeWidth;
+        const firstColor = Document(inks[0].rootDoc).color;
+        const firstFill = Document(inks[0].rootDoc).fillColor;
+        // const firstBezier
+        const firstRotation = Document(inks[0].rootDoc).rotation;
+        const firstArrowStart = Document(inks[0].rootDoc).arrowStart;
+        const firstArrowEnd = Document(inks[0].rootDoc).arrowEnd;
+        const firstDash = Document(inks[0].rootDoc).dash;
+        const firstWidthSize = Document(inks[0].rootDoc)._width;
+        const firstHeightSize = Document(inks[0].rootDoc)._height;
+        const firstHorizontal = Document(inks[0].rootDoc).x;
+        const firstVertical = Document(inks[0].rootDoc).y;
+        this._noFill = Document(inks[0].rootDoc).fillColor === "none" ? true : false;
+        this._solidFill = Document(inks[0].rootDoc).fillColor === "none" ? false : true;
+        this._noLine = Document(inks[0].rootDoc).color === "none" ? true : false;
+        if (Document(inks[0].rootDoc).color !== "none") {
+            this._solidLine = true;
+            this._dashLine = true;
+            if (Document(inks[0].rootDoc).dash === "0") {
+                this._dashLine = false;
+            } else {
+                this._solidLine = false;
+
+            }
+        }
+        // this._solidLine = (Document(inks[0].rootDoc).color === "none") ? false : Document(inks[0].rootDoc).dash === 0 ? true : false;
+        // this._dashLine = (Document(inks[0].rootDoc).color === "none") ? false : Document(inks[0].rootDoc).dash !== 0 ? true : false;
+        // // this._widthBtn = false;    
+        this._currWidth = String(Document(inks[0].rootDoc).strokeWidth);
+        // this._single = false;
+        this._currFill = String(Document(inks[0].rootDoc).fillColor);
+        this._currColor = String(Document(inks[0].rootDoc).color);
+        this._arrowHead = Document(inks[0].rootDoc).arrowStart === "none" ? false : true;
+        this._arrowEnd = Document(inks[0].rootDoc).arrowEnd === "none" ? false : true;
+        this._currSizeHeight = String(Document(inks[0].rootDoc)._height);
+        this._currSizeWidth = String(Document(inks[0].rootDoc)._width);
+        this._currRotation = String(Document(inks[0].rootDoc).rotation);
+        this._currPositionHorizontal = String(Document(inks[0].rootDoc).x);
+        this._currPositionVertical = String(Document(inks[0].rootDoc).y);
+        for (var i = 0; i < inks.length; i++) {
+            if (Document(inks[i].rootDoc).strokeWidth !== firstWidth) {
+                this._currWidth = "";
+            }
+            if (Document(inks[i].rootDoc).color !== firstColor) {
+                this._noLine = false;
+                this._solidLine = false;
+                this._dashLine = false;
+            }
+            if (Document(inks[i].rootDoc).fillColor !== firstFill) {
+                this._solidFill = false;
+                this._noFill = false;
+            }
+            if (Document(inks[i].rootDoc).arrowStart !== firstArrowStart) {
+                this._arrowHead = false;
+            }
+            if (Document(inks[i].rootDoc).arrowEnd !== firstArrowEnd) {
+                this._arrowEnd = false;
+            }
+            if (Document(inks[i].rootDoc).x !== firstHorizontal) {
+                this._currPositionHorizontal = "";
+            }
+            if (Document(inks[i].rootDoc).y !== firstVertical) {
+                this._currPositionVertical = "";
+            }
+            if (Document(inks[i].rootDoc)._width !== firstWidthSize) {
+                this._currSizeWidth = "";
+            }
+            if (Document(inks[i].rootDoc)._height !== firstHeightSize) {
+                this._currSizeHeight = "";
+            }
+            if (Document(inks[i].rootDoc).rotation !== firstRotation) {
+                this._currRotation = "";
+            }
+        }
+
+
+
+    }
+
+    @action
+    upDownButtons = (dirs: string, field: string) => {
+        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
+            const doc = Document(element.rootDoc);
+            if (doc.type === DocumentType.INK) {
+                switch (field) {
+                    case "width":
+                        if (doc.strokeWidth) {
+                            doc.strokeWidth = dirs === "up" ? doc.strokeWidth + 1 : doc.strokeWidth - 1;
+                            SetActiveInkWidth(String(doc.strokeWidth));
+
+                        }
+                        break;
+                    case "sizeWidth":
+                        if (doc._width && doc._height) {
+                            const oldWidth = doc._width;
+                            const oldHeight = doc._height;
+
+                            doc._width = dirs === "up" ? doc._width + 10 : doc._width - 10;
+                            if (this._lock) {
+                                doc._height = (doc._width * oldHeight) / oldWidth;
+                            }
+                        }
+                        break;
+                    case "sizeHeight":
+                        if (doc._width && doc._height) {
+                            const oldWidth = doc._width;
+                            const oldHeight = doc._height;
+                            doc._height = dirs === "up" ? doc._height + 10 : doc._height - 10;
+                            if (this._lock) {
+                                doc._width = (doc._height * oldWidth) / oldHeight;
+                            }
+                        }
+                        break;
+                    case "horizontal":
+                        if (doc.x) {
+                            doc.x = dirs === "up" ? doc.x + 10 : doc.x - 10;
+                        }
+                        break;
+                    case "vertical":
+                        if (doc.y) {
+                            doc.y = dirs === "up" ? doc.y + 10 : doc.y - 10;
+                        }
+                    case "rotation":
+
+                        this.rotate(dirs === "up" ? Number(doc.rotation) + Number(0.1) : Number(doc.rotation) - Number(0.1));
+
+                        break;
+                    default:
+                        break;
+                }
+                this.selected();
+
+            }
+        }));
+    }
+
+    @action
+    editProperties = (value: any, field: string) => {
+        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
+            const doc = Document(element.rootDoc);
+            if (doc.type === DocumentType.INK) {
+                switch (field) {
+                    case "width":
+                        SetActiveInkWidth(value);
+                        doc.strokeWidth = Number(value);
+                        break;
+                    case "color":
+                        doc.color = String(value);
+                        break;
+                    case "fill":
+                        doc.fillColor = String(value);
+                        break;
+                    case "bezier":
+                        // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300;
+                        break;
+                    case "arrowStart":
+                        doc.arrowStart = String(value);
+                        break;
+                    case "arrowEnd":
+                        doc.arrowEnd = String(value);
+                        break;
+                    case "dash":
+                        doc.dash = String(value);
+                        break;
+                    case "widthSize":
+                        if (doc._width && doc._height) {
+                            const oldWidth = doc._width;
+                            const oldHeight = doc._height;
+
+                            doc._width = Number(value);
+                            if (this._lock) {
+                                doc._height = (doc._width * oldHeight) / oldWidth;
+                            }
+                        }
+                        break;
+                    case "heightSize":
+                        if (doc._width && doc._height) {
+                            const oldWidth = doc._width;
+                            const oldHeight = doc._height;
+
+                            doc._height = Number(value);
+                            if (this._lock) {
+                                doc._width = (doc._height * oldWidth) / oldHeight;
+                            }
+                        }
+                        break;
+                    case "horizontal":
+                        doc.x = Number(value);
+                        break;
+                    case "vertical":
+                        doc.y = Number(value);
+
+                        break;
+                    default:
+                        break;
+                }
+            }
+            this.selected();
+        }));
+        this.checkSame();
+
+    }
+
+    @computed get close() {
+        const close = <button
+            className="antimodeMenu-button"
+            key="close"
+            onPointerDown={action(() => { this.closePane(); })}
+            style={{ right: 0, position: "absolute" }}>
+            X
+                </button>;
+        return close;
+    }
+
+    @computed get modes() {
+        const modes = <div className="antimodeMenu-button-tab">
+            {this._mode.map(mode => {
+                return <button
+                    className="antimodeMenu-button"
+                    key={mode}
+                    onPointerDown={action(() => { console.log("mode"); this.currMode = mode; })}
+                    style={{ backgroundColor: this.currMode === mode ? "121212" : "", position: "relative", top: 30 }}>
+                    <FontAwesomeIcon icon={mode as IconProp} size="lg" />
+                </button>;
+            })
+            }</div>;
+        return modes;
+    }
+
+    @action
+    selected = () => {
+        this._selectDoc = SelectionManager.SelectedDocuments();
+        if (this._selectDoc.length === 1 && Document(this._selectDoc[0].rootDoc).type === DocumentType.INK) {
+            this._single = true;
+            const doc = Document(this._selectDoc[0].rootDoc);
+            if (doc.type === DocumentType.INK) {
+                console.log(doc.fillColor);
+                if (doc.fillColor === "none") {
+                    this._noFill = true;
+                    this._solidFill = false;
+                } else {
+                    this._solidFill = true;
+                    this._noFill = false;
+                    this._currFill = String(doc.fillColor);
+                }
+                if (doc.color === "none") {
+                    this._noLine = true;
+                    this._solidLine = false;
+                    this._dashLine = false;
+                } else {
+                    console.log(doc.strokeWidth);
+                    this._currWidth = String(doc.strokeWidth);
+                    this._currColor = String(doc.color);
+                    if (doc.dash === "0") {
+                        this._solidLine = true;
+                        this._noLine = false;
+                        this._dashLine = false;
+                    } else {
+                        this._dashLine = true;
+                        this._noLine = false;
+                        this._solidLine = false;
+                    }
+
+                    this._arrowHead = doc.arrowStart === "none" ? false : true;
+                    this._arrowEnd = doc.arrowEnd === "none" ? false : true;
+
+
+                    this._currPositionHorizontal = String(doc.x);
+                    this._currPositionVertical = String(doc.y);
+                    console.log(doc.rotation);
+                    this._currRotation = String(doc.rotation);
+                    this._currSizeHeight = String(doc._height);
+                    this._currSizeWidth = String(doc._width);
+                }
+
+            }
+        } else {
+            this._noFill = false;
+            this._solidFill = false;
+            this._single = false;
+            this._currFill = "#D0021B";
+            this._noLine = false;
+            this._solidLine = false;
+            this._dashLine = false;
+            this._currColor = "#D0021B";
+            this._arrowHead = false;
+            this._arrowEnd = false;
+            this._currPositionHorizontal = "";
+            this._currPositionVertical = "";
+            this._currRotation = "";
+            this._currSizeHeight = "";
+            this._currSizeWidth = "";
+        }
+        this.checkSame();
+    }
+
+    @action
+    rotate = (degrees: number) => {
+        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
+            const doc = Document(element.rootDoc);
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                // doc.rotation = (Number(doc.rotation) + (Number(angle) * 180 / Math.PI));
+                // console.log(doc.rotation);
+                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);
+                    const ys = ink.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    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 });
+
+                    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;
+                        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) * element.props.ScreenToLocalTransform().Scale;
+                    doc._width = (right2 - left2) * element.props.ScreenToLocalTransform().Scale;
+
+                }
+            }
+        }));
+    }
+
+    @action
+    toggle = (check: string) => {
+        switch (check) {
+            case "noFill":
+                if (!this._noFill) {
+                    this._noFill = true;
+                    this._solidFill = false;
+                }
+                break;
+            case "solidFill":
+                if (!this._solidFill) {
+                    this._solidFill = true;
+                    this._noFill = false;
+                    if (this._currFill === "none") {
+                        this._currFill = "#D0021B";
+                    }
+                }
+                break;
+            case "noLine":
+                if (!this._noLine) {
+                    this._noLine = true;
+                    this._solidLine = false;
+                    this._dashLine = false;
+                }
+                break;
+            case "solidLine":
+                if (!this._solidLine) {
+                    this._solidLine = true;
+                    this._noLine = false;
+                    this._dashLine = false;
+                    if (this._currColor === "none") {
+                        this._currColor = "#D0021B";
+                    }
+                }
+                break;
+            case "dashLine":
+                if (!this._dashLine) {
+                    this._dashLine = true;
+                    this._solidLine = false;
+                    this._noLine = false;
+                    if (this._currColor === "none") {
+                        this._currColor = "#D0021B";
+                    }
+                }
+                break;
+            case "lock":
+                if (this._lock) {
+                    this._lock = false;
+                } else {
+                    this._lock = true;
+                }
+                break;
+            case "arrowHead":
+                this._arrowHead = this._arrowHead ? false : true;
+                break;
+            case "arrowEnd":
+                this._arrowEnd = this._arrowEnd ? false : true;
+                break;
+            default:
+                break;
+        }
+    }
+
+    @computed get subMenu() {
+        const fillCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
+            <input id="nofill" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._noFill} onChange={action(() => { this.toggle("noFill"); this.editProperties("none", "fill"); })} />
+            No Fill
+            <br></br>
+            <input id="solidfill" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._solidFill} onChange={action(() => { this.toggle("solidFill"); this.editProperties(this._currFill, "fill"); })} />
+            Solid Fill
+            <br></br>
+            <br></br>
+            {this._solidFill ? "Color" : ""}
+            {this._solidFill ? this.fillButton : ""}
+            {this._fillBtn && this._solidFill ? this.fillPicker : ""}
+
+        </div>;
+        const arrows = <> <input id="arrowHead" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._arrowHead} onChange={action(() => { this.toggle("arrowHead"); this.editProperties(this._arrowHead ? "arrowHead" : "none", "arrowStart"); })} />
+         Arrow Head
+            <br></br>
+
+            <input id="arrowEnd" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._arrowEnd} onChange={action(() => { this.toggle("arrowEnd"); this.editProperties(this._arrowEnd ? "arrowEnd" : "none", "arrowEnd"); })} />
+         Arrow End
+            <br></br></>;
+        const lineCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
+            <input id="noLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._noLine} onChange={action(() => { this.toggle("noLine"); this.editProperties("none", "color"); })} />
+                No Line
+                <br></br>
+            <input id="solidLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._solidLine} onChange={action(() => { this.toggle("solidLine"); this.editProperties(this._currColor, "color"); this.editProperties("0", "dash"); })} />
+                Solid Line
+                <br></br>
+            <input id="dashLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._dashLine} onChange={action(() => { this.toggle("dashLine"); this.editProperties(this._currColor, "color"); this.editProperties("2", "dash"); })} />
+                Dash Line
+                <br></br>
+            <br></br>
+            {(this._solidLine || this._dashLine) ? "Color" : ""}
+            {(this._solidLine || this._dashLine) ? this.lineButton : ""}
+            {this._lineBtn && (this._solidLine || this._dashLine) ? this.linePicker : ""}
+            <br></br>
+            {(this._solidLine || this._dashLine) ? "Width" : ""}
+            {(this._solidLine || this._dashLine) ? this.widthInput : ""}
+            <br></br>
+            <br></br>
+            {(this._solidLine || this._dashLine) ? arrows : ""}
+
+        </div>;
+
+        const sizeCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
+            Height {this.sizeHeightInput}
+            <br></br>
+            <br></br>
+
+
+            Width {this.sizeWidthInput}
+            <br></br>
+            <br></br>
+
+            <input id="lock" style={{ width: "inherit", position: "absolute", right: 0 }} type="checkbox" checked={this._lock} onChange={action(() => { this.toggle("lock"); })} />
+                Lock Ratio
+            <br></br>
+            <br></br>
+
+
+            Rotation {this.rotationInput}
+            <br></br>
+            <br></br>
+
+
+        </div>;
+        const positionCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
+            Horizontal {this.positionHorizontalInput}
+            <br></br>
+            <br></br>
+
+            Vertical {this.positionVerticalInput}
+            <br></br>
+            <br></br>
+
+
+        </div>;
+
+        const subMenu = <div className="antimodeMenu-sub" style={{ position: "absolute", width: "inherit", top: 60 }}>
+            {this._subMenu.map((subMenu, i) => {
+                if (subMenu === "fill" || subMenu === "line") {
+                    return <div style={{ width: "inherit" }}><button
+                        className="antimodeMenu-button"
+                        key={subMenu}
+                        onPointerDown={action(() => { this._subOpen[i] = this._subOpen[i] ? false : true; })}
+                        style={{ backgroundColor: "121212", display: this.currMode === "fill-drip" ? "" : "none", width: "inherit", textAlign: "left" }}>
+                        {this._subOpen[i] ? "▼" : "▶︎"}
+                        {subMenu}
+                    </button>
+                        {this.currMode === "fill-drip" && subMenu === "fill" && this._subOpen[0] ? fillCheck : ""}
+                        {this.currMode === "fill-drip" && subMenu === "line" && this._subOpen[1] ? lineCheck : ""}
+
+                    </div>;
+                }
+                else if (subMenu === "size" || subMenu === "position") {
+                    return <div style={{ width: "inherit" }}><button
+                        className="antimodeMenu-button"
+                        key={subMenu}
+                        onPointerDown={action(() => { this._subOpen[i] = this._subOpen[i] ? false : true; })}
+                        style={{ backgroundColor: "121212", display: this.currMode === "ruler-combined" ? "" : "none", width: "inherit", textAlign: "left" }}>
+                        {this._subOpen[i] ? "▼" : "▶︎"}
+                        {subMenu}
+                    </button>
+                        {this.currMode === "ruler-combined" && subMenu === "size" && this._subOpen[2] ? sizeCheck : ""}
+                        {this.currMode === "ruler-combined" && subMenu === "position" && this._subOpen[3] ? positionCheck : ""}
+
+                    </div>
+                        ;
+
+                }
+            })
+            }</div>;
+        return subMenu;
+    }
+
+    @computed get fillButton() {
+        const fillButton = <><button
+            className="antimodeMenu-button"
+            key="fill"
+            title="fillChanger"
+            onPointerDown={action(e => this._fillBtn = !this._fillBtn)}
+            style={{
+                // backgroundColor: "121212",
+                position: "absolute", right: 80
+            }}>
+            <FontAwesomeIcon icon="fill-drip" size="lg" />
+            <div className="color-previewI" style={{ backgroundColor: this._currFill ?? "121212" }}></div>
+        </button>
+            <br></br>
+            <br></br></>;
+        return fillButton;
+    }
+    @computed get fillPicker() {
+        const fillPicker = <div className="btn-group-palette" key="fill" >
+            {this._palette.map(color => {
+                return <button
+                    className="antimodeMenu-button"
+                    key={color}
+                    onPointerDown={action(() => { this._currFill = color; this.editProperties(color, "fill"); })}
+                    style={{
+                        // backgroundColor: this._fillBtn ? "121212" : "",
+                        zIndex: 1001
+                    }}>
+                    <div className="color-previewII" style={{ backgroundColor: color }}></div>
+                </button>;
+            })}
+
+        </div>;
+        return fillPicker;
+    }
+
+    @computed get lineButton() {
+        const lineButton = <><button
+            className="antimodeMenu-button"
+            key="line"
+            title="lineChanger"
+            onPointerDown={action(e => this._lineBtn = !this._lineBtn)}
+            style={{
+                // backgroundColor: "121212",
+                position: "absolute", right: 80
+            }}>
+            <FontAwesomeIcon icon="pen-nib" size="lg" />
+            <div className="color-previewI" style={{ backgroundColor: this._currColor ?? "121212" }}></div>
+        </button>
+            <br></br>
+            <br></br></>;
+        return lineButton;
+    }
+    @computed get linePicker() {
+        const linePicker = <div className="btn-group-palette" key="line" >
+            {this._palette.map(color => {
+                return <button
+                    className="antimodeMenu-button"
+                    key={color}
+                    onPointerDown={action(() => { this._currColor = color; this.editProperties(color, "color"); })}
+                    style={{
+                        // backgroundColor: this._lineBtn ? "121212" : "",
+                        zIndex: 1001
+                    }}>
+                    <div className="color-previewII" style={{ backgroundColor: color }}></div>
+                </button>;
+            })}
+
+        </div>;
+        return linePicker;
+    }
+    @computed get widthInput() {
+        const widthInput = <>
+            <input
+                style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+                type="text" value={this._currWidth}
+                onChange={e => this.onChange(e.target.value, "width")}
+                autoFocus></input>  <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("up", "width"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                ˄
+            </button>
+            <br />
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("down", "width"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                ˅
+            </button></>;
+        return widthInput;
+    }
+    @computed get sizeHeightInput() {
+        const sizeHeightInput = <>
+            <input
+                style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+                type="text" value={this._currSizeHeight}
+                onChange={e => this.onChange(e.target.value, "sizeHeight")}
+                autoFocus></input>
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("up", "sizeHeight"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                ˄
+            </button>
+            <br />
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("down", "sizeHeight"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                ˅
+            </button>
+        </>;
+        return sizeHeightInput;
+    }
+
+    @computed get sizeWidthInput() {
+        const sizeWidthInput = <>
+            <input
+                style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+                type="text" value={this._currSizeWidth}
+                onChange={e => this.onChange(e.target.value, "sizeWidth")}
+                autoFocus></input>
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("up", "sizeWidth"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                ˄
+            </button>
+            <br></br>
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("down", "sizeWidth"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                ˅
+            </button></>;
+        return sizeWidthInput;
+    }
+
+    @computed get rotationInput() {
+        const rotationInput =
+            <>
+                <input
+                    style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+                    type="text" value={this._currRotation}
+                    onChange={e => this.onChange(e.target.value, "rotation")}
+                    autoFocus></input>
+                <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("up", "rotation"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                    ˄
+            </button>
+                <br></br>
+                <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("down", "rotation"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                    ˅
+            </button></>;
+        return rotationInput;
+    }
+
+    @computed get positionHorizontalInput() {
+        const positionHorizontalInput =
+            <><input
+                style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+                type="text" value={this._currPositionHorizontal}
+                onChange={e => this.onChange(e.target.value, "positionHorizontal")}
+                autoFocus></input>
+                <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("up", "horizontal"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                    ˄
+            </button>
+                <br></br>
+                <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("down", "horizontal"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                    ˅
+            </button></>;
+        return positionHorizontalInput;
+    }
+
+    @computed get positionVerticalInput() {
+        const positionVerticalInput =
+            <><input
+                style={{ color: "black", width: 80, position: "absolute", right: 20 }}
+                type="text" value={this._currPositionVertical}
+                onChange={e => this.onChange(e.target.value, "positionVertical")}
+                autoFocus></input>
+                <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("down", "vertical"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                    ˄
+            </button>
+                <br></br>
+                <button
+                    className="antiMenu-Buttonup"
+                    key="up"
+                    onPointerDown={action(() => { this.upDownButtons("up", "vertical"); })}
+                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                    ˅
+            </button></>;
+        return positionVerticalInput;
+    }
+
+
+    @action
+    onChange = (val: string, property: string): void => {
+        if (!Number.isNaN(Number(val)) && Number(val) !== null && val !== " ") {
+
+            // if (val === "") {
+            //     val = "0";
+            // }
+            switch (property) {
+                case "width":
+                    this._currWidth = val;
+                    if (val !== "") {
+                        this.editProperties(this._currWidth, "width");
+                    }
+                    break;
+                case "sizeHeight":
+                    this._currSizeHeight = val;
+                    if (val !== "") {
+                        this.editProperties(this._currSizeHeight, "heightSize");
+                    }
+                    break;
+                case "sizeWidth":
+                    this._currSizeWidth = val;
+                    if (val !== "") {
+
+                        this.editProperties(this._currSizeWidth, "widthSize");
+                    }
+                    break;
+                case "rotation":
+
+                    this._currRotation = val;
+                    if (val !== "") {
+
+                        this.rotate(Number(val));
+                    }
+                    break;
+                case "positionHorizontal":
+                    this._currPositionHorizontal = val; if (val !== "") {
+
+                        this.editProperties(this._currPositionHorizontal, "horizontal");
+                    }
+
+                    break;
+                case "positionVertical":
+                    this._currPositionVertical = val;
+                    if (val !== "") {
+
+                        this.editProperties(this._currPositionVertical, "vertical");
+                    }
+
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+
+
+
+    // @action
+    // changeWidth = (event: React.ChangeEvent<HTMLInputElement>) => {
+    //     console.log(event.target.value);
+    //     this._currWidth = NumCast(event.target.value);
+
+    // }
+
+    @computed get upDown() {
+        const upDown = <div>
+            <button
+                className="antiMenu-Button"
+                key="up"
+                onPointerDown={action(() => { console.log("up"); })}>
+                up
+            </button>
+            <br></br>
+            <button
+                className="antiMenu-Button"
+                key="up"
+                onPointerDown={action(() => { console.log("dpwm"); })}>
+                down
+            </button>
+        </div>;
+        return upDown;
+    }
+
+
+    @computed get widthPicker() {
+        var widthPicker = <button
+            className="antimodeMenu-button"
+            key="width"
+            onPointerDown={action(e => this._widthBtn = !this._widthBtn)}
+            style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
+            <FontAwesomeIcon icon="bars" size="lg" />
+        </button>;
+        if (this._widthBtn) {
+            widthPicker = <div className="btn2-group" key="width">
+                {widthPicker}
+                {this._width.map(wid => {
+                    return <button
+                        className="antimodeMenu-button"
+                        key={wid}
+                        onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })}
+                        style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
+                        {wid}
+                    </button>;
+                })}
+            </div>;
+        }
+        return widthPicker;
+    }
+
+
+
+    render() {
+        const buttons = [
+
+            this.close,
+            this.modes,
+            this.subMenu
+
+        ];
+
+        return this.getElementVert(buttons);
+    }
+}
+Scripting.addGlobal(function activatePen2(penBtn: any) {
+    if (penBtn) {
+        //no longer changes to inkmode
+        // Doc.SetSelectedTool(InkTool.Pen);
+        FormatShapePane.Instance.jumpTo(300, 300);
+        FormatShapePane.Instance.Pinned = true;
+
+    } else {
+        // Doc.SetSelectedTool(InkTool.None);
+        FormatShapePane.Instance.Pinned = false;
+        FormatShapePane.Instance.fadeOut(true);
+
+    }
+});
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
index 7329f4fc1..f739fcc8c 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
@@ -32,7 +32,7 @@
 }
 
 .btn2-group {
-    display: block;
+    display: grid;
     background: #323232;
     grid-template-columns: auto;
 
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index 7de70b8cd..e4f3248d0 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -36,14 +36,15 @@ export default class InkOptionsMenu extends AntimodeMenu {
     // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"];
     // private _arrowIcons = ["→", "↔︎", "•", "••", " "];
     private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"];
-    private _head = ["none", "arrowHead", "arrowHead", "none", "arrowHead", "arrowHead", "none", "none", "none"];
-    private _end = ["none", "none", "arrowEnd", "none", "none", "arrowEnd", "none", "none", "none"];
+    private _head = ["none", "none", "arrowHead", "none", "none", "arrowHead", "none", "none", "none"];
+    private _end = ["none", "arrowEnd", "arrowEnd", "none", "arrowEnd", "arrowEnd", "none", "none", "none"];
     private _shape = ["", "", "", "", "", "", "rectangle", "circle", "triangle"];
 
     @observable _shapesNum = this._shape.length;
     @observable _selected = this._shapesNum;
 
     @observable private collapsed: boolean = false;
+    @observable _double = "";
 
     @observable _colorBtn = false;
     @observable _widthBtn = false;
@@ -155,7 +156,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
                     className="antimodeMenu-button"
                     key={icon}
                     onPointerDown={action(() => {
-                        console.log(this._selected);
+                        this._double = "";
 
                         if (this._selected !== i) {
                             this._selected = i;
@@ -177,6 +178,31 @@ export default class InkOptionsMenu extends AntimodeMenu {
                         }
                         console.log(this._selected);
 
+                    })}
+                    onDoubleClick={action(() => {
+                        console.log("double");
+                        this._double = this._draw[i];
+                        if (this._selected !== i) {
+                            this._selected = i;
+                            Doc.SetSelectedTool(InkTool.Pen);
+                            SetActiveArrowStart(this._head[i]);
+                            SetActiveArrowEnd(this._end[i]);
+                            SetActiveBezierApprox("300");
+
+                            //  this.editProperties(this._head[i], "arrowStart"), this.editProperties(this._end[i], "arrowEnd"); 
+                            GestureOverlay.Instance.InkShape = this._shape[i];
+                        } else {
+                            this._selected = this._shapesNum;
+                            Doc.SetSelectedTool(InkTool.None);
+                            SetActiveArrowStart("none");
+                            SetActiveArrowEnd("none");
+                            GestureOverlay.Instance.InkShape = "";
+                            SetActiveBezierApprox("0");
+
+                        }
+
+
+
                     })}
                     style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}>
                     {this._draw[i]}
@@ -235,7 +261,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
                         className="antimodeMenu-button"
                         key={wid}
                         onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })}
-                        style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
+                        style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001 }}>
                         {wid}
                     </button>;
                 })}
@@ -265,7 +291,7 @@ export default class InkOptionsMenu extends AntimodeMenu {
                         className="antimodeMenu-button"
                         key={color}
                         onPointerDown={action(() => { this.changeColor(color, "color"); this._colorBtn = false; this.editProperties(color, "color"); })}
-                        style={{ backgroundColor: this._colorBtn ? "121212" : "" }}>
+                        style={{ backgroundColor: this._colorBtn ? "121212" : "", zIndex: 1001 }}>
                         {/* <FontAwesomeIcon icon="pen-nib" size="lg" /> */}
                         <div className="color-previewII" style={{ backgroundColor: color }}></div>
                     </button>;
@@ -286,14 +312,14 @@ export default class InkOptionsMenu extends AntimodeMenu {
             <div className="color-previewI" style={{ backgroundColor: ActiveFillColor() ?? "121212" }}></div>
         </button>;
         if (this._fillBtn) {
-            fillPicker = <div className="btn-group" key="fill">
+            fillPicker = <div className="btn-group" key="fill" >
                 {fillPicker}
                 {this._palette.map(color => {
                     return <button
                         className="antimodeMenu-button"
                         key={color}
                         onPointerDown={action(() => { this.changeColor(color, "fill"); this._fillBtn = false; this.editProperties(color, "fill"); })}
-                        style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
+                        style={{ backgroundColor: this._fillBtn ? "121212" : "", zIndex: 1001 }}>
                         <div className="color-previewII" style={{ backgroundColor: color }}></div>
                     </button>;
                 })}
-- 
cgit v1.2.3-70-g09d2


From 6b5c11a26e114f26f3907342f9afbd47b27cecf4 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 11 Jul 2020 17:54:20 -0400
Subject: restructured ink to make more react-friendly

---
 src/client/util/CurrentUserUtils.ts                |   6 +-
 src/client/util/InteractionUtils.tsx               |  21 +-
 src/client/util/SelectionManager.ts                |   3 -
 src/client/views/AntimodeMenu.tsx                  |   1 -
 src/client/views/DocumentDecorations.tsx           |   5 +-
 src/client/views/InkingStroke.tsx                  |  18 +-
 .../collectionFreeForm/FormatShapePane.tsx         | 801 +++++++--------------
 .../collectionFreeForm/InkOptionsMenu.tsx          |  24 +-
 src/client/views/nodes/ColorBox.tsx                |   1 -
 9 files changed, 299 insertions(+), 581 deletions(-)

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index d0ca0e57e..0b644fa79 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -760,9 +760,9 @@ export class CurrentUserUtils {
         doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)");
         doc.activeInkWidth = StrCast(doc.activeInkWidth, "1");
         doc.activeInkBezier = StrCast(doc.activeInkBezier, "0");
-        doc.activeFillColor = StrCast(doc.activeFillColor, "none");
-        doc.activeArrowStart = StrCast(doc.activeArrowStart, "none");
-        doc.activeArrowEnd = StrCast(doc.activeArrowEnd, "none");
+        doc.activeFillColor = StrCast(doc.activeFillColor, "");
+        doc.activeArrowStart = StrCast(doc.activeArrowStart, "");
+        doc.activeArrowEnd = StrCast(doc.activeArrowEnd, "");
         doc.activeDash = StrCast(doc.activeDash, "0");
         doc.fontSize = NumCast(doc.fontSize, 12);
         doc["constants-snapThreshold"] = NumCast(doc["constants-snapThreshold"], 10); // 
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 2883e2056..6ab7bcc87 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -3,7 +3,6 @@ import * as beziercurve from 'bezier-curve';
 import * as fitCurve from 'fit-curve';
 import "./InteractionUtils.scss";
 import { Utils } from "../../Utils";
-import InkOptionsMenu from "../views/collections/collectionFreeForm/InkOptionsMenu";
 
 export namespace InteractionUtils {
     export const MOUSETYPE = "mouse";
@@ -96,12 +95,6 @@ export namespace InteractionUtils {
         color: string, width: number, strokeWidth: number, bezier: string, fill: string, arrowStart: string, arrowEnd: string,
         dash: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean, nodefs: boolean) {
 
-        // if (InkOptionsMenu.Instance.Pinned) {
-        //     for (var i = 0; i < points.length; i++) {
-        //         points[i].Y -= 35;
-        //     }
-        // }
-
         let pts: { X: number; Y: number; }[] = [];
         if (shape) { //if any of the shape are true
             pts = makePolygon(shape, points);
@@ -127,15 +120,15 @@ export namespace InteractionUtils {
         const dashArray = String(Number(width) * Number(dash));
         const defGuid = Utils.GenerateGuid();
         const arrowDim = Math.max(0.5, 8 / Math.log(Math.max(2, strokeWidth)));
-        return (<svg fill={fill === "none" ? color : fill}> {/* setting the svg fill sets the arrowhead fill */}
+        return (<svg fill={!fill || fill === "none" ? color : fill}> {/* setting the svg fill sets the arrowStart fill */}
             {nodefs ? (null) : <defs>
                 {arrowStart !== "dot" && arrowEnd !== "dot" ? (null) : <marker id={`dot${defGuid}`} orient="auto" overflow="visible">
                     <circle r={1} fill="context-stroke" />
                 </marker>}
-                {arrowStart !== "arrowHead" && arrowEnd !== "arrowHead" ? (null) : <marker id={`arrowHead${defGuid}`} orient="auto" overflow="visible" refX="1.6" refY="0" markerWidth="10" markerHeight="7">
+                {arrowStart !== "arrow" && arrowEnd !== "arrow" ? (null) : <marker id={`arrowStart${defGuid}`} orient="auto" overflow="visible" refX="1.6" refY="0" markerWidth="10" markerHeight="7">
                     <polygon points={`${arrowDim} ${-Math.max(1, arrowDim / 2)}, ${arrowDim} ${Math.max(1, arrowDim / 2)}, -1 0`} />
                 </marker>}
-                {arrowStart !== "arrowEnd" && arrowEnd !== "arrowEnd" ? (null) : <marker id={`arrowEnd${defGuid}`} orient="auto" overflow="visible" refX="1.6" refY="0" markerWidth="10" markerHeight="7">
+                {arrowStart !== "arrow" && arrowEnd !== "arrow" ? (null) : <marker id={`arrowEnd${defGuid}`} orient="auto" overflow="visible" refX="1.6" refY="0" markerWidth="10" markerHeight="7">
                     <polygon points={`${2 - arrowDim} ${-Math.max(1, arrowDim / 2)}, ${2 - arrowDim} ${Math.max(1, arrowDim / 2)}, 3 0`} />
                 </marker>}
             </defs>}
@@ -144,7 +137,7 @@ export namespace InteractionUtils {
                 points={strpts}
                 style={{
                     filter: drawHalo ? "url(#inkSelectionHalo)" : undefined,
-                    fill,
+                    fill: fill ? fill : "transparent",
                     opacity: strokeWidth !== width ? 0.5 : undefined,
                     pointerEvents: pevents as any,
                     stroke: color ?? "rgb(0, 0, 0)",
@@ -153,8 +146,8 @@ export namespace InteractionUtils {
                     strokeLinecap: "round",
                     strokeDasharray: dashArray
                 }}
-                markerStart={`url(#${arrowStart + defGuid})`}
-                markerEnd={`url(#${arrowEnd + defGuid})`}
+                markerStart={`url(#${arrowStart + "Start" + defGuid})`}
+                markerEnd={`url(#${arrowEnd + "End" + defGuid})`}
             />
 
         </svg>);
@@ -163,7 +156,7 @@ export namespace InteractionUtils {
     // export function makeArrow() {
     //     return (
     //         InkOptionsMenu.Instance.getColors().map(color => {
-    //             const id1 = "arrowHeadTest" + color;
+    //             const id1 = "arrowStartTest" + color;
     //             console.log(color);
     //             <marker id={id1} orient="auto" overflow="visible" refX="0" refY="1" markerWidth="10" markerHeight="7">
     //                 <polygon points="0 0, 3 1, 0 2" fill={"#" + color} />
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index af2f320d3..9a968aeda 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -5,7 +5,6 @@ import { computedFn } from "mobx-utils";
 import { List } from "../../fields/List";
 import { Scripting } from "./Scripting";
 import { DocumentManager } from "./DocumentManager";
-import FormatShapePane from "../views/collections/collectionFreeForm/FormatShapePane";
 
 export namespace SelectionManager {
 
@@ -31,8 +30,6 @@ export namespace SelectionManager {
                 manager.SelectedDocuments.set(docView, true);
             }
             Doc.UserDoc().activeSelection = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
-            FormatShapePane.Instance.selected();
-
         }
         @action
         DeselectDoc(docView: DocumentView): void {
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index cb6de1785..3303a5e68 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -1,7 +1,6 @@
 import React = require("react");
 import { observable, action } from "mobx";
 import "./AntimodeMenu.scss";
-import { inherits } from "util";
 
 /**
  * This is an abstract class that serves as the base for a PDF-style or Marquee-style
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 8edd4c4a9..81b4f9162 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -152,8 +152,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         if (e.button === 0 && !e.altKey && !e.ctrlKey) {
             let child = SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0];
             while (child.children.length) {
-                const next = Array.from(child.children).find(c => !c.className.includes("collectionViewChrome"));
-                if (next?.className.includes("documentView-node")) break;
+                const next = Array.from(child.children).find(c => typeof (c.className) !== "string" || !c.className.includes("collectionViewChrome"));
+                if (typeof (next?.className) === "string" && next?.className.includes("documentView-node")) break;
                 if (next) child = next;
                 else break;
             }
@@ -294,7 +294,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             const doc = Document(element.rootDoc);
             if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
                 doc.rotation = Number(doc.rotation) + Number(angle);
-                console.log(doc.rotation);
                 const ink = Cast(doc.data, InkField)?.inkData;
                 if (ink) {
 
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 7d9a3c8b3..224abfd77 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -43,8 +43,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
     @action
     private formatShape = () => {
         FormatShapePane.Instance.Pinned = true;
-        FormatShapePane.Instance.selected();
-
     }
 
     render() {
@@ -62,14 +60,14 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         const height = bottom - top;
         const scaleX = (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth);
         const scaleY = (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth);
-        const strokeColor = StrCast(this.layoutDoc.color, ActiveInkColor());
+        const strokeColor = StrCast(this.layoutDoc.color, "");
         const points = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
-            StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), StrCast(this.layoutDoc.fillColor, ActiveFillColor()),
-            StrCast(this.layoutDoc.arrowStart, ActiveArrowStart()), StrCast(this.layoutDoc.arrowEnd, ActiveArrowEnd()),
-            StrCast(this.layoutDoc.dash, ActiveDash()), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false);
+            StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
+            StrCast(this.layoutDoc.arrowStart), StrCast(this.layoutDoc.arrowEnd),
+            StrCast(this.layoutDoc.dash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false);
         const hpoints = InteractionUtils.CreatePolyline(data, left, top,
             this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
-            StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), StrCast(this.layoutDoc.fillColor, ActiveFillColor()),
+            StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
             "none", "none", "0", scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
         return (
             <svg className="inkingStroke"
@@ -106,9 +104,9 @@ export function SetActiveArrowEnd(value: string) { ActiveInkPen() && (ActiveInkP
 export function SetActiveDash(dash: string): void { !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash); }
 export function ActiveInkPen(): Doc { return Cast(Doc.UserDoc().activeInkPen, Doc, null); }
 export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, "black"); }
-export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, "none"); }
-export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, "none"); }
-export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, "none"); }
+export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ""); }
+export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ""); }
+export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ""); }
 export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, "0"); }
 export function ActiveInkWidth(): string { return StrCast(ActiveInkPen()?.activeInkWidth, "1"); }
 export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); }
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index bf2218fdc..321b5648e 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -3,10 +3,9 @@ import AntimodeMenu from "../../AntimodeMenu";
 import { observer } from "mobx-react";
 import { observable, action, computed } from "mobx";
 import "./FormatShapePane.scss";
-import { SetActiveInkWidth } from "../../InkingStroke";
 import { Scripting } from "../../../util/Scripting";
 import { InkField } from "../../../../fields/InkField";
-import { Doc } from "../../../../fields/Doc";
+import { Doc, Opt } from "../../../../fields/Doc";
 import { SelectionManager } from "../../../util/SelectionManager";
 import { DocumentView } from "../../../views/nodes/DocumentView";
 import { Document } from "../../../../fields/documentSchemas";
@@ -15,7 +14,6 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
 import { faRulerCombined, faFillDrip, faPenNib } from "@fortawesome/free-solid-svg-icons";
 import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types";
-import e = require("express");
 
 library.add(faRulerCombined, faFillDrip, faPenNib);
 
@@ -27,31 +25,131 @@ export default class FormatShapePane extends AntimodeMenu {
     private _width = ["1", "5", "10", "100"];
     private _mode = ["fill-drip", "ruler-combined"];
     private _subMenu = ["fill", "line", "size", "position"];
+    @computed get inks() {
+        const inks: DocumentView[] = [];
+        const docs = SelectionManager.SelectedDocuments();
+        for (var i = 0; i < docs.length; i++) {
+            if (Document(docs[i].rootDoc).type === DocumentType.INK) {
+                inks.push(docs[i]);
+            }
+        }
+        return inks.length ? inks : undefined;
+    }
     @observable private _subOpen = [false, false, false, false];
     @observable private collapsed: boolean = false;
     @observable private currMode: string = "fill-drip";
+    @observable _lock = false;
     @observable _fillBtn = false;
     @observable _lineBtn = false;
-    @observable _selectDoc: DocumentView[] = [];
-    @observable _noFill = false;
-    @observable _solidFill = false;
-    @observable _noLine = false;
-    @observable _solidLine = false;
-    @observable _dashLine = false;
-    @observable _lock = false;
-    @observable _multiple = false;
-    @observable _widthBtn = false;
-    @observable _single = false;
-    @observable _arrowHead = false;
-    @observable _arrowEnd = false;
-    @observable _currSizeHeight = "10";
-    @observable _currSizeWidth = "10";
-    @observable _currRotation = "10";
-    @observable _currPositionHorizontal = "10";
-    @observable _currPositionVertical = "10";
-    @observable _currWidth = "10";
-    @observable _currFill = "#D0021B";
-    @observable _currColor = "#D0021B";
+    _lastFill = "#D0021B";
+    _lastLine = "#D0021B";
+    _lastDash = "2";
+
+    @computed get _noFill() {
+        return this.inks?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false;
+    }
+    @computed get _solidFill() {
+        return this.inks?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false;
+    }
+    set _noFill(value) { this._currFill = value ? "" : this._lastFill; }
+    set _solidFill(value) { this._noFill = !value; }
+
+    @computed get _noLine() {
+        return this.inks?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false;
+    }
+    @computed get _solidLine() {
+        return this.inks?.reduce((p, i) => p &&
+            i.rootDoc.color && (i.rootDoc.dash === undefined || i.rootDoc.dash === "0") ? true : false, true) || false;
+    }
+    @computed get _dashLine() {
+        return !this._noLine && this.inks?.reduce((p, i) =>
+            (p === undefined || (p && p === i.rootDoc.dash)) && i.rootDoc.dash !== "0" ? StrCast(i.rootDoc.dash) : "", undefined as Opt<string>) || "";
+    }
+    set _noLine(value) { this._currColor = value ? "" : this._lastLine; }
+    set _solidLine(value) { this._dashLine = ""; this._noLine = !value; }
+    set _dashLine(value) {
+        value && (this._lastDash = value); this._noLine = false;
+        this.inks?.forEach(i => i.rootDoc.dash = value ? this._lastDash : undefined)
+    }
+
+    @computed get _currFill() {
+        const cfill = this._noFill || !this.inks ? "" : StrCast(this.inks[0].rootDoc.fillColor);
+        cfill && (this._lastFill = cfill);
+        return cfill;
+    }
+    @computed get _currColor() {
+        const ccol = this._noLine || !this.inks ? "" : StrCast(this.inks[0].rootDoc.color, "");
+        this._lastLine = ccol ? ccol : this._lastLine;
+        return ccol;
+    }
+    set _currFill(value) { value && (this._lastFill = value); this.inks?.forEach(i => i.rootDoc.fillColor = value); }
+    set _currColor(value) { value && (this._lastLine = value); this.inks?.forEach(i => i.rootDoc.color = value ? value : undefined) }
+
+    @computed get _arrowStart() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p && p === i.rootDoc.arrowStart)) ? StrCast(i.rootDoc.arrowStart) : "", undefined as Opt<string>) || "";
+    }
+    @computed get _arrowEnd() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p && p === i.rootDoc.arrowEnd)) ? StrCast(i.rootDoc.arrowEnd) : "", undefined as Opt<string>) || ""
+    }
+    set _arrowStart(value) { this.inks?.forEach(i => i.rootDoc.arrowStart = value); }
+    set _arrowEnd(value) { this.inks?.forEach(i => i.rootDoc.arrowEnd = value); }
+
+    @computed get _currSizeHeight() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p === NumCast(i.rootDoc._height).toString())) ? NumCast(i.rootDoc._height).toString() : "", undefined as Opt<string>) || ""
+    }
+    @computed get _currSizeWidth() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p === NumCast(i.rootDoc._width).toString())) ? NumCast(i.rootDoc._width).toString() : "", undefined as Opt<string>) || ""
+    }
+    @computed get _currRotation() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p === NumCast(i.rootDoc.rotation).toString())) ? NumCast(i.rootDoc.rotation).toString() : "", undefined as Opt<string>) || ""
+    }
+    @computed get _currPositionHorizontal() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p === NumCast(i.rootDoc.x).toString())) ? NumCast(i.rootDoc.x).toString() : "", undefined as Opt<string>) || ""
+    }
+    @computed get _currPositionVertical() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p === NumCast(i.rootDoc.y).toString())) ? NumCast(i.rootDoc.y).toString() : "", undefined as Opt<string>) || ""
+    }
+    @computed get _currStrokeWidth() {
+        return this.inks?.reduce((p, i) =>
+            (p === undefined || (p === NumCast(i.rootDoc.strokeWidth).toString())) ? NumCast(i.rootDoc.strokeWidth).toString() : "", undefined as Opt<string>) || ""
+    }
+    set _currPositionHorizontal(value) { this.inks?.forEach(i => i.rootDoc.x = Number(value)); }
+    set _currPositionVertical(value) { this.inks?.forEach(i => i.rootDoc.y = Number(value)); }
+    set _currRotation(value) { this.inks?.forEach(i => i.rootDoc.rotation = Number(value)); }
+    set _currStrokeWidth(value) { this.inks?.forEach(i => i.rootDoc.strokeWidth = Number(value)); }
+    set _currSizeWidth(value) {
+        this.inks?.forEach(i => {
+            const doc = i.rootDoc;
+            if (doc._width && doc._height) {
+                const oldWidth = NumCast(doc._width);
+                const oldHeight = NumCast(doc._height);
+                doc._width = Number(value);
+                if (this._lock) {
+                    doc._height = (doc._width * oldHeight) / oldWidth;
+                }
+            }
+        });
+    }
+    set _currSizeHeight(value) {
+        this.inks?.forEach(i => {
+            const doc = i.rootDoc;
+            if (doc._width && doc._height) {
+                const oldWidth = NumCast(doc._width);
+                const oldHeight = NumCast(doc._height);
+                doc._height = Number(value);
+                if (this._lock) {
+                    doc._width = (doc._height * oldWidth) / oldHeight;
+                }
+            }
+        });
+    }
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -80,191 +178,40 @@ export default class FormatShapePane extends AntimodeMenu {
         this.Pinned = false;
     }
 
-    //if multiple inks are selected and do not share the same prop, leave blank
-    @action
-    checkSame = () => {
-        const docs = SelectionManager.SelectedDocuments();
-        const inks: DocumentView[] = [];
-        for (var i = 0; i < docs.length; i++) {
-            if (Document(docs[i].rootDoc).type === DocumentType.INK) {
-                inks.push(docs[i]);
-            }
-        }
-        this._noFill = Document(inks[0].rootDoc).fillColor === "none" ? true : false;
-        this._solidFill = Document(inks[0].rootDoc).fillColor === "none" ? false : true;
-        this._noLine = Document(inks[0].rootDoc).color === "none" ? true : false;
-        if (Document(inks[0].rootDoc).color !== "none") {
-            this._solidLine = true;
-            this._dashLine = true;
-            if (Document(inks[0].rootDoc).dash === "0") {
-                this._dashLine = false;
-            } else {
-                this._solidLine = false;
-
-            }
-        }
-        this._currWidth = String(Document(inks[0].rootDoc).strokeWidth);
-        this._currFill = String(Document(inks[0].rootDoc).fillColor);
-        this._currColor = String(Document(inks[0].rootDoc).color);
-        this._arrowHead = Document(inks[0].rootDoc).arrowStart === "none" ? false : true;
-        this._arrowEnd = Document(inks[0].rootDoc).arrowEnd === "none" ? false : true;
-        this._currSizeHeight = String(Document(inks[0].rootDoc)._height);
-        this._currSizeWidth = String(Document(inks[0].rootDoc)._width);
-        this._currRotation = String(Document(inks[0].rootDoc).rotation);
-        this._currPositionHorizontal = String(Document(inks[0].rootDoc).x);
-        this._currPositionVertical = String(Document(inks[0].rootDoc).y);
-        for (var i = 0; i < inks.length; i++) {
-            if (Document(inks[i].rootDoc).strokeWidth !== Document(inks[0].rootDoc).strokeWidth) {
-                this._currWidth = "";
-            }
-            if (Document(inks[i].rootDoc).color !== Document(inks[0].rootDoc).color) {
-                this._noLine = false;
-                this._solidLine = false;
-                this._dashLine = false;
-            }
-            if (Document(inks[i].rootDoc).fillColor !== Document(inks[0].rootDoc).fillColor) {
-                this._solidFill = false;
-                this._noFill = false;
-            }
-            if (Document(inks[i].rootDoc).arrowStart !== Document(inks[0].rootDoc).arrowStart) {
-                this._arrowHead = false;
-            }
-            if (Document(inks[i].rootDoc).arrowEnd !== Document(inks[0].rootDoc).arrowEnd) {
-                this._arrowEnd = false;
-            }
-            if (Document(inks[i].rootDoc).x !== Document(inks[0].rootDoc).x) {
-                this._currPositionHorizontal = "";
-            }
-            if (Document(inks[i].rootDoc).y !== Document(inks[0].rootDoc).y) {
-                this._currPositionVertical = "";
-            }
-            if (Document(inks[i].rootDoc)._width !== Document(inks[0].rootDoc)._width) {
-                this._currSizeWidth = "";
-            }
-            if (Document(inks[i].rootDoc)._height !== Document(inks[0].rootDoc)._height) {
-                this._currSizeHeight = "";
-            }
-            if (Document(inks[i].rootDoc).rotation !== Document(inks[0].rootDoc).rotation) {
-                this._currRotation = "";
-            }
-        }
-    }
-
-
     @action
     upDownButtons = (dirs: string, field: string) => {
-        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
-            const doc = Document(element.rootDoc);
-            if (doc.type === DocumentType.INK) {
-                switch (field) {
-                    case "width":
-                        if (doc.strokeWidth) {
-                            doc.strokeWidth = dirs === "up" ? doc.strokeWidth + 1 : doc.strokeWidth - 1;
-                            SetActiveInkWidth(String(doc.strokeWidth));
+        switch (field) {
+            case "horizontal": this.inks?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break;
+            case "vertical": this.inks?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break;
+            case "rotation": this.rotate((dirs === "up" ? .1 : -.1)); break;
+            case "width": this.inks?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
+            case "sizeWidth":
+                this.inks?.forEach(i => {
+                    const doc = i.rootDoc;
+                    if (doc._width && doc._height) {
+                        const oldWidth = NumCast(doc._width);
+                        const oldHeight = NumCast(doc._height);
+                        doc._width = NumCast(doc._width) + (dirs === "up" ? 10 : - 10);
+                        if (this._lock) {
+                            doc._height = (NumCast(doc._width) * oldHeight) / oldWidth;
                         }
-                        break;
-                    case "sizeWidth":
-                        if (doc._width && doc._height) {
-                            const oldWidth = doc._width;
-                            const oldHeight = doc._height;
-                            doc._width = dirs === "up" ? doc._width + 10 : doc._width - 10;
-                            if (this._lock) {
-                                doc._height = (doc._width * oldHeight) / oldWidth;
-                            }
-                        }
-                        break;
-                    case "sizeHeight":
-                        if (doc._width && doc._height) {
-                            const oldWidth = doc._width;
-                            const oldHeight = doc._height;
-                            doc._height = dirs === "up" ? doc._height + 10 : doc._height - 10;
-                            if (this._lock) {
-                                doc._width = (doc._height * oldWidth) / oldHeight;
-                            }
-                        }
-                        break;
-                    case "horizontal":
-                        if (doc.x) {
-                            doc.x = dirs === "up" ? doc.x + 10 : doc.x - 10;
-                        }
-                        break;
-                    case "vertical":
-                        if (doc.y) {
-                            doc.y = dirs === "up" ? doc.y + 10 : doc.y - 10;
-                        }
-                    case "rotation":
-                        this.rotate(dirs === "up" ? Number(doc.rotation) + Number(0.1) : Number(doc.rotation) - Number(0.1));
-                        break;
-                    default:
-                        break;
-                }
-                this.selected();
-            }
-        }));
-    }
-
-
-    @action
-    editProperties = (value: any, field: string) => {
-        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
-            const doc = Document(element.rootDoc);
-            if (doc.type === DocumentType.INK) {
-                switch (field) {
-                    case "width":
-                        SetActiveInkWidth(value);
-                        doc.strokeWidth = Number(value);
-                        break;
-                    case "color":
-                        doc.color = String(value);
-                        break;
-                    case "fill":
-                        doc.fillColor = String(value);
-                        break;
-                    case "bezier":
-                        break;
-                    case "arrowStart":
-                        doc.arrowStart = String(value);
-                        break;
-                    case "arrowEnd":
-                        doc.arrowEnd = String(value);
-                        break;
-                    case "dash":
-                        doc.dash = String(value);
-                        break;
-                    case "widthSize":
-                        if (doc._width && doc._height) {
-                            const oldWidth = doc._width;
-                            const oldHeight = doc._height;
-                            doc._width = Number(value);
-                            if (this._lock) {
-                                doc._height = (doc._width * oldHeight) / oldWidth;
-                            }
-                        }
-                        break;
-                    case "heightSize":
-                        if (doc._width && doc._height) {
-                            const oldWidth = doc._width;
-                            const oldHeight = doc._height;
-                            doc._height = Number(value);
-                            if (this._lock) {
-                                doc._width = (doc._height * oldWidth) / oldHeight;
-                            }
+                    }
+                });
+                break;
+            case "sizeHeight":
+                this.inks?.forEach(i => {
+                    const doc = i.rootDoc;
+                    if (doc._width && doc._height) {
+                        const oldWidth = NumCast(doc._width);
+                        const oldHeight = NumCast(doc._height)
+                        doc._height = NumCast(doc._height) + (dirs === "up" ? 10 : - 10);
+                        if (this._lock) {
+                            doc._width = (NumCast(doc._height) * oldWidth) / oldHeight;
                         }
-                        break;
-                    case "horizontal":
-                        doc.x = Number(value);
-                        break;
-                    case "vertical":
-                        doc.y = Number(value);
-                        break;
-                    default:
-                        break;
-                }
-            }
-            this.selected();
-        }));
-        this.checkSame();
-
+                    }
+                });
+                break;
+        }
     }
 
     @computed get close() {
@@ -294,69 +241,6 @@ export default class FormatShapePane extends AntimodeMenu {
         return modes;
     }
 
-    //detects currently selected document and change value in pane
-    @action
-    selected = () => {
-        this._selectDoc = SelectionManager.SelectedDocuments();
-        if (this._selectDoc.length === 1 && Document(this._selectDoc[0].rootDoc).type === DocumentType.INK) {
-            this._single = true;
-            const doc = Document(this._selectDoc[0].rootDoc);
-            if (doc.type === DocumentType.INK) {
-                if (doc.fillColor === "none") {
-                    this._noFill = true;
-                    this._solidFill = false;
-                } else {
-                    this._solidFill = true;
-                    this._noFill = false;
-                    this._currFill = String(doc.fillColor);
-                }
-                if (doc.color === "none") {
-                    this._noLine = true;
-                    this._solidLine = false;
-                    this._dashLine = false;
-                } else {
-                    this._currWidth = String(doc.strokeWidth);
-                    this._currColor = String(doc.color);
-                    if (doc.dash === "0") {
-                        this._solidLine = true;
-                        this._noLine = false;
-                        this._dashLine = false;
-                    } else {
-                        this._dashLine = true;
-                        this._noLine = false;
-                        this._solidLine = false;
-                    }
-
-                    this._arrowHead = doc.arrowStart === "none" ? false : true;
-                    this._arrowEnd = doc.arrowEnd === "none" ? false : true;
-                    this._currPositionHorizontal = String(doc.x);
-                    this._currPositionVertical = String(doc.y);
-                    this._currRotation = String(doc.rotation);
-                    this._currSizeHeight = String(doc._height);
-                    this._currSizeWidth = String(doc._width);
-                }
-
-            }
-        } else {
-            this._noFill = false;
-            this._solidFill = false;
-            this._single = false;
-            this._currFill = "#D0021B";
-            this._noLine = false;
-            this._solidLine = false;
-            this._dashLine = false;
-            this._currColor = "#D0021B";
-            this._arrowHead = false;
-            this._arrowEnd = false;
-            this._currPositionHorizontal = "";
-            this._currPositionVertical = "";
-            this._currRotation = "";
-            this._currSizeHeight = "";
-            this._currSizeWidth = "";
-        }
-        this.checkSame();
-    }
-
     @action
     rotate = (degrees: number) => {
         SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
@@ -395,143 +279,80 @@ export default class FormatShapePane extends AntimodeMenu {
         }));
     }
 
-    @action
-    toggle = (check: string) => {
-        switch (check) {
-            case "noFill":
-                if (!this._noFill) {
-                    this._noFill = true;
-                    this._solidFill = false;
-                }
-                break;
-            case "solidFill":
-                if (!this._solidFill) {
-                    this._solidFill = true;
-                    this._noFill = false;
-                    if (this._currFill === "none") {
-                        this._currFill = "#D0021B";
-                    }
-                }
-                break;
-            case "noLine":
-                if (!this._noLine) {
-                    this._noLine = true;
-                    this._solidLine = false;
-                    this._dashLine = false;
-                }
-                break;
-            case "solidLine":
-                if (!this._solidLine) {
-                    this._solidLine = true;
-                    this._noLine = false;
-                    this._dashLine = false;
-                    if (this._currColor === "none") {
-                        this._currColor = "#D0021B";
-                    }
-                }
-                break;
-            case "dashLine":
-                if (!this._dashLine) {
-                    this._dashLine = true;
-                    this._solidLine = false;
-                    this._noLine = false;
-                    if (this._currColor === "none") {
-                        this._currColor = "#D0021B";
-                    }
-                }
-                break;
-            case "lock":
-                if (this._lock) {
-                    this._lock = false;
-                } else {
-                    this._lock = true;
-                }
-                break;
-            case "arrowHead":
-                this._arrowHead = this._arrowHead ? false : true;
-                break;
-            case "arrowEnd":
-                this._arrowEnd = this._arrowEnd ? false : true;
-                break;
-            default:
-                break;
-        }
-    }
-
     @computed get subMenu() {
         const fillCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            <input id="nofill" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._noFill} onChange={action(() => { this.toggle("noFill"); this.editProperties("none", "fill"); })} />
+            <input id="nofill" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._noFill} onChange={action(() => this._noFill = true)} />
             No Fill
-            <br></br>
-            <input id="solidfill" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._solidFill} onChange={action(() => { this.toggle("solidFill"); this.editProperties(this._currFill, "fill"); })} />
+            <br />
+            <input id="solidfill" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._solidFill} onChange={action(() => this._solidFill = true)} />
             Solid Fill
-            <br></br>
-            <br></br>
+            <br />
+            <br />
             {this._solidFill ? "Color" : ""}
             {this._solidFill ? this.fillButton : ""}
             {this._fillBtn && this._solidFill ? this.fillPicker : ""}
 
         </div>;
-        const arrows = <> <input id="arrowHead" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._arrowHead} onChange={action(() => { this.toggle("arrowHead"); this.editProperties(this._arrowHead ? "arrowHead" : "none", "arrowStart"); })} />
+        const arrows = <> <input id="arrowStart" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._arrowStart !== ""} onChange={action(() => this._arrowStart = this._arrowStart ? "" : "arrow")} />
          Arrow Head
-            <br></br>
+            <br />
 
-            <input id="arrowEnd" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._arrowEnd} onChange={action(() => { this.toggle("arrowEnd"); this.editProperties(this._arrowEnd ? "arrowEnd" : "none", "arrowEnd"); })} />
+            <input id="arrowEnd" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._arrowEnd !== ""} onChange={action(() => this._arrowEnd = this._arrowEnd ? "" : "arrow")} />
          Arrow End
-            <br></br></>;
+            <br /></>;
         const lineCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            <input id="noLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._noLine} onChange={action(() => { this.toggle("noLine"); this.editProperties("none", "color"); })} />
+            <input id="noLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._noLine} onChange={action(() => this._noLine = true)} />
                 No Line
-                <br></br>
-            <input id="solidLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._solidLine} onChange={action(() => { this.toggle("solidLine"); this.editProperties(this._currColor, "color"); this.editProperties("0", "dash"); })} />
+            <br />
+            <input id="solidLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._solidLine} onChange={action(() => this._solidLine = true)} />
                 Solid Line
-                <br></br>
-            <input id="dashLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._dashLine} onChange={action(() => { this.toggle("dashLine"); this.editProperties(this._currColor, "color"); this.editProperties("2", "dash"); })} />
+            <br />
+            <input id="dashLine" style={{ width: "inherit", position: "absolute" }} type="checkbox" checked={this._dashLine ? true : false} onChange={action(() => this._dashLine = "2")} />
                 Dash Line
-                <br></br>
-            <br></br>
+            <br />
+            <br />
             {(this._solidLine || this._dashLine) ? "Color" : ""}
             {(this._solidLine || this._dashLine) ? this.lineButton : ""}
             {this._lineBtn && (this._solidLine || this._dashLine) ? this.linePicker : ""}
-            <br></br>
+            <br />
             {(this._solidLine || this._dashLine) ? "Width" : ""}
             {(this._solidLine || this._dashLine) ? this.widthInput : ""}
-            <br></br>
-            <br></br>
+            <br />
+            <br />
             {(this._solidLine || this._dashLine) ? arrows : ""}
 
         </div>;
 
         const sizeCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
             Height {this.sizeHeightInput}
-            <br></br>
-            <br></br>
+            <br />
+            <br />
 
 
             Width {this.sizeWidthInput}
-            <br></br>
-            <br></br>
+            <br />
+            <br />
 
-            <input id="lock" style={{ width: "inherit", position: "absolute", right: 0 }} type="checkbox" checked={this._lock} onChange={action(() => { this.toggle("lock"); })} />
+            <input id="lock" style={{ width: "inherit", position: "absolute", right: 0 }} type="checkbox" checked={this._lock} onChange={action(() => this._lock = !this._lock)} />
                 Lock Ratio
-            <br></br>
-            <br></br>
+            <br />
+            <br />
 
 
             Rotation {this.rotationInput}
-            <br></br>
-            <br></br>
+            <br />
+            <br />
 
 
         </div>;
         const positionCheck = <div style={{ width: "inherit", backgroundColor: "#323232", color: "white", }}>
             Horizontal {this.positionHorizontalInput}
-            <br></br>
-            <br></br>
+            <br />
+            <br />
 
             Vertical {this.positionVerticalInput}
-            <br></br>
-            <br></br>
+            <br />
+            <br />
 
 
         </div>;
@@ -574,29 +395,30 @@ export default class FormatShapePane extends AntimodeMenu {
     }
 
     @computed get fillButton() {
-        const fillButton = <><button
-            className="antimodeMenu-button"
-            key="fill"
-            title="fillChanger"
-            onPointerDown={action(e => this._fillBtn = !this._fillBtn)}
-            style={{
-                // backgroundColor: "121212",
-                position: "absolute", right: 80
-            }}>
-            <FontAwesomeIcon icon="fill-drip" size="lg" />
-            <div className="color-previewI" style={{ backgroundColor: this._currFill ?? "121212" }}></div>
-        </button>
+        return <>
+            <button
+                className="antimodeMenu-button"
+                key="fill"
+                title="fillChanger"
+                onPointerDown={action(e => this._fillBtn = !this._fillBtn)}
+                style={{
+                    // backgroundColor: "121212",
+                    position: "absolute", right: 80
+                }}>
+                <FontAwesomeIcon icon="fill-drip" size="lg" />
+                <div className="color-previewI" style={{ backgroundColor: this._currFill ?? "121212" }}></div>
+            </button>
             <br></br>
-            <br></br></>;
-        return fillButton;
+            <br></br>
+        </>;
     }
     @computed get fillPicker() {
-        const fillPicker = <div className="btn-group-palette" key="fill" >
+        return <div className="btn-group-palette" key="fill" >
             {this._palette.map(color => {
                 return <button
                     className="antimodeMenu-button"
                     key={color}
-                    onPointerDown={action(() => { this._currFill = color; this.editProperties(color, "fill"); })}
+                    onPointerDown={action(() => this._currFill = color)}
                     style={{
                         // backgroundColor: this._fillBtn ? "121212" : "",
                         zIndex: 1001
@@ -606,33 +428,33 @@ export default class FormatShapePane extends AntimodeMenu {
             })}
 
         </div>;
-        return fillPicker;
     }
 
     @computed get lineButton() {
-        const lineButton = <><button
-            className="antimodeMenu-button"
-            key="line"
-            title="lineChanger"
-            onPointerDown={action(e => this._lineBtn = !this._lineBtn)}
-            style={{
-                // backgroundColor: "121212",
-                position: "absolute", right: 80
-            }}>
-            <FontAwesomeIcon icon="pen-nib" size="lg" />
-            <div className="color-previewI" style={{ backgroundColor: this._currColor ?? "121212" }}></div>
-        </button>
-            <br></br>
-            <br></br></>;
-        return lineButton;
+        return <>
+            <button
+                className="antimodeMenu-button"
+                key="line"
+                title="lineChanger"
+                onPointerDown={action(e => this._lineBtn = !this._lineBtn)}
+                style={{
+                    // backgroundColor: "121212",
+                    position: "absolute", right: 80
+                }}>
+                <FontAwesomeIcon icon="pen-nib" size="lg" />
+                <div className="color-previewI" style={{ backgroundColor: this._currColor ?? "121212" }}></div>
+            </button>
+            <br />
+            <br />
+        </>;
     }
     @computed get linePicker() {
-        const linePicker = <div className="btn-group-palette" key="line" >
+        return <div className="btn-group-palette" key="line" >
             {this._palette.map(color => {
                 return <button
                     className="antimodeMenu-button"
                     key={color}
-                    onPointerDown={action(() => { this._currColor = color; this.editProperties(color, "color"); })}
+                    onPointerDown={action(() => this._currColor = color)}
                     style={{
                         // backgroundColor: this._lineBtn ? "121212" : "",
                         zIndex: 1001
@@ -642,19 +464,19 @@ export default class FormatShapePane extends AntimodeMenu {
             })}
 
         </div>;
-        return linePicker;
     }
     @computed get widthInput() {
         const widthInput = <>
             <input
                 style={{ color: "black", width: 80, position: "absolute", right: 20 }}
-                type="text" value={this._currWidth}
-                onChange={e => this.onChange(e.target.value, "width")}
-                autoFocus></input>  <button
-                    className="antiMenu-Buttonup"
-                    key="up"
-                    onPointerDown={action(() => { this.upDownButtons("up", "width"); })}
-                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                type="text" value={this._currStrokeWidth}
+                onChange={e => this._currStrokeWidth = e.target.value}
+                autoFocus />
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("up", "width"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
                 ˄
             </button>
             <br />
@@ -672,8 +494,8 @@ export default class FormatShapePane extends AntimodeMenu {
             <input
                 style={{ color: "black", width: 80, position: "absolute", right: 20 }}
                 type="text" value={this._currSizeHeight}
-                onChange={e => this.onChange(e.target.value, "sizeHeight")}
-                autoFocus></input>
+                onChange={e => this._currSizeHeight = e.target.value}
+                autoFocus />
             <button
                 className="antiMenu-Buttonup"
                 key="up"
@@ -698,8 +520,8 @@ export default class FormatShapePane extends AntimodeMenu {
             <input
                 style={{ color: "black", width: 80, position: "absolute", right: 20 }}
                 type="text" value={this._currSizeWidth}
-                onChange={e => this.onChange(e.target.value, "sizeWidth")}
-                autoFocus></input>
+                onChange={e => this._currSizeWidth = e.target.value}
+                autoFocus />
             <button
                 className="antiMenu-Buttonup"
                 key="up"
@@ -707,7 +529,7 @@ export default class FormatShapePane extends AntimodeMenu {
                 style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
                 ˄
             </button>
-            <br></br>
+            <br />
             <button
                 className="antiMenu-Buttonup"
                 key="up"
@@ -724,7 +546,7 @@ export default class FormatShapePane extends AntimodeMenu {
                 <input
                     style={{ color: "black", width: 80, position: "absolute", right: 20 }}
                     type="text" value={this._currRotation}
-                    onChange={e => this.onChange(e.target.value, "rotation")}
+                    onChange={e => this._currRotation = e.target.value}
                     autoFocus></input>
                 <button
                     className="antiMenu-Buttonup"
@@ -733,7 +555,7 @@ export default class FormatShapePane extends AntimodeMenu {
                     style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
                     ˄
             </button>
-                <br></br>
+                <br />
                 <button
                     className="antiMenu-Buttonup"
                     key="up"
@@ -745,137 +567,56 @@ export default class FormatShapePane extends AntimodeMenu {
     }
 
     @computed get positionHorizontalInput() {
-        const positionHorizontalInput =
-            <><input
+        return <>
+            <input
                 style={{ color: "black", width: 80, position: "absolute", right: 20 }}
                 type="text" value={this._currPositionHorizontal}
-                onChange={e => this.onChange(e.target.value, "positionHorizontal")}
-                autoFocus></input>
-                <button
-                    className="antiMenu-Buttonup"
-                    key="up"
-                    onPointerDown={action(() => { this.upDownButtons("up", "horizontal"); })}
-                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
-                    ˄
+                onChange={e => this._currPositionHorizontal = e.target.value}
+                autoFocus
+            />
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("up", "horizontal"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                ˄
+                </button>
+            <br></br>
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("down", "horizontal"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                ˅
             </button>
-                <br></br>
-                <button
-                    className="antiMenu-Buttonup"
-                    key="up"
-                    onPointerDown={action(() => { this.upDownButtons("down", "horizontal"); })}
-                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
-                    ˅
-            </button></>;
-        return positionHorizontalInput;
+        </>;
     }
 
     @computed get positionVerticalInput() {
-        const positionVerticalInput =
-            <><input
+        return <>
+            <input
                 style={{ color: "black", width: 80, position: "absolute", right: 20 }}
                 type="text" value={this._currPositionVertical}
-                onChange={e => this.onChange(e.target.value, "positionVertical")}
+                onChange={e => this._currPositionVertical = e.target.value}
                 autoFocus></input>
-                <button
-                    className="antiMenu-Buttonup"
-                    key="up"
-                    onPointerDown={action(() => { this.upDownButtons("down", "vertical"); })}
-                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
-                    ˄
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("down", "vertical"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0 }}>
+                ˄
             </button>
-                <br></br>
-                <button
-                    className="antiMenu-Buttonup"
-                    key="up"
-                    onPointerDown={action(() => { this.upDownButtons("up", "vertical"); })}
-                    style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
-                    ˅
-            </button></>;
-        return positionVerticalInput;
-    }
-
-    //change inputs
-    @action
-    onChange = (val: string, property: string): void => {
-        if (!Number.isNaN(Number(val)) && Number(val) !== null && val !== " ") {
-
-            switch (property) {
-                case "width":
-                    this._currWidth = val;
-                    if (val !== "") {
-                        this.editProperties(this._currWidth, "width");
-                    }
-                    break;
-                case "sizeHeight":
-                    this._currSizeHeight = val;
-                    if (val !== "") {
-                        this.editProperties(this._currSizeHeight, "heightSize");
-                    }
-                    break;
-                case "sizeWidth":
-                    this._currSizeWidth = val;
-                    if (val !== "") {
-
-                        this.editProperties(this._currSizeWidth, "widthSize");
-                    }
-                    break;
-                case "rotation":
-
-                    this._currRotation = val;
-                    if (val !== "") {
-
-                        this.rotate(Number(val));
-                    }
-                    break;
-                case "positionHorizontal":
-                    this._currPositionHorizontal = val; if (val !== "") {
-
-                        this.editProperties(this._currPositionHorizontal, "horizontal");
-                    }
-
-                    break;
-                case "positionVertical":
-                    this._currPositionVertical = val;
-                    if (val !== "") {
-
-                        this.editProperties(this._currPositionVertical, "vertical");
-                    }
-
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-
-    @computed get widthPicker() {
-        var widthPicker = <button
-            className="antimodeMenu-button"
-            key="width"
-            onPointerDown={action(e => this._widthBtn = !this._widthBtn)}
-            style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
-            <FontAwesomeIcon icon="bars" size="lg" />
-        </button>;
-        if (this._widthBtn) {
-            widthPicker = <div className="btn2-group" key="width">
-                {widthPicker}
-                {this._width.map(wid => {
-                    return <button
-                        className="antimodeMenu-button"
-                        key={wid}
-                        onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })}
-                        style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
-                        {wid}
-                    </button>;
-                })}
-            </div>;
-        }
-        return widthPicker;
+            <br></br>
+            <button
+                className="antiMenu-Buttonup"
+                key="up"
+                onPointerDown={action(() => { this.upDownButtons("up", "vertical"); })}
+                style={{ position: "absolute", width: 20, height: 10, right: 0, padding: 0, marginTop: -8 }}>
+                ˅
+            </button>
+        </>;
     }
 
-
-
     render() {
         const buttons = [
 
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
index e4f3248d0..0866db2be 100644
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
@@ -25,19 +25,19 @@ library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSup
 export default class InkOptionsMenu extends AntimodeMenu {
     static Instance: InkOptionsMenu;
 
-    private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", "none"];
+    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 = ["arrowHead", "arrowHead", "dot", "dot", "none"];
+    // private _arrowStart = ["arrowStart", "arrowStart", "dot", "dot", "none"];
     // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"];
     // private _arrowIcons = ["→", "↔︎", "•", "••", " "];
     private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"];
-    private _head = ["none", "none", "arrowHead", "none", "none", "arrowHead", "none", "none", "none"];
-    private _end = ["none", "arrowEnd", "arrowEnd", "none", "arrowEnd", "arrowEnd", "none", "none", "none"];
+    private _head = ["", "", "arrow", "", "", "arrow", "", "", ""];
+    private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""];
     private _shape = ["", "", "", "", "", "", "rectangle", "circle", "triangle"];
 
     @observable _shapesNum = this._shape.length;
@@ -122,12 +122,6 @@ export default class InkOptionsMenu extends AntimodeMenu {
                     case "bezier":
                         // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300;
                         break;
-                    case "arrowStart":
-                        doc.arrowStart = String(value);
-                        break;
-                    case "arrowEnd":
-                        doc.arrowEnd = String(value);
-                        break;
                     case "dash":
                         doc.dash = Number(value);
                     default:
@@ -165,13 +159,12 @@ export default class InkOptionsMenu extends AntimodeMenu {
                             SetActiveArrowEnd(this._end[i]);
                             SetActiveBezierApprox("300");
 
-                            //  this.editProperties(this._head[i], "arrowStart"), this.editProperties(this._end[i], "arrowEnd"); 
                             GestureOverlay.Instance.InkShape = this._shape[i];
                         } else {
                             this._selected = this._shapesNum;
                             Doc.SetSelectedTool(InkTool.None);
-                            SetActiveArrowStart("none");
-                            SetActiveArrowEnd("none");
+                            SetActiveArrowStart("");
+                            SetActiveArrowEnd("");
                             GestureOverlay.Instance.InkShape = "";
                             SetActiveBezierApprox("0");
 
@@ -189,13 +182,12 @@ export default class InkOptionsMenu extends AntimodeMenu {
                             SetActiveArrowEnd(this._end[i]);
                             SetActiveBezierApprox("300");
 
-                            //  this.editProperties(this._head[i], "arrowStart"), this.editProperties(this._end[i], "arrowEnd"); 
                             GestureOverlay.Instance.InkShape = this._shape[i];
                         } else {
                             this._selected = this._shapesNum;
                             Doc.SetSelectedTool(InkTool.None);
-                            SetActiveArrowStart("none");
-                            SetActiveArrowEnd("none");
+                            SetActiveArrowStart("");
+                            SetActiveArrowEnd("");
                             GestureOverlay.Instance.InkShape = "";
                             SetActiveBezierApprox("0");
 
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 137b387c0..31c5a8b13 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -14,7 +14,6 @@ import { ViewBoxBaseComponent } from "../DocComponent";
 import { ActiveInkPen, ActiveInkWidth, ActiveInkBezierApprox, SetActiveInkColor, SetActiveInkWidth, SetActiveBezierApprox } from "../InkingStroke";
 import "./ColorBox.scss";
 import { FieldView, FieldViewProps } from './FieldView';
-import { FormattedTextBox } from "./formattedText/FormattedTextBox";
 
 type ColorDocument = makeInterface<[typeof documentSchema]>;
 const ColorDocument = makeInterface(documentSchema);
-- 
cgit v1.2.3-70-g09d2


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

---
 src/client/util/InteractionUtils.tsx               |  9 +++
 src/client/views/GestureOverlay.tsx                | 17 +++++
 src/client/views/InkingStroke.tsx                  | 82 ++++++++++++++++++++++
 .../collectionFreeForm/FormatShapePane.tsx         | 59 ++++++++++++++++
 4 files changed, 167 insertions(+)

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 07adbb8b1..1d7655748 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -99,6 +99,15 @@ export namespace InteractionUtils {
         if (shape) { //if any of the shape are true
             pts = makePolygon(shape, points);
         }
+        else if (points.length > 9 && points[3].X === points[4].X && points[7].X === points[8].X) {
+            for (var i = 0; i < points.length; i += 4) {
+                const array = [[points[i].X, points[i].Y], [points[i + 1].X, points[i + 1].Y], [points[i + 2].X, points[i + 2].Y], [points[i + 3].X, points[i + 3].Y]];
+                for (var t = 0; t < 1; t += 0.01) {
+                    const point = beziercurve(t, array);
+                    pts.push({ X: point[0], Y: point[1] });
+                }
+            }
+        }
         else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) {
             //pointer is up (first and last points are the same)
             const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]);
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index a48b7b673..90d8b370e 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -23,6 +23,7 @@ import HorizontalPalette from "./Palette";
 import { Touchable } from "./Touchable";
 import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
 import InkOptionsMenu from "./collections/collectionFreeForm/InkOptionsMenu";
+import * as fitCurve from 'fit-curve';
 
 @observer
 export default class GestureOverlay extends Touchable {
@@ -632,6 +633,22 @@ export default class GestureOverlay extends Touchable {
 
                 // if no gesture (or if the gesture was unsuccessful), "dry" the stroke into an ink document
                 if (!actionPerformed) {
+                    const newPoints = this._points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]);
+                    newPoints.pop();
+                    const controlPoints: { X: number, Y: number }[] = [];
+
+                    const bezierCurves = fitCurve(newPoints, 10);
+                    for (const curve of bezierCurves) {
+
+                        controlPoints.push({ X: curve[0][0], Y: curve[0][1] });
+                        controlPoints.push({ X: curve[1][0], Y: curve[1][1] });
+                        controlPoints.push({ X: curve[2][0], Y: curve[2][1] });
+                        controlPoints.push({ X: curve[3][0], Y: curve[3][1] });
+
+
+                    }
+                    this._points = controlPoints;
+
                     this.dispatchGesture(GestureUtils.Gestures.Stroke);
                 }
                 this._points = [];
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index abc698e62..974921be8 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -17,6 +17,7 @@ import { Scripting } from "../util/Scripting";
 import { Doc } from "../../fields/Doc";
 import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
 import { action } from "mobx";
+import { setupMoveUpEvents } from "../../Utils";
 
 library.add(faPaintBrush);
 
@@ -45,6 +46,38 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         FormatShapePane.Instance.Pinned = true;
     }
 
+    private _prevX = 0;
+    private _prevY = 0;
+    private _controlNum = 0;
+    @action
+    onControlDown = (e: React.PointerEvent, i: number): void => {
+        setupMoveUpEvents(this, e, this.onControlMove, this.onControlup, (e) => { });
+        this._prevX = e.clientX;
+        this._prevY = e.clientY;
+        this._controlNum = i;
+    }
+
+    @action
+    changeCurrPoint = (i: number) => {
+        FormatShapePane.Instance._currPoint = i;
+    }
+
+    @action
+    onControlMove = (e: PointerEvent, down: number[]): boolean => {
+        const xDiff = this._prevX - e.clientX;
+        const yDiff = this._prevY - e.clientY;
+        FormatShapePane.Instance.control(xDiff, yDiff, this._controlNum);
+        this._prevX = e.clientX;
+        this._prevY = e.clientY;
+        return false;
+    }
+
+    onControlup = (e: PointerEvent) => {
+        this._prevX = 0;
+        this._prevY = 0;
+        this._controlNum = 0;
+    }
+
     render() {
         TraceMobx();
         const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
@@ -69,6 +102,51 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
             this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
             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 }[] = [];
+
+        if (data.length > 5) {
+            for (var i = 0; i <= data.length - 4; i += 4) {
+                controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
+                controlPoints.push({ X: data[i + 3].X, Y: data[i + 3].Y, I: i + 3 });
+                handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 });
+                handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 });
+            }
+            handleLine.push({ X1: data[0].X, Y1: data[0].Y, X2: data[0].X, Y2: data[0].Y, X3: data[1].X, Y3: data[1].Y, dot1: 0, dot2: 0 });
+            for (var i = 2; i < data.length - 2; i += 4) {
+                handleLine.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 1].X, Y2: data[i + 1].Y, X3: data[i + 3].X, Y3: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
+            }
+            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 });
+
+
+        }
+        const controls = controlPoints.map((pts, i) =>
+
+            <svg height="10" width="10">
+                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r="5" stroke="black" stroke-width="1" fill="red"
+                    onPointerDown={(e) => { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="all-scroll" />
+            </svg>);
+        const handles = handlePoints.map((pts, i) =>
+
+            <svg height="10" width="10">
+                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r="5" stroke="black" stroke-width="1" fill="green"
+                    onPointerDown={(e) => this.onControlDown(e, pts.I)} pointerEvents="all" cursor="all-scroll" display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
+            </svg>);
+        const handleLines = handleLine.map((pts, i) =>
+
+            <svg height="100" width="100">
+                <line x1={(pts.X1 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y1 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+                    x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="black" stroke-width="1"
+                    display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
+                <line x1={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+                    x2={(pts.X3 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y3 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="black" stroke-width="1"
+                    display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
+
+            </svg>);
+
+
         return (
             <svg className="inkingStroke"
                 width={width}
@@ -91,6 +169,10 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
                 </defs>
                 {hpoints}
                 {points}
+                {FormatShapePane.Instance._controlBtn && this.props.isSelected() ? controls : ""}
+                {FormatShapePane.Instance._controlBtn && this.props.isSelected() ? handles : ""}
+                {FormatShapePane.Instance._controlBtn && this.props.isSelected() ? handleLines : ""}
+
             </svg>
         );
     }
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 d21ef189f2c160d3d80a5cf7d824c314262a59ac Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 19 Jul 2020 22:24:19 -0400
Subject: removed spurious point

---
 src/client/util/InteractionUtils.tsx | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 07adbb8b1..473d4a263 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -112,7 +112,11 @@ export namespace InteractionUtils {
                 }
             }
         } else {
-            pts = points;
+            pts = points.slice();
+            // bcz: Ugh... this is ugly, but shapes apprently have an extra point added that is = (p[0].x,p[0].y+1) as some sort of flag.  need to remove it here.
+            if (pts.length > 2 && pts[pts.length - 2].X === pts[0].X && pts[pts.length - 2].Y === pts[0].Y) {
+                pts.pop();
+            }
         }
         const strpts = pts.reduce((acc: string, pt: { X: number, Y: number }) => acc +
             `${(pt.X - left - width / 2) * scalex + width / 2},
-- 
cgit v1.2.3-70-g09d2


From ac413fb11720bb6704a9049e5d21fe02aae197b9 Mon Sep 17 00:00:00 2001
From: yunahi <60233430+yunahi@users.noreply.github.com>
Date: Mon, 20 Jul 2020 17:17:52 +0900
Subject: fixed control points

---
 src/client/util/InteractionUtils.tsx | 23 ++++++++++-
 src/client/views/GestureOverlay.tsx  | 77 +++++++++++++++++++++++++++++++++++-
 src/client/views/InkingStroke.tsx    | 20 ++++++----
 3 files changed, 109 insertions(+), 11 deletions(-)

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 1d7655748..31b2a56e6 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -99,8 +99,8 @@ export namespace InteractionUtils {
         if (shape) { //if any of the shape are true
             pts = makePolygon(shape, points);
         }
-        else if (points.length > 9 && points[3].X === points[4].X && points[7].X === points[8].X) {
-            for (var i = 0; i < points.length; i += 4) {
+        else if (points.length >= 5 && points[3].X === points[4].X) {
+            for (var i = 0; i < points.length - 3; i += 4) {
                 const array = [[points[i].X, points[i].Y], [points[i + 1].X, points[i + 1].Y], [points[i + 2].X, points[i + 2].Y], [points[i + 3].X, points[i + 3].Y]];
                 for (var t = 0; t < 1; t += 0.01) {
                     const point = beziercurve(t, array);
@@ -223,10 +223,28 @@ export namespace InteractionUtils {
                 points.push({ X: left, Y: top });
                 return points;
             case "triangle":
+                // points.push({ X: left, Y: bottom });
+                // points.push({ X: right, Y: bottom });
+                // points.push({ X: (right + left) / 2, Y: top });
+                // points.push({ X: left, Y: bottom });
+
+                points.push({ X: left, Y: bottom });
                 points.push({ X: left, Y: bottom });
+
+                points.push({ X: right, Y: bottom });
                 points.push({ X: right, Y: bottom });
+                points.push({ X: right, Y: bottom });
+                points.push({ X: right, Y: bottom });
+
+                points.push({ X: (right + left) / 2, Y: top });
                 points.push({ X: (right + left) / 2, Y: top });
+                points.push({ X: (right + left) / 2, Y: top });
+                points.push({ X: (right + left) / 2, Y: top });
+
+                points.push({ X: left, Y: bottom });
                 points.push({ X: left, Y: bottom });
+
+
                 return points;
             case "circle":
                 const centerX = (right + left) / 2;
@@ -262,6 +280,7 @@ export namespace InteractionUtils {
             //     points.push({ X: x2, Y: y2 });
             //     return points;
             case "line":
+
                 points.push({ X: left, Y: top });
                 points.push({ X: right, Y: bottom });
                 return points;
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 90d8b370e..2eec8ed6a 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -703,18 +703,53 @@ export default class GestureOverlay extends Touchable {
             //must be (points[0].X,points[0]-1)
             case "rectangle":
                 this._points.push({ X: left, Y: top });
+                this._points.push({ X: left, Y: top });
+
+                this._points.push({ X: right, Y: top });
                 this._points.push({ X: right, Y: top });
+                this._points.push({ X: right, Y: top });
+                this._points.push({ X: right, 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: left, Y: bottom });
+                this._points.push({ X: left, Y: bottom });
                 this._points.push({ X: left, Y: bottom });
+                this._points.push({ X: left, Y: bottom });
+
+                this._points.push({ X: left, Y: top });
                 this._points.push({ X: left, Y: top });
-                this._points.push({ X: left, Y: top - 1 });
+                // this._points.push({ X: left, Y: top });
+                // this._points.push({ X: left, Y: top });
+
+                // this._points.push({ X: left, Y: top - 1 });
                 break;
             case "triangle":
+                // this._points.push({ X: left, Y: bottom });
+                // this._points.push({ X: right, Y: bottom });
+                // this._points.push({ X: (right + left) / 2, Y: top });
+                // this._points.push({ X: left, Y: bottom });
+                // this._points.push({ X: left, Y: bottom - 1 });
+                this._points.push({ X: left, Y: bottom });
                 this._points.push({ X: left, 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 + left) / 2, Y: top });
+                this._points.push({ X: (right + left) / 2, Y: top });
                 this._points.push({ X: (right + left) / 2, Y: top });
+                this._points.push({ X: (right + left) / 2, Y: top });
+
+                this._points.push({ X: left, Y: bottom });
                 this._points.push({ X: left, Y: bottom });
-                this._points.push({ X: left, Y: bottom - 1 });
+
+
                 break;
             case "circle":
                 const centerX = (right + left) / 2;
@@ -731,10 +766,48 @@ export default class GestureOverlay extends Touchable {
                 }
                 this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top });
                 this._points.push({ X: Math.sqrt(Math.pow(radius, 2) - (Math.pow((top - centerY), 2))) + centerX, Y: top - 1 });
+                // this._points.push({ X: centerX, Y: top });
+                // this._points.push({ X: centerX + radius / 2, Y: top });
+
+                // this._points.push({ X: right, Y: top + radius / 2 });
+                // this._points.push({ X: right, Y: top + radius });
+                // this._points.push({ X: right, Y: top + radius });
+                // this._points.push({ X: right, Y: bottom - radius / 2 });
+
+                // this._points.push({ X: right - radius / 2, Y: bottom });
+                // this._points.push({ X: right - radius, Y: bottom });
+                // this._points.push({ X: right - radius, Y: bottom });
+                // this._points.push({ X: left + radius / 2, Y: bottom });
+
+                // this._points.push({ X: left, Y: bottom - radius / 2 });
+                // this._points.push({ X: left, Y: bottom - radius });
+                // this._points.push({ X: left, Y: bottom - radius });
+                // this._points.push({ X: left, Y: top + radius / 2 });
+
+                // this._points.push({ X: left + radius / 2, Y: top });
+                // this._points.push({ X: left + radius, Y: top });
+
+
+
+
+
+
+
                 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":
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 974921be8..22c89b6da 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -94,10 +94,12 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         const scaleX = (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth);
         const scaleY = (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth);
         const strokeColor = StrCast(this.layoutDoc.color, "");
+
         const points = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
             StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
             StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
             StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false);
+
         const hpoints = InteractionUtils.CreatePolyline(data, left, top,
             this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
             StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
@@ -106,42 +108,46 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         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 }[] = [];
-
-        if (data.length > 5) {
+        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 });
                 controlPoints.push({ X: data[i + 3].X, Y: data[i + 3].Y, I: i + 3 });
                 handlePoints.push({ X: data[i + 1].X, Y: data[i + 1].Y, I: i + 1, dot1: i, dot2: i === 0 ? i : i - 1 });
                 handlePoints.push({ X: data[i + 2].X, Y: data[i + 2].Y, I: i + 2, dot1: i + 3, dot2: i === data.length ? i + 3 : i + 4 });
             }
+
             handleLine.push({ X1: data[0].X, Y1: data[0].Y, X2: data[0].X, Y2: data[0].Y, X3: data[1].X, Y3: data[1].Y, dot1: 0, dot2: 0 });
-            for (var i = 2; i < data.length - 2; i += 4) {
+            for (var i = 2; i < data.length - 4; i += 4) {
+
                 handleLine.push({ X1: data[i].X, Y1: data[i].Y, X2: data[i + 1].X, Y2: data[i + 1].Y, X3: data[i + 3].X, Y3: data[i + 3].Y, dot1: i + 1, dot2: i + 2 });
+
             }
             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 });
 
 
         }
+        const dotsize = String(Math.min(width * scaleX, height * scaleY) / 40);
+
         const controls = controlPoints.map((pts, i) =>
 
             <svg height="10" width="10">
-                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r="5" stroke="black" stroke-width="1" fill="red"
+                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={dotsize} stroke="black" stroke-width={String(Number(dotsize) / 2)} fill="red"
                     onPointerDown={(e) => { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="all-scroll" />
             </svg>);
         const handles = handlePoints.map((pts, i) =>
 
             <svg height="10" width="10">
-                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r="5" stroke="black" stroke-width="1" fill="green"
+                <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={dotsize} stroke="black" stroke-width={String(Number(dotsize) / 2)} fill="green"
                     onPointerDown={(e) => this.onControlDown(e, pts.I)} pointerEvents="all" cursor="all-scroll" display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
             </svg>);
         const handleLines = handleLine.map((pts, i) =>
 
             <svg height="100" width="100">
                 <line x1={(pts.X1 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y1 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
-                    x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="black" stroke-width="1"
+                    x2={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="green" stroke-width={String(Number(dotsize) / 2)}
                     display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
                 <line x1={(pts.X2 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y1={(pts.Y2 - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
-                    x2={(pts.X3 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y3 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="black" stroke-width="1"
+                    x2={(pts.X3 - left - strokeWidth / 2) * scaleX + strokeWidth / 2} y2={(pts.Y3 - top - strokeWidth / 2) * scaleY + strokeWidth / 2} stroke="green" stroke-width={String(Number(dotsize) / 2)}
                     display={(pts.dot1 === FormatShapePane.Instance._currPoint || pts.dot2 === FormatShapePane.Instance._currPoint) ? "inherit" : "none"} />
 
             </svg>);
-- 
cgit v1.2.3-70-g09d2


From 3bcc0e3a8ce4ab67dff4b3d62191c346764aa351 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 23 Jul 2020 11:56:05 -0400
Subject: got rid of lots of console.logs().  fixed fonticon box to show a
 'label' if defined otherwise 'title'.  if neither, then it shows no tooltip.

---
 src/client/ClientRecommender.tsx                   |  2 --
 src/client/apis/IBM_Recommender.ts                 |  2 --
 .../apis/google_docs/GooglePhotosClientUtils.ts    |  2 --
 src/client/cognitive_services/CognitiveServices.ts |  2 --
 src/client/documents/Documents.ts                  |  3 ++-
 src/client/util/CurrentUserUtils.ts                |  1 -
 src/client/util/DictationManager.ts                |  2 +-
 src/client/util/InteractionUtils.tsx               |  2 --
 src/client/util/ScriptManager.ts                   | 10 ---------
 src/client/util/SearchUtil.ts                      |  1 -
 src/client/util/SelectionManager.ts                |  1 -
 src/client/views/EditableView.tsx                  |  1 -
 src/client/views/GestureOverlay.tsx                |  1 -
 src/client/views/KeyphraseQueryView.tsx            |  1 -
 src/client/views/ScriptBox.tsx                     |  2 +-
 src/client/views/SearchDocBox.tsx                  |  9 --------
 src/client/views/Touchable.tsx                     |  3 ---
 src/client/views/animationtimeline/Keyframe.tsx    |  4 ----
 src/client/views/animationtimeline/Timeline.tsx    |  1 -
 src/client/views/animationtimeline/Track.tsx       |  4 ----
 .../views/collections/CollectionCarousel3DView.tsx |  3 ---
 .../views/collections/CollectionCarouselView.tsx   |  2 --
 .../collections/CollectionMasonryViewFieldRow.tsx  |  1 -
 src/client/views/collections/CollectionMenu.tsx    |  2 +-
 .../views/collections/CollectionSchemaCells.tsx    | 12 -----------
 .../views/collections/CollectionSchemaView.tsx     |  1 -
 src/client/views/collections/CollectionSubView.tsx |  2 --
 .../views/collections/CollectionTreeView.tsx       |  4 ----
 src/client/views/collections/CollectionView.tsx    |  2 +-
 src/client/views/collections/SchemaTable.tsx       |  3 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 --
 .../collections/collectionFreeForm/MarqueeView.tsx |  3 ---
 src/client/views/linking/LinkMenu.tsx              |  1 -
 src/client/views/linking/LinkMenuItem.tsx          |  5 -----
 src/client/views/nodes/DocumentContentsView.tsx    |  2 +-
 src/client/views/nodes/DocumentLinksButton.tsx     |  2 --
 src/client/views/nodes/DocumentView.tsx            |  1 -
 src/client/views/nodes/FontIconBox.tsx             | 24 ++++++++++++----------
 src/client/views/nodes/PresBox.tsx                 |  1 -
 src/client/views/nodes/RadialMenu.tsx              |  1 -
 src/client/views/nodes/ScreenshotBox.tsx           |  2 +-
 src/client/views/nodes/ScriptingBox.tsx            |  1 -
 src/client/views/nodes/VideoBox.tsx                |  2 +-
 src/client/views/nodes/WebBox.tsx                  |  2 +-
 .../views/nodes/formattedText/DashDocView.tsx      |  2 +-
 .../views/nodes/formattedText/RichTextSchema.tsx   |  2 +-
 src/client/views/search/FilterBox.tsx              |  1 -
 src/client/views/search/SearchBox.tsx              |  5 +----
 src/client/views/search/ToggleBar.tsx              |  1 -
 src/fields/Doc.ts                                  |  1 -
 src/fields/ScriptField.ts                          |  1 -
 src/fields/util.ts                                 |  1 -
 src/server/Recommender.ts                          |  4 ----
 src/server/downsize.ts                             |  2 +-
 54 files changed, 28 insertions(+), 127 deletions(-)

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/ClientRecommender.tsx b/src/client/ClientRecommender.tsx
index d18669b02..3f875057e 100644
--- a/src/client/ClientRecommender.tsx
+++ b/src/client/ClientRecommender.tsx
@@ -50,7 +50,6 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
     @observable private corr_matrix = [[0, 0], [0, 0]]; // for testing
 
     constructor(props: RecommenderProps) {
-        //console.log("creating client recommender...");
         super(props);
         if (!ClientRecommender.Instance) ClientRecommender.Instance = this;
         ClientRecommender.Instance.docVectors = new Set();
@@ -383,7 +382,6 @@ export class ClientRecommender extends React.Component<RecommenderProps> {
                         case 200:
                             const title_vals: string[] = [];
                             const url_vals: string[] = [];
-                            //console.log(result);
                             if (xml) {
                                 const titles = xml.getElementsByTagName("title");
                                 let counter = 1;
diff --git a/src/client/apis/IBM_Recommender.ts b/src/client/apis/IBM_Recommender.ts
index 480b9cb1c..e6265fcb5 100644
--- a/src/client/apis/IBM_Recommender.ts
+++ b/src/client/apis/IBM_Recommender.ts
@@ -29,10 +29,8 @@
 //     export const analyze = async (_parameters: any): Promise<Opt<string>> => {
 //         try {
 //             const response = await naturalLanguageUnderstanding.analyze(_parameters);
-//             console.log(response);
 //             return (JSON.stringify(response, null, 2));
 //         } catch (err) {
-//             console.log('error: ', err);
 //             return undefined;
 //         }
 //     };
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 13bfb3a91..92eaf2e73 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -156,8 +156,6 @@ export namespace GooglePhotos {
             const values = Object.values(ContentCategories).filter(value => value !== ContentCategories.NONE);
             for (const value of values) {
                 const searched = (await ContentSearch({ included: [value] }))?.mediaItems?.map(({ id }) => id);
-                console.log("Searching " + value);
-                console.log(searched);
                 searched?.forEach(async id => {
                     const image = await Cast(idMapping[id], Doc);
                     if (image) {
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 6b0b3e029..80961af14 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -377,7 +377,6 @@ export namespace CognitiveServices {
                         console.log("successful vectorization!");
                         const vectorValues = new List<number>();
                         indices.forEach((ind: any) => {
-                            //console.log(wordvec.word);
                             vectorValues.push(wordvecs[ind]);
                         });
                         ClientRecommender.Instance.processVector(vectorValues, dataDoc, mainDoc);
@@ -385,7 +384,6 @@ export namespace CognitiveServices {
                     else {
                         console.log("unsuccessful :( word(s) not in vocabulary");
                     }
-                    //console.log(vectorValues.size);
                 }
                 );
             }
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e2569ec70..cd2792226 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -92,6 +92,7 @@ export interface DocumentOptions {
     layoutKey?: string;
     type?: string;
     title?: string;
+    label?: string;
     toolTip?: string; // tooltip to display on hover
     style?: string;
     page?: number;
@@ -494,7 +495,7 @@ export namespace Docs {
                     Doc.Get.FromJson({ data: device, appendToExisting: { targetDoc: Doc.GetProto(doc) } });
                     Doc.AddDocToList(parentProto, "data", doc);
                 } else if (errors) {
-                    console.log(errors);
+                    console.log("Documents:" + errors);
                 } else {
                     alert("A Buxton document import was completely empty (??)");
                 }
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 23b8f09de..b47cfb33a 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -487,7 +487,6 @@ export class CurrentUserUtils {
     // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu
     static setupActiveMobileMenu(doc: Doc) {
         if (doc.activeMobileMenu === undefined) {
-            console.log("undefined");
             doc.activeMobileMenu = this.setupMobileMenu();
         }
         return doc.activeMobileMenu as Doc;
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 28b1ca6cf..540540642 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -121,7 +121,7 @@ export namespace DictationManager {
 
         const listenImpl = (options?: Partial<ListeningOptions>) => {
             if (!recognizer) {
-                console.log(unsupported);
+                console.log("DictationManager:" + unsupported);
                 return unsupported;
             }
             if (isListening) {
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 473d4a263..8b3614ea7 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -161,7 +161,6 @@ export namespace InteractionUtils {
     //     return (
     //         InkOptionsMenu.Instance.getColors().map(color => {
     //             const id1 = "arrowStartTest" + color;
-    //             console.log(color);
     //             <marker id={id1} orient="auto" overflow="visible" refX="0" refY="1" markerWidth="10" markerHeight="7">
     //                 <polygon points="0 0, 3 1, 0 2" fill={"#" + color} />
     //             </marker>;
@@ -383,7 +382,6 @@ export namespace InteractionUtils {
         //                 let dist12 = TwoPointEuclidist(pt1, pt2);
         //                 let dist23 = TwoPointEuclidist(pt2, pt3);
         //                 let dist13 = TwoPointEuclidist(pt1, pt3);
-        //                 console.log(`distances: ${dist12}, ${dist23}, ${dist13}`);
         //                 let dist12close = dist12 < leniency;
         //                 let dist23close = dist23 < leniency;
         //                 let dist13close = dist13 < leniency;
diff --git a/src/client/util/ScriptManager.ts b/src/client/util/ScriptManager.ts
index 785e63d9a..94806a7ba 100644
--- a/src/client/util/ScriptManager.ts
+++ b/src/client/util/ScriptManager.ts
@@ -32,24 +32,17 @@ export class ScriptManager {
     }
 
     public addScript(scriptDoc: Doc): boolean {
-
-        console.log("in add script method");
-
         const scriptList = this.getAllScripts();
         scriptList.push(scriptDoc);
         if (ScriptManager.Instance.ScriptManagerDoc) {
             ScriptManager.Instance.ScriptManagerDoc.data = new List<Doc>(scriptList);
             ScriptManager.addScriptToGlobals(scriptDoc);
-            console.log("script added");
             return true;
         }
         return false;
     }
 
     public deleteScript(scriptDoc: Doc): boolean {
-
-        console.log("in delete script method");
-
         if (scriptDoc.name) {
             Scripting.removeGlobal(StrCast(scriptDoc.name));
         }
@@ -70,7 +63,6 @@ export class ScriptManager {
         Scripting.removeGlobal(StrCast(scriptDoc.name));
 
         const params = Cast(scriptDoc["data-params"], listSpec("string"), []);
-        console.log(params);
         const paramNames = params.reduce((o: string, p: string) => {
             if (params.indexOf(p) === params.length - 1) {
                 o = o + p.split(":")[0].trim();
@@ -82,8 +74,6 @@ export class ScriptManager {
 
         const f = new Function(paramNames, StrCast(scriptDoc.script));
 
-        console.log(scriptDoc.script);
-
         Object.defineProperty(f, 'name', { value: StrCast(scriptDoc.name), writable: false });
 
         let parameters = "(";
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 1ac68480e..0a01d8ac7 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -128,7 +128,6 @@ export namespace SearchUtil {
         });
         const result: IdSearchResult = JSON.parse(response);
         const { ids, numFound, highlighting } = result;
-        //console.log(ids.length);
         const docMap = await DocServer.GetRefFields(ids);
         const docs: Doc[] = [];
         for (const id of ids) {
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 9a968aeda..20d881961 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -22,7 +22,6 @@ export namespace SelectionManager {
                 }
 
                 manager.SelectedDocuments.set(docView, true);
-                // console.log(manager.SelectedDocuments);
                 docView.props.whenActiveChanged(true);
             } else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) {
                 Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false));
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 25a87ab56..ad61d3f91 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -73,7 +73,6 @@ export class EditableView extends React.Component<EditableProps> {
     //     // this is done because when autosuggest is turned on, the suggestions are passed in as a prop,
     //     // so when the suggestions are passed in, and no editing prop is passed in, it used to set it
     //     // to false. this will no longer do so -syip
-    //     console.log("props editing = " + nextProps.editing);
     //     if (nextProps.editing && nextProps.editing !== this._editing) {
     //         this._editing = nextProps.editing;
     //         EditableView.loadId = "";
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index b0b0d72b1..2e588ceb5 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -160,7 +160,6 @@ export default class GestureOverlay extends Touchable {
             if (nts.nt.length === 1) {
                 // -- radial menu code --
                 this._holdTimer = setTimeout(() => {
-                    console.log("hold");
                     const target = document.elementFromPoint(te.changedTouches?.item(0).clientX, te.changedTouches?.item(0).clientY);
                     const pt: any = te.touches[te.touches?.length - 1];
                     if (nts.nt.length === 1 && pt.radiusX > 1 && pt.radiusY > 1) {
diff --git a/src/client/views/KeyphraseQueryView.tsx b/src/client/views/KeyphraseQueryView.tsx
index 1dc156968..13d52db88 100644
--- a/src/client/views/KeyphraseQueryView.tsx
+++ b/src/client/views/KeyphraseQueryView.tsx
@@ -11,7 +11,6 @@ export interface KP_Props {
 export class KeyphraseQueryView extends React.Component<KP_Props>{
     constructor(props: KP_Props) {
         super(props);
-        console.log("FIRST KEY PHRASE: ", props.keyphrases[0]);
     }
 
     render() {
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index 888f84dfa..2c185be86 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -39,7 +39,7 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
 
     @action
     onError = (error: string) => {
-        console.log(error);
+        console.log("ScriptBox: " + error);
     }
 
     overlayDisposer?: () => void;
diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx
index e038d8213..084f952a3 100644
--- a/src/client/views/SearchDocBox.tsx
+++ b/src/client/views/SearchDocBox.tsx
@@ -60,8 +60,6 @@ export class SearchDocBox extends React.Component<FieldViewProps> {
 
     componentDidMount() {
         runInAction(() => {
-            console.log("didit"
-            );
             this.query = StrCast(this.props.Document.searchText);
             this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }));
 
@@ -83,12 +81,9 @@ export class SearchDocBox extends React.Component<FieldViewProps> {
         if (newKey.length > 1) {
             const newdocs = await this.getAllResults(this.query);
             const things = newdocs.docs;
-            console.log(things);
-            console.log(this.content);
             runInAction(() => {
                 this.content = Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query });
             });
-            console.log(this.content);
         }
 
 
@@ -150,12 +145,9 @@ export class SearchDocBox extends React.Component<FieldViewProps> {
     }
 
     enter = async (e: React.KeyboardEvent) => {
-        console.log(e.key);
         if (e.key === "Enter") {
             const newdocs = await this.getAllResults(this.query);
-            console.log(newdocs.docs);
             this.content = Docs.Create.TreeDocument(newdocs.docs, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` });
-
         }
     }
 
@@ -256,7 +248,6 @@ export class SearchDocBox extends React.Component<FieldViewProps> {
     startDragCollection = async () => {
         const res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString));
         const filtered = FilterBox.Instance.filterDocsByType(res.docs);
-        // console.log(this._results)
         const docs = filtered.map(doc => {
             const isProto = Doc.GetT(doc, "isPrototype", "boolean", true);
             if (isProto) {
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 5e48d5ffb..c4cae7e8d 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -54,7 +54,6 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
             }
         });
 
-        // console.log(ptsToDelete.length);
         ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
 
         if (this.prevPoints.size) {
@@ -86,7 +85,6 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
         // if we're not actually moving a lot, don't consider it as dragging yet
         if (!InteractionUtils.IsDragging(this.prevPoints, myTouches, 5) && !this._touchDrag) return;
         this._touchDrag = true;
-        // console.log(myTouches.length);
         switch (myTouches.length) {
             case 1:
                 this.handle1PointerMove(te, me);
@@ -107,7 +105,6 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
 
     @action
     protected onTouchEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
-        // console.log(InteractionUtils.GetMyTargetTouches(e, this.prevPoints).length + " up");
         // remove all the touches associated with the event
         const te = me.touchEvent;
         for (const pt of me.changedTouches) {
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index 3a7182a94..1b81c544a 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -527,10 +527,6 @@ export class Keyframe extends React.Component<IProps> {
      */
     //154, 206, 223
     render() {
-        trace();
-        console.log(this.props.RegionData.position);
-        console.log(this.regiondata.position);
-        console.log(this.pixelPosition);
         return (
             <div className="bar" ref={this._bar} style={{
                 transform: `translate(${this.pixelPosition}px)`,
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index eac30ca75..df828897e 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -466,7 +466,6 @@ export class Timeline extends React.Component<FieldViewProps> {
                 //TODO: remove undefineds and duplicates
             }
         });
-        // console.log(longestTime); 
         return longestTime;
     }
 
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 4987006e7..25c2e68e7 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -134,7 +134,6 @@ export class Track extends React.Component<IProps> {
     autoCreateKeyframe = () => {
         const objects = this.objectWhitelist.map(key => this.props.node[key]);
         intercept(this.props.node, change => {
-            console.log(change);
             return change;
         });
         return reaction(() => {
@@ -174,7 +173,6 @@ export class Track extends React.Component<IProps> {
             if (regiondata) {
                 this.props.node.hidden = false;
                 // if (!this._autoKfReaction) {
-                //     // console.log("creating another reaction"); 
                 //     // this._autoKfReaction = this.autoCreateKeyframe(); 
                 // }
                 this.timeChange();
@@ -204,7 +202,6 @@ export class Track extends React.Component<IProps> {
                     }
                 });
             } else {
-                console.log("reverting state");
                 //this.revertState(); 
             }
         });
@@ -229,7 +226,6 @@ export class Track extends React.Component<IProps> {
             const rightkf: (Doc | undefined) = await KeyframeFunc.calcMinRight(regiondata, this.time); //right keyframe, if it exists        
             const currentkf: (Doc | undefined) = await this.calcCurrent(regiondata); //if the scrubber is on top of the keyframe
             if (currentkf) {
-                console.log("is current");
                 await this.applyKeys(currentkf);
                 this.saveStateKf = currentkf;
                 this.saveStateRegion = regiondata;
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 8e9970ada..0f3b6f212 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -86,7 +86,6 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume
     interval?: number;
     startAutoScroll = (direction: number) => {
         this.interval = window.setInterval(() => {
-            console.log(this.interval, this.scrollSpeed);
             this.changeSlide(direction);
         }, this.scrollSpeed);
     }
@@ -113,13 +112,11 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume
     onPointerDown = (e: React.PointerEvent) => {
         this._downX = e.clientX;
         this._downY = e.clientY;
-        console.log("CAROUSEL down");
         document.addEventListener("pointerup", this.onpointerup);
     }
     private _lastTap: number = 0;
     private _doubleTap = false;
     onpointerup = (e: PointerEvent) => {
-        console.log("CAROUSEL up");
         this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
         this._lastTap = Date.now();
     }
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 404dc0daa..27aea4b99 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -91,13 +91,11 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
     onPointerDown = (e: React.PointerEvent) => {
         this._downX = e.clientX;
         this._downY = e.clientY;
-        console.log("CAROUSEL down");
         document.addEventListener("pointerup", this.onpointerup);
     }
     private _lastTap: number = 0;
     private _doubleTap = false;
     onpointerup = (e: PointerEvent) => {
-        console.log("CAROUSEL up");
         this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
         this._lastTap = Date.now();
     }
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 627b22417..9a7ea2c93 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -84,7 +84,6 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @undoBatch
     rowDrop = action((e: Event, de: DragManager.DropEvent) => {
-        console.log("masronry row drop");
         this._createAliasSelected = false;
         if (de.complete.docDragData) {
             (this.props.parent.Document.dropConverter instanceof ScriptField) &&
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 5d95b214a..992c1f600 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -462,7 +462,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
     render() {
         return this.Document.isAnnotationOverlay ? (null) :
             <div className="collectionFreeFormMenu-cont">
-                <div key="back" title="mini map" className="backKeyframe" onClick={this.miniMap}>
+                <div key="map" title="mini map" className="backKeyframe" onClick={this.miniMap}>
                     <FontAwesomeIcon icon={"map"} size={"lg"} />
                 </div>
                 <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index d76b6d204..eecaf7672 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -151,7 +151,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     //     let field = this.props.rowProps.original[this.props.rowProps.column.id as string];
     //     let doc = FieldValue(Cast(field, Doc));
 
-    //     console.log("Expanding doc", StrCast(doc!.title));
     //     this.props.setPreviewDoc(doc!);
 
     //     // this.props.changeFocusedCellByIndex(this.props.row, this.props.col);
@@ -265,7 +264,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                                     return "0";
                                 } else {
                                     const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
-                                    console.log(cfield);
                                     if (type === "number") {
                                         return StrCast(cfield);
                                     }
@@ -286,7 +284,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                                     const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
                                     if (script.compiled) {
                                         retVal = this.applyToDoc(props.Document, this.props.row, this.props.col, script.run);
-                                        console.log("compiled");
                                     }
 
                                 }
@@ -350,17 +347,13 @@ export class CollectionSchemaDateCell extends CollectionSchemaCell {
 
     @action
     handleChange = (date: any) => {
-        console.log(date);
         this._date = date;
         // const script = CompileScript(date.toString(), { requiredType: "Date", addReturn: true, params: { this: Doc.name } });
         // if (script.compiled) {
-        //     console.log("scripting");
         //     this.applyToDoc(this._document, this.props.row, this.props.col, script.run);
         // } else {
-        console.log(DateCast(date));
         // ^ DateCast is always undefined for some reason, but that is what the field should be set to
         this._document[this.props.rowProps.column.id as string] = date as Date;
-        console.log(this._document[this.props.rowProps.column.id as string]);
         //}
     }
 
@@ -425,8 +418,6 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
 
         const results = script.compiled && script.run();
         if (results && results.success) {
-
-            console.log(results.result);
             this._doc = results.result;
             this._document[this.prop.fieldKey] = results.result;
             this._docTitle = this._doc?.title;
@@ -457,10 +448,8 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
             this._preview = false;
         } else {
             if (bool) {
-                console.log("show doc");
                 this.props.showDoc(this._doc, this.prop.DataDoc, e.clientX, e.clientY);
             } else {
-                console.log("no doc");
                 this.props.showDoc(undefined);
             }
         }
@@ -675,7 +664,6 @@ export class CollectionSchemaListCell extends CollectionSchemaCell {
 
     @action
     toggleOpened(open: boolean) {
-        console.log("open: " + open);
         this._opened = open;
     }
 
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 3c42a2f1c..5553bbbb7 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -332,7 +332,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
 
     @action
     openHeader = (col: any, screenx: number, screeny: number) => {
-        console.log("header opening");
         this._col = col;
         this._headerOpen = !this._headerOpen;
         this._pointerX = screenx;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a147b06a3..8480a56cc 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -340,7 +340,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                 // if ((matches = /(https:\/\/)?photos\.google\.com\/(u\/3\/)?album\/([^\\]+)/g.exec(text)) !== null) {
                 //     const albumId = matches[3];
                 //     const mediaItems = await GooglePhotos.Query.AlbumSearch(albumId);
-                //     console.log(mediaItems);
                 //     return;
                 // }
             }
@@ -381,7 +380,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                     file?.type && files.push(file);
 
                     file?.type === "application/json" && Utils.readUploadedFileAsText(file).then(result => {
-                        console.log(result);
                         const json = JSON.parse(result as string);
                         this.addDocument(Docs.Create.TreeDocument(
                             json["rectangular-puzzle"].crossword.clues[0].clue.map((c: any) => {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 96a2e23c9..651357e5d 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -796,9 +796,6 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
         </div >;
     }
 
-    onKeyPress = (e: React.KeyboardEvent) => {
-        console.log(e);
-    }
     onChildClick = () => {
         return this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick);
     }
@@ -819,7 +816,6 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
                         paddingTop: `${NumCast(this.doc._yPadding, 20)}px`,
                         pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined
                     }}
-                    onKeyPress={this.onKeyPress}
                     onWheel={(e) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
                     onDrop={this.onTreeDrop}
                     ref={this.createTreeDropTarget}>
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 53fd83f26..e2f78d6f9 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -167,7 +167,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         const context = Cast(doc.context, Doc, null);
                         if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
                             const pushpin = Docs.Create.FontIconDocument({
-                                title: "pushpin",
+                                title: "pushpin", label: "",
                                 icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), _backgroundColor: "#0000003d", color: "#ACCEF7",
                                 _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, displayTimecode: Cast(doc.displayTimecode, "number", null)
                             });
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 9e3b4d961..cde795098 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -135,7 +135,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     changeSorting = (col: any) => {
-        console.log(col.heading);
         if (col.desc === undefined) {
             // no sorting
             this.props.changeColumnSort(col, true);
@@ -149,7 +148,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     @action
-    changeTitleMode = () => { console.log("header clicked"); this._showTitleDropdown = !this._showTitleDropdown; }
+    changeTitleMode = () => this._showTitleDropdown = !this._showTitleDropdown;
 
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 3b19a2ab8..979b21321 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -497,10 +497,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 const start = this.getTransform().transformPoint(Math.min(...ge.points.map(p => p.X)), Math.min(...ge.points.map(p => p.Y)));
                 this._inkToTextStartX = start[0];
                 this._inkToTextStartY = start[1];
-                console.log("start");
                 break;
             case GestureUtils.Gestures.EndBracket:
-                console.log("end");
                 if (this._inkToTextStartX && this._inkToTextStartY) {
                     const end = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y)));
                     const setDocs = this.getActiveDocuments().filter(s => s.proto?.type === "rtf" && s.color);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 84719b2c9..aa9a3b4ae 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -434,8 +434,6 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             });
             CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then((results) => {
                 // const wordResults = results.filter((r: any) => r.category === "inkWord");
-                // console.log(wordResults);
-                // console.log(results);
                 // for (const word of wordResults) {
                 //     const indices: number[] = word.strokeIds;
                 //     indices.forEach(i => {
@@ -476,7 +474,6 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 //     });
                 // }
                 const lines = results.filter((r: any) => r.category === "line");
-                console.log(lines);
                 const text = lines.map((l: any) => l.recognizedText).join("\r\n");
                 this.props.addDocument(Docs.Create.TextDocument(text, { _width: this.Bounds.width, _height: this.Bounds.height, x: this.Bounds.left + this.Bounds.width, y: this.Bounds.top, title: text }));
             });
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 2d151e9bc..7b5fb0127 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -46,7 +46,6 @@ export class LinkMenu extends React.Component<Props> {
 
         if (this._linkMenuRef && !this._linkMenuRef.current?.contains(e.target as any)) {
             if (this._editorRef && !this._editorRef.current?.contains(e.target as any)) {
-                console.log("outside click");
                 DocumentLinksButton.EditLink = undefined;
             }
         }
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d8ba39f09..d1c839c3b 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -81,10 +81,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     @action toggleShowMore(e: React.PointerEvent) { e.stopPropagation(); this._showMore = !this._showMore; }
 
     onEdit = (e: React.PointerEvent): void => {
-
-        console.log("Edit");
         LinkManager.currentLink = this.props.linkDoc;
-        console.log(this.props.linkDoc);
         setupMoveUpEvents(this, e, this.editMoved, emptyFunction, () => this.props.showEditor(this.props.linkDoc));
     }
 
@@ -119,7 +116,6 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         document.addEventListener("pointerup", this.onLinkButtonUp);
 
         if (this._buttonRef && !!!this._buttonRef.current?.contains(e.target as any)) {
-            console.log("outside click");
             LinkDocPreview.LinkInfo = undefined;
         }
     }
@@ -153,7 +149,6 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
 
     @action.bound
     async followDefault() {
-        console.log("FOLLOWWW");
         DocumentLinksButton.EditLink = undefined;
         LinkDocPreview.LinkInfo = undefined;
 
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index f2f8ada68..47dc0a773 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -200,7 +200,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
                 jsx={layoutFrame}
                 showWarnings={true}
 
-                onError={(test: any) => { console.log(test); }}
+                onError={(test: any) => { console.log("DocumentContentsView:" + test); }}
             />;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 13bec5d7f..b17accfd6 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -68,8 +68,6 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 //action(() => Doc.BrushDoc(this.props.View.Document));
                 DocumentLinksButton.StartLink = this.props.View;
             } else if (!this.props.InMenu) {
-                console.log("editing");
-                this.props.View ? console.log("view") : null;
                 DocumentLinksButton.EditLink = this.props.View;
                 DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
             }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9e492650b..998c6798e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -910,7 +910,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         if (!ClientRecommender.Instance) new ClientRecommender({ title: "Client Recommender" });
         const documents: Doc[] = [];
         const allDocs = await SearchUtil.GetAllDocs();
-        // allDocs.forEach(doc => console.log(doc.title));
         // clears internal representation of documents as vectors
         ClientRecommender.Instance.reset_docs();
         //ClientRecommender.Instance.arxivrequest("electrons");
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index a4d16fe0e..ab34e13b0 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -61,16 +61,18 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
     render() {
         const referenceDoc = (this.layoutDoc.dragFactory instanceof Doc ? this.layoutDoc.dragFactory : this.layoutDoc);
         const refLayout = Doc.Layout(referenceDoc);
-        return <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
-            <button className="fontIconBox-outerDiv" ref={this._ref} onContextMenu={this.specificContextMenu}
-                style={{
-                    padding: Cast(this.layoutDoc._xPadding, "number", null),
-                    background: StrCast(refLayout._backgroundColor, StrCast(refLayout.backgroundColor)),
-                    boxShadow: this.layoutDoc.ischecked ? `4px 4px 12px black` : undefined
-                }}>
-                <FontAwesomeIcon className="fontIconBox-icon" icon={this.dataDoc.icon as any} color={StrCast(this.layoutDoc.color, this._foregroundColor)} size="sm" />
-                {!this.rootDoc.title ? (null) : <div className="fontIconBox-label"> {StrCast(this.rootDoc.title).substring(0, 6)} </div>}
-            </button>
-        </Tooltip>;
+        const button = <button className="fontIconBox-outerDiv" ref={this._ref} onContextMenu={this.specificContextMenu}
+            style={{
+                padding: Cast(this.layoutDoc._xPadding, "number", null),
+                background: StrCast(refLayout._backgroundColor, StrCast(refLayout.backgroundColor)),
+                boxShadow: this.layoutDoc.ischecked ? `4px 4px 12px black` : undefined
+            }}>
+            <FontAwesomeIcon className="fontIconBox-icon" icon={this.dataDoc.icon as any} color={StrCast(this.layoutDoc.color, this._foregroundColor)} size="sm" />
+            {!this.rootDoc.title ? (null) : <div className="fontIconBox-label" style={{ width: this.rootDoc.label ? "max-content" : undefined }}> {StrCast(this.rootDoc.label, StrCast(this.rootDoc.title).substring(0, 6))} </div>}
+        </button>;
+        return !this.layoutDoc.toolTip ? button :
+            <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
+                {button}
+            </Tooltip>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 8818d375e..a304ced18 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -297,7 +297,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
     render() {
-        // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
         // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs);
         // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
         //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index a3ac09a11..7f0956e51 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -89,7 +89,6 @@ export class RadialMenu extends React.Component {
 
     @action
     componentDidMount = () => {
-        console.log(this._pageX);
         document.addEventListener("pointerdown", this.onPointerDown);
         document.addEventListener("pointerup", this.onPointerUp);
         this.previewcircle();
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index f7dee0896..1cd29d795 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -112,7 +112,7 @@ export class ScreenshotBox extends ViewBoxBaseComponent<FieldViewProps, Screensh
             return returnedUri;
 
         } catch (e) {
-            console.log(e);
+            console.log("ScreenShotBox:" + e);
         }
     }
     @observable _screenCapture = false;
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 04ac34cc2..bc43cd473 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -109,7 +109,6 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc
     @action
     resetSuggestionPos(caret: any) {
         if (!this._suggestionRef.current || !this._scriptTextRef.current) return;
-        console.log('(top, left, height) = (%s, %s, %s)', caret.top, caret.left, caret.height);
         const suggestionWidth = this._suggestionRef.current.offsetWidth;
         const scriptWidth = this._scriptTextRef.current.offsetWidth;
         const top = caret.top;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index a5c6c4a48..ee92e517c 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -205,7 +205,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
             return returnedUri;
 
         } catch (e) {
-            console.log(e);
+            console.log("VideoBox :" + e);
         }
     }
     @observable _screenCapture = false;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 05355caba..39bb7c01d 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -189,7 +189,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             this.dataDoc[this.fieldKey] = new WebField(URLy);
             this.dataDoc[this.annotationKey] = new List<Doc>([]);
         } catch (e) {
-            console.log("Error in URL :" + this._url);
+            console.log("WebBox URL error:" + this._url);
         }
     }
 
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 5c3f3dcc9..212da3f3d 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -209,7 +209,7 @@ export class DashDocView extends React.Component<IDashDocView> {
                 try { // bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made
                     view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: dashDoc._width + "px", height: dashDoc._height + "px" }));
                 } catch (e) {
-                    console.log(e);
+                    console.log("DashDocView:" + e);
                 }
             }
 
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index 7a50ec3af..33a080fe4 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -170,7 +170,7 @@ export class DashDocView {
                             }
                         }
                     } catch (e) {
-                        console.log(e);
+                        console.log("RichTextSchema: " + e);
                     }
                 }
             };
diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx
index 4b53963a5..eb61f9a14 100644
--- a/src/client/views/search/FilterBox.tsx
+++ b/src/client/views/search/FilterBox.tsx
@@ -352,7 +352,6 @@ export class FilterBox extends React.Component {
     getDataStatus() { return this._deletedDocsStatus; }
 
     getActiveFilters() {
-        console.log(this._authorFieldStatus, this._titleFieldStatus, this._dataFieldStatus);
         return (
             <div className="active-filters">
                 {!this._basicWordStatus ? <div className="active-icon container">
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index c9d29e485..99fa6da21 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -125,7 +125,7 @@ export class SearchBox extends React.Component<SearchProps> {
             return returnedUri;
 
         } catch (e) {
-            console.log(e);
+            console.log("SearchBox:" + e);
         }
     }
 
@@ -582,7 +582,6 @@ export class SearchBox extends React.Component<SearchProps> {
     }
 
     expandSection(thing: string) {
-        console.log("expand");
         const element = document.getElementById(thing)!;
         // get the height of the element's inner content, regardless of its actual size
         const sectionHeight = element.scrollHeight;
@@ -593,7 +592,6 @@ export class SearchBox extends React.Component<SearchProps> {
         // when the next css transition finishes (which should be the one we just triggered)
         element.addEventListener('transitionend', function handler(e) {
             // remove this event listener so it only gets triggered once
-            console.log("autoset");
             element.removeEventListener('transitionend', handler);
 
             // remove "height" from the element's inline styles, so it can return to its initial value
@@ -608,7 +606,6 @@ export class SearchBox extends React.Component<SearchProps> {
 
     autoset(thing: string) {
         const element = document.getElementById(thing)!;
-        console.log("autoset");
         element.removeEventListener('transitionend', function (e) { });
 
         // remove "height" from the element's inline styles, so it can return to its initial value
diff --git a/src/client/views/search/ToggleBar.tsx b/src/client/views/search/ToggleBar.tsx
index e4d7f2fd5..466822eba 100644
--- a/src/client/views/search/ToggleBar.tsx
+++ b/src/client/views/search/ToggleBar.tsx
@@ -58,7 +58,6 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
         this._forwardTimeline.play();
         this._forwardTimeline.reverse();
         this.props.handleChange();
-        console.log(this.props.getStatus());
     }
 
     @action.bound
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 917a6853c..7e91a7761 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -566,7 +566,6 @@ export namespace Doc {
     export async function Zip(doc: Doc) {
         const { clone, map } = await Doc.MakeClone(doc, true);
         function replacer(key: any, value: any) {
-            console.log("Checkin: " + key);
             if (["cloneOf", "context", "cursors"].includes(key)) return undefined;
             else if (value instanceof Doc) {
                 if (key !== "field" && Number.isNaN(Number(key))) {
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 4604a2132..bd08b2f32 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -53,7 +53,6 @@ async function deserializeScript(script: ScriptField) {
     if (script.script.originalScript === 'convertToButtons(dragData)') {
         return (script as any).script = (ScriptField.ConvertToButtons ?? (ScriptField.ConvertToButtons = ComputedField.MakeFunction('convertToButtons(dragData)', { dragData: "DocumentDragData" })))?.script;
     }
-    console.log(script.script.originalScript);
     const captures: ProxyField<Doc> = (script as any).captures;
     if (captures) {
         const doc = (await captures.value())!;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 20b072786..ef66d9633 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -35,7 +35,6 @@ export namespace Plugins {
 }
 
 const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
-    //console.log("-set " + target[SelfProxy].title + "(" + target[SelfProxy][prop] + ")." + prop.toString() + " = " + value);
     if (SerializationHelper.IsSerializing()) {
         target[prop] = value;
         return true;
diff --git a/src/server/Recommender.ts b/src/server/Recommender.ts
index 423ce9b46..935ec3871 100644
--- a/src/server/Recommender.ts
+++ b/src/server/Recommender.ts
@@ -21,7 +21,6 @@
 //     private choice: string = ""; // Tensorflow or Word2Vec
 
 //     constructor() {
-//         console.log("creating recommender...");
 //         Recommender.Instance = this;
 //     }
 
@@ -70,7 +69,6 @@
 //         if (this._model) {
 //             if (this.choice === "WV") {
 //                 let similarity = this._model.similarity('father', 'mother');
-//                 console.log(similarity);
 //             }
 //             else if (this.choice === "TF") {
 //                 const model = this._model as use.UniversalSentenceEncoder;
@@ -119,7 +117,6 @@
 //     }
 
 //     // public async trainModel() {
-//     //     console.log("phrasing...");
 //     //     w2v.word2vec("./node_modules/word2vec/examples/eng_news-typical_2016_1M-sentences.txt", './node_modules/word2vec/examples/my_phrases.txt', {
 //     //         cbow: 1,
 //     //         size: 200,
@@ -131,7 +128,6 @@
 //     //         iter: 200,
 //     //         minCount: 2
 //     //     });
-//     //     console.log("phrased!!!");
 //     // }
 
 // }
diff --git a/src/server/downsize.ts b/src/server/downsize.ts
index cd0d83812..5cd709fa3 100644
--- a/src/server/downsize.ts
+++ b/src/server/downsize.ts
@@ -7,7 +7,7 @@ const jpgTypes = ["jpg", "JPG", "jpeg", "JPEG"];
 const smallResizer = sharp().resize(100);
 fs.readdir(folder, async (err, files) => {
     if (err) {
-        console.log(err);
+        console.log("readdir:" + err);
         return;
     }
     // files.forEach(file => {
-- 
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/util/InteractionUtils.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 ac3bc783a331d61037c5547cc7aee03ee40bf8f4 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 29 Jul 2020 09:57:40 -0400
Subject: removed InkOptionsMenu

---
 src/client/util/InteractionUtils.tsx               |  11 -
 src/client/views/DocumentDecorations.tsx           |   4 +-
 src/client/views/GestureOverlay.tsx                |   1 -
 .../collectionFreeForm/InkOptionsMenu.tsx          | 355 ---------------------
 4 files changed, 1 insertion(+), 370 deletions(-)
 delete mode 100644 src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx

(limited to 'src/client/util/InteractionUtils.tsx')

diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 3a7fd7626..04a750f93 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -171,17 +171,6 @@ export namespace InteractionUtils {
         </svg>);
     }
 
-    // export function makeArrow() {
-    //     return (
-    //         InkOptionsMenu.Instance.getColors().map(color => {
-    //             const id1 = "arrowStartTest" + color;
-    //             <marker id={id1} orient="auto" overflow="visible" refX="0" refY="1" markerWidth="10" markerHeight="7">
-    //                 <polygon points="0 0, 3 1, 0 2" fill={"#" + color} />
-    //             </marker>;
-    //         })
-    //     );
-    // }
-
     export function makePolygon(shape: string, points: { X: number, Y: number }[]) {
         if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y + 1 === points[0].Y) {
             //pointer is up (first and last points are the same)
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c5e0a3303..c0a35a32a 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -21,10 +21,8 @@ import e = require('express');
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { SnappingManager } from '../util/SnappingManager';
 import { HtmlField } from '../../fields/HtmlField';
-import { InkData, InkField, InkTool } from "../../fields/InkField";
+import { InkField } 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);
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 53bc01b3d..5bc1b902e 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -22,7 +22,6 @@ import { RadialMenu } from "./nodes/RadialMenu";
 import HorizontalPalette from "./Palette";
 import { Touchable } from "./Touchable";
 import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
-import InkOptionsMenu from "./collections/collectionFreeForm/InkOptionsMenu";
 import * as fitCurve from 'fit-curve';
 import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
 
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
deleted file mode 100644
index 80d1264ce..000000000
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ /dev/null
@@ -1,355 +0,0 @@
-import React = require("react");
-import AntimodeMenu from "../../AntimodeMenu";
-import { observer } from "mobx-react";
-import { observable, action, computed } from "mobx";
-import "./InkOptionsMenu.scss";
-import { ActiveInkColor, ActiveInkBezierApprox, ActiveFillColor, ActiveArrowStart, ActiveArrowEnd, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke";
-import { Scripting } from "../../../util/Scripting";
-import { InkTool } from "../../../../fields/InkField";
-import { ColorState } from "react-color";
-import { Utils } from "../../../../Utils";
-import GestureOverlay from "../../GestureOverlay";
-import { Doc } from "../../../../fields/Doc";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { DocumentView } from "../../../views/nodes/DocumentView";
-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, 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, faLongArrowAltRight, faArrowsAltH, faMinus, faCircle, faSquare, faSquare, faPenFancy, faAngleDoubleRight,);
-
-
-
-@observer
-export default class InkOptionsMenu extends AntimodeMenu {
-    static Instance: InkOptionsMenu;
-
-    private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""];
-    private _width = ["1", "5", "10", "100"];
-    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;
-
-    @observable private collapsed: boolean = false;
-    @observable _double = "";
-
-    @observable _colorBtn = false;
-    @observable _widthBtn = false;
-    @observable _fillBtn = false;
-    // @observable _arrowBtn = false;
-    // @observable _dashBtn = false;
-    // @observable _shapeBtn = false;
-
-
-
-    constructor(props: Readonly<{}>) {
-        super(props);
-        InkOptionsMenu.Instance = this;
-        this._canFade = false; // don't let the inking menu fade away
-        this.Pinned = BoolCast(Doc.UserDoc()["menuInkOptions-pinned"]);
-
-    }
-
-    @action
-    toggleMenuPin = (e: React.MouseEvent) => {
-        Doc.UserDoc()["menuInkOptions-pinned"] = this.Pinned = !this.Pinned;
-        if (!this.Pinned) {
-            // this.fadeOut(true);
-        }
-    }
-
-    @action
-    protected toggleCollapse = (e: React.MouseEvent) => {
-        this.collapsed = !this.collapsed;
-        setTimeout(() => {
-            const x = Math.min(this._left, window.innerWidth - InkOptionsMenu.Instance.width);
-            InkOptionsMenu.Instance.jumpTo(x, this._top, true);
-        }, 0);
-    }
-
-
-
-
-    getColors = () => {
-        return this._palette;
-    }
-
-    // @action
-    // changeArrow = (arrowStart: string, arrowEnd: string) => {
-    //     SetActiveArrowStart(arrowStart);
-    //     SetActiveArrowEnd(arrowEnd);
-    // }
-
-    @action
-    changeColor = (color: string, type: string) => {
-        const col: ColorState = {
-            hex: color, hsl: { a: 0, h: 0, s: 0, l: 0, source: "" }, hsv: { a: 0, h: 0, s: 0, v: 0, source: "" },
-            rgb: { a: 0, r: 0, b: 0, g: 0, source: "" }, oldHue: 0, source: "",
-        };
-        if (type === "color") {
-            SetActiveInkColor(Utils.colorString(col));
-        } else if (type === "fill") {
-            SetActiveFillColor(Utils.colorString(col));
-        }
-    }
-
-    @action
-    editProperties = (value: any, field: string) => {
-        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
-            const doc = Document(element.rootDoc);
-            if (doc.type === DocumentType.INK) {
-                switch (field) {
-                    case "width":
-                        doc.strokeWidth = Number(value);
-                        break;
-                    case "color":
-                        doc.color = String(value);
-                        break;
-                    case "fill":
-                        doc.fillColor = String(value);
-                        break;
-                    case "bezier":
-                        // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300;
-                        break;
-                    case "dash":
-                        doc.strokeDash = Number(value);
-                    default:
-                        break;
-                }
-            }
-        }));
-    }
-
-
-    @action
-    changeBezier = (e: React.PointerEvent): void => {
-        SetActiveBezierApprox(!ActiveInkBezierApprox() ? "300" : "");
-        this.editProperties(0, "bezier");
-    }
-    @action
-    changeDash = (e: React.PointerEvent): void => {
-        SetActiveDash(ActiveDash() === "0" ? "2" : "0");
-        this.editProperties(ActiveDash(), "strokeDash");
-    }
-
-    @computed get drawButtons() {
-        const drawButtons = <div className="btn-draw" key="draw">
-            {this._draw.map((icon, i) => {
-                return <button
-                    className="antimodeMenu-button"
-                    key={icon}
-                    title={this._title[i]}
-                    onPointerDown={action(() => {
-                        this._double = "";
-
-                        if (this._selected !== i) {
-                            this._selected = i;
-                            Doc.SetSelectedTool(InkTool.Pen);
-                            SetActiveArrowStart(this._head[i]);
-                            SetActiveArrowEnd(this._end[i]);
-                            SetActiveBezierApprox("300");
-
-                            GestureOverlay.Instance.InkShape = this._shape[i];
-                        } else {
-                            this._selected = this._shapesNum;
-                            Doc.SetSelectedTool(InkTool.None);
-                            SetActiveArrowStart("");
-                            SetActiveArrowEnd("");
-                            GestureOverlay.Instance.InkShape = "";
-                            SetActiveBezierApprox("0");
-
-                        }
-                        console.log(this._selected);
-
-                    })}
-                    onDoubleClick={action(() => {
-                        console.log("double");
-                        this._double = this._draw[i];
-                        if (this._selected !== i) {
-                            this._selected = i;
-                            Doc.SetSelectedTool(InkTool.Pen);
-                            SetActiveArrowStart(this._head[i]);
-                            SetActiveArrowEnd(this._end[i]);
-                            SetActiveBezierApprox("300");
-
-                            GestureOverlay.Instance.InkShape = this._shape[i];
-                        } else {
-                            this._selected = this._shapesNum;
-                            Doc.SetSelectedTool(InkTool.None);
-                            SetActiveArrowStart("");
-                            SetActiveArrowEnd("");
-                            GestureOverlay.Instance.InkShape = "";
-                            SetActiveBezierApprox("0");
-
-                        }
-
-
-
-                    })}
-                    style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}>
-                    <FontAwesomeIcon icon={this._faName[i] as IconProp} size="sm" />
-
-                </button>;
-            })}</div>;
-        return drawButtons;
-    }
-
-
-    @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" />
-        </button>;
-        if (this._widthBtn) {
-            widthPicker = <div className="btn2-group" key="width">
-                {widthPicker}
-                {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, fontSize: this._dotsize[i], padding: 0, textAlign: "center" }}>
-                        •
-                    </button>;
-                })}
-            </div>;
-        }
-        return widthPicker;
-    }
-
-
-
-    @computed get colorPicker() {
-        var colorPicker = <button
-            className="antimodeMenu-button"
-            key="color"
-            title="Change Ink Color"
-            onPointerDown={action(e => this._colorBtn = !this._colorBtn)}
-            style={{ backgroundColor: this._colorBtn ? "121212" : "" }}>
-            <FontAwesomeIcon icon="pen-nib" size="lg" />
-            <div className="color-previewI" style={{ backgroundColor: ActiveInkColor() ?? "121212" }}></div>
-
-        </button>;
-        if (this._colorBtn) {
-            colorPicker = <div className="btn-group" key="color">
-                {colorPicker}
-                {this._palette.map(color => {
-                    return <button
-                        className="antimodeMenu-button"
-                        key={color}
-                        onPointerDown={action(() => { this.changeColor(color, "color"); this._colorBtn = false; this.editProperties(color, "color"); })}
-                        style={{ backgroundColor: this._colorBtn ? "121212" : "", zIndex: 1001 }}>
-                        {/* <FontAwesomeIcon icon="pen-nib" size="lg" /> */}
-                        <div className="color-previewII" style={{ backgroundColor: color }}></div>
-                    </button>;
-                })}
-            </div>;
-        }
-        return colorPicker;
-    }
-    @computed get formatPane() {
-        return <button className="antimodeMenu-button" key="format"
-            title="toggle foramatting pane"
-            onPointerDown={action(e => FormatShapePane.Instance.Pinned = !FormatShapePane.Instance.Pinned)}
-            style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
-            <FontAwesomeIcon icon="angle-double-right" size="lg" />
-        </button>;
-    }
-
-    @computed get fillPicker() {
-        var fillPicker = <button
-            className="antimodeMenu-button"
-            key="fill"
-            title="Change Fill Color"
-            onPointerDown={action(e => this._fillBtn = !this._fillBtn)}
-            style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
-            <FontAwesomeIcon icon="fill-drip" size="lg" />
-            <div className="color-previewI" style={{ backgroundColor: ActiveFillColor() ?? "121212" }}></div>
-        </button>;
-        if (this._fillBtn) {
-            fillPicker = <div className="btn-group" key="fill" >
-                {fillPicker}
-                {this._palette.map(color => {
-                    return <button
-                        className="antimodeMenu-button"
-                        key={color}
-                        onPointerDown={action(() => { this.changeColor(color, "fill"); this._fillBtn = false; this.editProperties(color, "fill"); })}
-                        style={{ backgroundColor: this._fillBtn ? "121212" : "", zIndex: 1001 }}>
-                        <div className="color-previewII" style={{ backgroundColor: color }}></div>
-                    </button>;
-                })}
-
-            </div>;
-        }
-        return fillPicker;
-    }
-
-
-    @computed get bezierButton() {
-        return <button
-            className="antimodeMenu-button"
-            title="Bezier changer"
-            key="bezier"
-            onPointerDown={e => this.changeBezier(e)}
-            style={{ backgroundColor: ActiveInkBezierApprox() ? "121212" : "" }}>
-            <FontAwesomeIcon icon="bezier-curve" size="lg" />
-
-        </button>;
-    }
-
-    @computed get dashButton() {
-        return <button
-            className="antimodeMenu-button"
-            title="dash changer"
-            key="dash"
-            onPointerDown={e => this.changeDash(e)}
-            style={{ backgroundColor: ActiveDash() !== "0" ? "121212" : "" }}>
-            <FontAwesomeIcon icon="ellipsis-h" size="lg" />
-
-        </button>;
-    }
-
-    render() {
-        const buttons = [
-
-            this.drawButtons,
-            this.widthPicker,
-            this.colorPicker,
-            this.fillPicker,
-
-
-            this.formatPane,
-
-            <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>
-        ];
-
-        // return this.getElement(buttons);
-        return this.getElement(buttons);
-    }
-}
-Scripting.addGlobal(function activatePen(penBtn: any) {
-    if (penBtn) {
-        InkOptionsMenu.Instance.jumpTo(300, 300);
-        InkOptionsMenu.Instance.Pinned = true;
-    } else {
-        InkOptionsMenu.Instance.Pinned = false;
-        InkOptionsMenu.Instance.fadeOut(true);
-    }
-});
-- 
cgit v1.2.3-70-g09d2

