aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorgeireann <60007097+geireann@users.noreply.github.com>2020-07-21 15:02:02 +0800
committergeireann <60007097+geireann@users.noreply.github.com>2020-07-21 15:02:02 +0800
commitf82682f6136ae61902b807c5e52a14c69bcc64ff (patch)
treed7466124d28e0551cd92643cf5cc9cf919bb01ff /src/client/views/collections
parentad6762c369fd0933326579707ecbc34fda42ab6c (diff)
parentd21ef189f2c160d3d80a5cf7d824c314262a59ac (diff)
merge with master
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx5
-rw-r--r--src/client/views/collections/CollectionMenu.scss133
-rw-r--r--src/client/views/collections/CollectionMenu.tsx203
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss83
-rw-r--r--src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx194
6 files changed, 269 insertions, 353 deletions
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index be1ef56d0..53b2d5254 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -829,6 +829,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
@computed get miniTop() { return 50 + (NumCast(this._document?._panY) - this.renderContentBounds.cy) / this.renderContentBounds.dim * 100 - this.miniHeight / 2; }
@computed get miniWidth() { return this.panelWidth() / NumCast(this._document?._viewScale, 1) / this.renderContentBounds.dim * 100; }
@computed get miniHeight() { return this.panelHeight() / NumCast(this._document?._viewScale, 1) / this.renderContentBounds.dim * 100; }
+ childLayoutTemplate = () => Cast(this._document?.childLayoutTemplate, Doc, null);
returnMiniSize = () => NumCast(this._document?._miniMapSize, 150);
miniDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
@@ -848,6 +849,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
CollectionView={undefined}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
+ ChildLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid havin to set stuff like this.
+ noOverlay={true} // don't render overlay Docs since they won't scale
active={returnTrue}
select={emptyFunction}
dropAction={undefined}
@@ -916,7 +919,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
docFilters={returnEmptyFilter}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined} />
- {document._viewType === CollectionViewType.Freeform ? this.renderMiniMap() : (null)}
+ {document._viewType === CollectionViewType.Freeform && !this._document?.hideMinimap ? this.renderMiniMap() : (null)}
</>;
}
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 929c22c35..7201afcc0 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -2,24 +2,25 @@
.collectionMenu-cont {
- position:relative;
- display:inline-flex;
+ position: relative;
+ display: inline-flex;
width: 100%;
opacity: 0.9;
z-index: 9001;
transition: top .5s;
- background: #121721;
+ background: #323232;
color: white;
transform-origin: top left;
top: 0;
- width:100%;
+ width: 100%;
.antimodeMenu-button {
- padding:0;
- width:40px;
+ padding: 0;
+ width: 30px;
display: flex;
+
svg {
- margin:auto;
+ margin: auto;
}
}
@@ -37,13 +38,11 @@
.collectionViewBaseChrome-viewPicker {
font-size: 75%;
- //text-transform: uppercase;
- //letter-spacing: 2px;
- background: #121721;
- color: white;
+ background: #323232;
outline-color: black;
+ color: white;
border: none;
- //padding: 12px 10px 11px 10px;
+ border-right: solid gray 1px;
}
.collectionViewBaseChrome-viewPicker:active {
@@ -66,14 +65,15 @@
margin-left: 3px;
margin-right: 0px;
font-size: 75%;
- background: #121721;
- border: none;
+ background: #323232;
color: white;
+ border: none;
+ border-right: solid gray 1px;
}
.commandEntry-outerDiv {
pointer-events: all;
- background-color: #121721;
+ background-color: #323232;
display: flex;
flex-direction: row;
height: 30px;
@@ -89,7 +89,7 @@
.collectionViewBaseChrome-collapse {
transition: all .5s, opacity 0.3s;
position: absolute;
- width: 40px;
+ width: 30px;
transform-origin: top left;
pointer-events: all;
// margin-top: 10px;
@@ -109,20 +109,25 @@
margin-top: auto;
margin-bottom: auto;
}
+
.collectionViewBaseChrome-viewSpecs {
margin-left: 5px;
display: grid;
+ border: none;
+ border-right: solid gray 1px;
.collectionViewBaseChrome-filterIcon {
position: relative;
display: flex;
margin: auto;
- background: #121721;
+ background: #323232;
color: white;
width: 30px;
height: 30px;
align-items: center;
justify-content: center;
+ border: none;
+ border-right: solid gray 1px;
}
.collectionViewBaseChrome-viewSpecsInput {
@@ -201,8 +206,9 @@
background: #121721;
color: white;
outline-color: black;
+ color: white;
border: none;
- //padding: 12px 10px 11px 10px;
+ border-right: solid gray 1px;
}
.collectionGridViewChrome-viewPicker:active {
@@ -306,49 +312,76 @@
}
.collectionFreeFormMenu-cont {
- width: 60px;
- display: flex;
+ display: inline-flex;
position: relative;
align-items: center;
- .fwdKeyframe,
-.numKeyframe,
-.backKeyframe {
- cursor: pointer;
- position: absolute;
- width: 20;
- height: 30;
- bottom: 0;
- background: #121721;
- display: flex;
- align-items: center;
- color: white;
-}
+ .antimodeMenu-button {
+ text-align: center;
+ display: block;
+ }
+
+ .color-previewI {
+ width: 80%;
+ height: 20%;
+ bottom: 0;
+ position: absolute;
+ }
-.backKeyframe {
- left: 0;
+ .color-previewII {
+ width: 80%;
+ height: 80%;
+ margin-left: 10%;
+ }
- svg {
- display: block;
+ .btn-group {
+ display: grid;
+ grid-template-columns: auto auto auto auto;
margin: auto;
+ /* Make the buttons appear below each other */
}
-}
-.numKeyframe {
- left: 20;
- display: flex;
- flex-direction: column;
- padding: 5px;
-}
+ .btn-draw {
+ display: inline-flex;
+ margin: auto;
+ /* Make the buttons appear below each other */
+ }
-.fwdKeyframe {
- left: 40;
+ .fwdKeyframe,
+ .numKeyframe,
+ .backKeyframe {
+ cursor: pointer;
+ position: relative;
+ width: 20;
+ height: 30;
+ bottom: 0;
+ background: #323232;
+ display: inline-flex;
+ align-items: center;
+ color: white;
+ }
- svg {
- display: block;
- margin: auto;
+ .backKeyframe {
+ svg {
+ display: block;
+ margin: auto;
+ }
+ }
+
+
+ .numKeyframe {
+ flex-direction: column;
+ padding-top: 5px;
+ }
+
+ .fwdKeyframe {
+ svg {
+ display: block;
+ margin: auto;
+ }
+
+ border-right: solid gray 1px;
}
-}
}
.collectionSchemaViewChrome-cont {
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index cdd653823..2be57b6d2 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,5 +1,5 @@
import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome";
import { action, computed, observable, reaction, runInAction, Lambda } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast, Opt } from "../../../fields/Doc";
@@ -15,6 +15,15 @@ import { List } from "../../../fields/List";
import { EditableView } from "../EditableView";
import { Id } from "../../../fields/FieldSymbols";
import { listSpec } from "../../../fields/Schema";
+import FormatShapePane from "./collectionFreeForm/FormatShapePane";
+import { ActiveFillColor, SetActiveInkWidth, ActiveInkColor, SetActiveBezierApprox, SetActiveArrowEnd, SetActiveArrowStart, SetActiveFillColor, SetActiveInkColor } from "../InkingStroke";
+import GestureOverlay from "../GestureOverlay";
+import { InkTool } from "../../../fields/InkField";
+import { DocumentType } from "../../documents/DocumentTypes";
+import { Document } from "../../../fields/documentSchemas";
+import { SelectionManager } from "../../util/SelectionManager";
+import { DocumentView } from "../nodes/DocumentView";
+import { ColorState } from "react-color";
@observer
export default class CollectionMenu extends AntimodeMenu {
@@ -62,37 +71,37 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
get target() { return this.props.CollectionView.props.Document; }
_templateCommand = {
- params: ["target", "source"], title: "=> item view",
- script: "this.target.childLayout = getDocTemplate(this.source?.[0])",
- immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayout = Doc.getDocTemplate(source?.[0]))),
+ params: ["target", "source"], title: "item view",
+ script: "this.target.childLayoutTemplate = getDocTemplate(this.source?.[0])",
+ immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayoutTemplate = Doc.getDocTemplate(source?.[0]))),
initialize: emptyFunction,
};
_narrativeCommand = {
- params: ["target", "source"], title: "=> child click view",
+ params: ["target", "source"], title: "child click view",
script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])",
immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))),
initialize: emptyFunction,
};
_contentCommand = {
- params: ["target", "source"], title: "=> clear content",
+ params: ["target", "source"], title: "clear content",
script: "getProto(this.target).data = copyField(this.source);",
immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List<Doc>(source)), // Doc.aliasDocs(source),
initialize: emptyFunction,
};
_viewCommand = {
- params: ["target"], title: "=> reset view",
- script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;",
- immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target.scale = 1; }),
- initialize: (button: Doc) => { button.restoredPanX = this.target._panX; button.restoredPanY = this.target._panY; button.restoredScale = this.target.scale; },
+ params: ["target"], title: "bookmark view",
+ script: "this.target._panX = this['target-panX']; this.target._panY = this['target-panY']; this.target._viewScale = this['target-viewScale'];",
+ immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; }),
+ initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; },
};
_clusterCommand = {
- params: ["target"], title: "=> fit content",
+ params: ["target"], title: "fit content",
script: "this.target._fitToBox = !this.target._fitToBox;",
immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox),
initialize: emptyFunction
};
_fitContentCommand = {
- params: ["target"], title: "=> toggle clusters",
+ params: ["target"], title: "toggle clusters",
script: "this.target.useClusters = !this.target.useClusters;",
immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters),
initialize: emptyFunction
@@ -211,9 +220,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
@computed get templateChrome() {
return <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} >
<div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
- <div className="commandEntry-drop">
- <FontAwesomeIcon icon="bullseye" size="2x" />
- </div>
+ <button className={"antimodeMenu-button"} >
+ <FontAwesomeIcon icon="bullseye" size="lg" />
+ </button>
<select
className="collectionViewBaseChrome-cmdPicker" onPointerDown={stopPropagation} onChange={this.commandChanged} value={this._currentKey}>
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={"empty"} value={""} />
@@ -228,9 +237,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
@computed get viewModes() {
return <div className="collectionViewBaseChrome-viewModes" >
<div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._viewRef} onPointerDown={this.dragViewDown}>
- <div className="commandEntry-drop">
- <FontAwesomeIcon icon="bullseye" size="2x" />
- </div>
+ <button className={"antimodeMenu-button"}>
+ <FontAwesomeIcon icon="bullseye" size="lg" />
+ </button>
<select
className="collectionViewBaseChrome-viewPicker"
onPointerDown={stopPropagation}
@@ -256,12 +265,12 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
<div className="collectionMenu">
<div className="collectionViewBaseChrome">
{this.viewModes}
+ {this.templateChrome}
<div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: "grid" }}>
- <div className="collectionViewBaseChrome-filterIcon" onPointerDown={this.toggleViewSpecs} >
- <FontAwesomeIcon icon="filter" size="2x" />
- </div>
+ <button className={"antimodeMenu-button"} onClick={this.toggleViewSpecs} >
+ <FontAwesomeIcon icon="filter" size="lg" />
+ </button>
</div>
- {this.templateChrome}
</div>
{this.subChrome}
</div>
@@ -272,7 +281,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
@observer
export class CollectionFreeFormViewChrome extends React.Component<CollectionMenuProps> {
-
+ public static Instance: CollectionFreeFormViewChrome;
+ constructor(props: any) {
+ super(props);
+ CollectionFreeFormViewChrome.Instance = this;
+ }
get Document() { return this.props.CollectionView.props.Document; }
@computed get dataField() {
return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)];
@@ -303,6 +316,144 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1);
}
+ private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""];
+ private _width = ["1", "5", "10", "100"];
+ private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"];
+ private _head = ["", "", "arrow", "", "", "arrow", "", "", ""];
+ private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""];
+ private _shape = ["line", "line", "line", "", "", "", "rectangle", "circle", "triangle"];
+
+ @observable _shapesNum = this._shape.length;
+ @observable _selected = this._shapesNum;
+
+ @observable _keepMode = false;
+
+ @observable _colorBtn = false;
+ @observable _widthBtn = false;
+ @observable _fillBtn = false;
+
+ @action
+ clearKeep() { this._selected = this._shapesNum; }
+
+ @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 "dash": doc.strokeDash = value;
+ }
+ }
+ }));
+ }
+
+ @computed get drawButtons() {
+ const func = action((i: number, keep: boolean) => {
+ this._keepMode = keep;
+ 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");
+ }
+ });
+ return <div className="btn-draw" key="draw">
+ {this._draw.map((icon, i) =>
+ <button className="antimodeMenu-button" key={icon} onPointerDown={() => func(i, false)} onDoubleClick={() => func(i, true)}
+ style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}>
+ {this._draw[i]}
+ </button>)}
+ </div>;
+ }
+
+ toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps["icon"], ele: JSX.Element | null) => {
+ return <button className="antimodeMenu-button" key={key} title={key}
+ onPointerDown={action(e => setter())}
+ style={{ backgroundColor: value ? "121212" : "" }}>
+ <FontAwesomeIcon icon={icon} size="lg" />
+ {ele}
+ </button>;
+ }
+
+ @computed get widthPicker() {
+ var widthPicker = this.toggleButton("stroke width", this._widthBtn, () => this._widthBtn = !this._widthBtn, "bars", null);
+ return !this._widthBtn ? widthPicker :
+ <div className="btn2-group" key="width">
+ {widthPicker}
+ {this._width.map(wid =>
+ <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}
+ </button>)}
+ </div>;
+ }
+
+ @computed get colorPicker() {
+ var colorPicker = this.toggleButton("stroke color", this._colorBtn, () => this._colorBtn = !this._colorBtn, "pen-nib",
+ <div className="color-previewI" style={{ backgroundColor: ActiveInkColor() ?? "121212" }} />);
+ return !this._colorBtn ? colorPicker :
+ <div className="btn-group" key="color">
+ {colorPicker}
+ {this._palette.map(color =>
+ <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 }} />
+ </button>)}
+ </div>;
+ }
+ @computed get fillPicker() {
+ var fillPicker = this.toggleButton("shape fill color", this._fillBtn, () => this._fillBtn = !this._fillBtn, "fill-drip",
+ <div className="color-previewI" style={{ backgroundColor: ActiveFillColor() ?? "121212" }} />);
+ return !this._fillBtn ? fillPicker :
+ <div className="btn-group" key="fill" >
+ {fillPicker}
+ {this._palette.map(color =>
+ <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>;
+ }
+
+ @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="chevron-right" size="lg" />
+ </button>;
+ }
+
render() {
return this.Document.isAnnotationOverlay ? (null) :
<div className="collectionFreeFormMenu-cont">
@@ -316,6 +467,12 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
<div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
<FontAwesomeIcon icon={"caret-right"} size={"lg"} />
</div>
+
+ {this.widthPicker}
+ {this.colorPicker}
+ {this.fillPicker}
+ {this.drawButtons}
+ {this.formatPane}
</div>;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 953b218b2..38a050d55 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1526,10 +1526,10 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
</marker>
<marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
orient="auto" overflow="visible">
- <rect width="3" height="3" fill="#69a6db" />
+ <rect x="1" y="1" width="5" height="5" fill="#69a6db" />
</marker>
- <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="3"
+ <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="7"
orient="auto" overflow="visible">
<path d="M2,2 L2,13 L8,7 L2,2" fill="#69a6db" />
</marker>
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
deleted file mode 100644
index 03c6c97ab..000000000
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss
+++ /dev/null
@@ -1,83 +0,0 @@
-.antimodeMenu-button {
- .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-draw {
- display: inline;
- /* Make the buttons appear below each other */
-}
-
-.btn2-group {
- display: grid;
- background: #323232;
- grid-template-columns: auto;
-
- /* Make the buttons appear below each other */
- .antimodeMenu-button {
- background: #323232;
- display: block;
-
- }
-}
-
-@media only screen and (max-device-width: 480px) {
- .antimodeMenu-button {
- font-size: 50%;
-
- .color-preview {
- width: 100%;
- height: 100%;
- }
-
- }
-
- .sketch-picker {
- background: #323232;
-
- .flexbox-fit {
- background: #323232;
- }
- }
-
- .btn-group {
- display: grid;
- grid-template-columns: auto auto;
- /* Make the buttons appear below each other */
- }
-
- .btn2-group {
- display: block;
- background: #323232;
- grid-template-columns: auto;
-
- /* Make the buttons appear below each other */
- .antimodeMenu-button {
- background: #323232;
- display: block;
- font-size: 50%;
- }
- }
-} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
deleted file mode 100644
index 23e1c194a..000000000
--- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx
+++ /dev/null
@@ -1,194 +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, ActiveFillColor, 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, FontAwesomeIconProps } from "@fortawesome/react-fontawesome";
-import { BoolCast } from "../../../../fields/Types";
-import FormatShapePane from "./FormatShapePane";
-
-@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 _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"];
- private _head = ["", "", "arrow", "", "", "arrow", "", "", ""];
- private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""];
- private _shape = ["line", "line", "line", "", "", "", "rectangle", "circle", "triangle"];
-
- @observable _shapesNum = this._shape.length;
- @observable _selected = this._shapesNum;
-
- @observable _collapsed = false;
- @observable _keepMode = false;
-
- @observable _colorBtn = false;
- @observable _widthBtn = false;
- @observable _fillBtn = 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;
- }
-
- @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 "dash": doc.strokeDash = value;
- }
- }
- }));
- }
-
- @computed get drawButtons() {
- const func = action((i: number, keep: boolean) => {
- this._keepMode = keep;
- 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");
- }
- });
- return <div className="btn-draw" key="draw">
- {this._draw.map((icon, i) =>
- <button className="antimodeMenu-button" key={icon} onPointerDown={() => func(i, false)} onDoubleClick={() => func(i, true)}
- style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}>
- {this._draw[i]}
- </button>)}
- </div>;
- }
-
- toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps["icon"], ele: JSX.Element | null) => {
- return <button className="antimodeMenu-button" key={key} title={key}
- onPointerDown={action(e => setter())}
- style={{ backgroundColor: value ? "121212" : "" }}>
- <FontAwesomeIcon icon={icon} size="lg" />
- {ele}
- </button>;
- }
-
- @computed get widthPicker() {
- var widthPicker = this.toggleButton("stroke width", this._widthBtn, () => this._widthBtn = !this._widthBtn, "bars", null);
- return !this._widthBtn ? widthPicker :
- <div className="btn2-group" key="width">
- {widthPicker}
- {this._width.map(wid =>
- <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}
- </button>)}
- </div>;
- }
-
- @computed get colorPicker() {
- var colorPicker = this.toggleButton("stroke color", this._colorBtn, () => this._colorBtn = !this._colorBtn, "pen-nib",
- <div className="color-previewI" style={{ backgroundColor: ActiveInkColor() ?? "121212" }} />);
- return !this._colorBtn ? colorPicker :
- <div className="btn-group" key="color">
- {colorPicker}
- {this._palette.map(color =>
- <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 }} />
- </button>)}
- </div>;
- }
- @computed get fillPicker() {
- var fillPicker = this.toggleButton("shape fill color", this._fillBtn, () => this._fillBtn = !this._fillBtn, "fill-drip",
- <div className="color-previewI" style={{ backgroundColor: ActiveFillColor() ?? "121212" }} />);
- return !this._fillBtn ? fillPicker :
- <div className="btn-group" key="fill" >
- {fillPicker}
- {this._palette.map(color =>
- <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>;
- }
-
- @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="chevron-right" size="lg" />
- </button>;
- }
-
- render() {
- return this.getElement([
- this.widthPicker,
- this.colorPicker,
- this.fillPicker,
- this.drawButtons,
- 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>
- ]);
- }
-}
-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);
- }
-});