aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/ClientRecommender.scss2
-rw-r--r--src/client/documents/Documents.ts2
-rw-r--r--src/client/util/CaptureManager.scss2
-rw-r--r--src/client/util/CurrentUserUtils.ts16
-rw-r--r--src/client/util/DragManager.ts2
-rw-r--r--src/client/util/InteractionUtils.tsx2
-rw-r--r--src/client/util/SettingsManager.scss4
-rw-r--r--src/client/views/AntimodeMenu.scss4
-rw-r--r--src/client/views/ContextMenu.scss20
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/DocumentButtonBar.scss16
-rw-r--r--src/client/views/DocumentDecorations.scss28
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/client/views/GlobalKeyHandler.ts2
-rw-r--r--src/client/views/InkControls.tsx135
-rw-r--r--src/client/views/InkHandles.tsx122
-rw-r--r--src/client/views/InkStroke.scss11
-rw-r--r--src/client/views/InkStrokeProperties.ts369
-rw-r--r--src/client/views/InkingStroke.scss11
-rw-r--r--src/client/views/InkingStroke.tsx219
-rw-r--r--src/client/views/Main.scss6
-rw-r--r--src/client/views/MainView.scss60
-rw-r--r--src/client/views/MainView.tsx6
-rw-r--r--src/client/views/PropertiesButtons.scss16
-rw-r--r--src/client/views/PropertiesView.tsx4
-rw-r--r--src/client/views/StyleProvider.tsx31
-rw-r--r--src/client/views/TemplateMenu.scss6
-rw-r--r--src/client/views/_nodeModuleOverrides.scss2
-rw-r--r--src/client/views/animationtimeline/Keyframe.scss10
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx2
-rw-r--r--src/client/views/animationtimeline/Timeline.scss6
-rw-r--r--src/client/views/animationtimeline/TimelineMenu.scss10
-rw-r--r--src/client/views/animationtimeline/TimelineOverview.scss2
-rw-r--r--src/client/views/animationtimeline/Track.scss6
-rw-r--r--src/client/views/collections/CollectionDockingView.scss16
-rw-r--r--src/client/views/collections/CollectionLinearView.scss12
-rw-r--r--src/client/views/collections/CollectionMenu.scss143
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx8
-rw-r--r--src/client/views/collections/CollectionStackingView.scss14
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.scss8
-rw-r--r--src/client/views/collections/CollectionView.scss4
-rw-r--r--src/client/views/collections/TreeView.scss6
-rw-r--r--src/client/views/collections/TreeView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx2
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.scss22
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx10
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTable.tsx2
-rw-r--r--src/client/views/global/globalCssVariables.scss (renamed from src/client/views/globalCssVariables.scss)49
-rw-r--r--src/client/views/global/globalCssVariables.scss.d.ts (renamed from src/client/views/globalCssVariables.scss.d.ts)0
-rw-r--r--src/client/views/global/globalEnums.tsx34
-rw-r--r--src/client/views/linking/LinkEditor.scss14
-rw-r--r--src/client/views/linking/LinkMenu.scss2
-rw-r--r--src/client/views/linking/LinkMenuItem.scss12
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx11
-rw-r--r--src/client/views/nodes/DocumentLinksButton.scss4
-rw-r--r--src/client/views/nodes/DocumentView.scss6
-rw-r--r--src/client/views/nodes/FontIconBox.scss13
-rw-r--r--src/client/views/nodes/KeyValueBox.scss20
-rw-r--r--src/client/views/nodes/KeyValuePair.scss2
-rw-r--r--src/client/views/nodes/PDFBox.scss5
-rw-r--r--src/client/views/nodes/PresBox.scss142
-rw-r--r--src/client/views/nodes/RadialMenu.scss4
-rw-r--r--src/client/views/nodes/WebBox.scss3
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss8
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx11
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.scss4
-rw-r--r--src/client/views/nodes/formattedText/TooltipTextMenu.scss10
-rw-r--r--src/client/views/search/CheckBox.scss6
-rw-r--r--src/client/views/search/CollectionFilters.scss2
-rw-r--r--src/client/views/search/IconBar.scss2
-rw-r--r--src/client/views/search/IconButton.scss6
-rw-r--r--src/client/views/search/IconButton.tsx4
-rw-r--r--src/client/views/search/NaviconButton.scss4
-rw-r--r--src/client/views/search/SearchBox.scss10
-rw-r--r--src/client/views/search/SelectorContextMenu.scss6
-rw-r--r--src/client/views/search/ToggleBar.scss8
-rw-r--r--src/client/views/webcam/DashWebRTCVideo.scss2
-rw-r--r--src/fields/Doc.ts24
-rw-r--r--src/fields/InkField.ts31
-rw-r--r--src/mobile/AudioUpload.scss2
-rw-r--r--src/mobile/ImageUpload.scss2
-rw-r--r--src/mobile/ImageUpload.tsx2
-rw-r--r--src/server/DashSession/Session/agents/server_worker.ts8
87 files changed, 1140 insertions, 738 deletions
diff --git a/src/client/ClientRecommender.scss b/src/client/ClientRecommender.scss
index 3f9102f15..178c7fdab 100644
--- a/src/client/ClientRecommender.scss
+++ b/src/client/ClientRecommender.scss
@@ -1,4 +1,4 @@
-// @import "/views/globalCssVariables.scss";
+// @import "/views/global/globalCssVariables.scss";
.space{
border: 1px dashed blue;
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 040571b10..c2cdf7f72 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -30,7 +30,7 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie
import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
import { ContextMenu } from "../views/ContextMenu";
import { ContextMenuProps } from "../views/ContextMenuItem";
-import { DFLT_IMAGE_NATIVE_DIM } from "../views/globalCssVariables.scss";
+import { DFLT_IMAGE_NATIVE_DIM } from "../views/global/globalCssVariables.scss";
import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, InkingStroke } from "../views/InkingStroke";
import { AudioBox } from "../views/nodes/AudioBox";
import { ColorBox } from "../views/nodes/ColorBox";
diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss
index 71539ee1e..a5024247e 100644
--- a/src/client/util/CaptureManager.scss
+++ b/src/client/util/CaptureManager.scss
@@ -1,4 +1,4 @@
-@import "../views/globalCssVariables";
+@import "../views/global/globalCssVariables";
.capture-interface {
//background-color: whitesmoke !important;
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 5bab827d5..22504f102 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -405,14 +405,18 @@ export class CurrentUserUtils {
selection: { type: "text", anchor: 1, head: 1 },
storedMarks: []
};
- const headerTemplate = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { title: "header", version: headerViewVersion, target: doc, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _autoHeight: true, system: true, cloneFieldFilter: new List<string>(["system"]) }, "header"); // text needs to be a space to allow templateText to be created
+ const headerTemplate = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), {
+ title: "text", version: headerViewVersion, target: doc, _height: 70, _headerPointerEvents: "all",
+ _headerHeight: 12, _headerFontSize: 9, _autoHeight: true, system: true, _fitWidth: true,
+ cloneFieldFilter: new List<string>(["system"])
+ }, "header");
const headerBtnHgt = 10;
headerTemplate[DataSym].layout =
- "<div style='height:100%'>" +
- ` <FormattedTextBox {...props} fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._headerHeight}px)'/>` +
- " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._headerFontSize}px' height='{this._headerHeight||1}px' background={this._headerColor ||this.target.mySharedDocs.userColor||'lightGray'} />" +
- ` <HTMLdiv fontSize='${headerBtnHgt - 1}' onClick={‘(this._headerHeight=Math.min(Math.max(1,this._height-30),this._headerHeight===1?50:1)) && (this._autoHeightMargins=this._headerHeight+${headerBtnHgt})’} height='${headerBtnHgt}px' background='yellow' >Metadata</HTMLdiv>` +
- "</div>";
+ "<HTMLdiv transformOrigin='top left' width='{100/scale}%' height='{100/scale}%' transform='scale({scale})'>" +
+ ` <FormattedTextBox {...props} dontScale='true' fieldKey={'text'} height='calc(100% - ${headerBtnHgt}px - {this._headerHeight}px)'/>` +
+ " <FormattedTextBox {...props} dontScale='true' fieldKey={'header'} dontSelectOnLoad='true' ignoreAutoHeight='true' fontSize='{this._headerFontSize}px' height='{(this._headerHeight||1)}px' background='{this._headerColor ||this.target.mySharedDocs.userColor||`lightGray`}' />" +
+ ` <HTMLdiv fontSize='${headerBtnHgt - 1}px' height='${headerBtnHgt}px' background='yellow' onClick={‘(this._headerHeight=scale*Math.min(Math.max(1,this._height-30),this._headerHeight===1?50:1)) && (this._autoHeightMargins=this._headerHeight+${headerBtnHgt})’} >Metadata</HTMLdiv>` +
+ "</HTMLdiv>";
// "<div style={'height:100%'}>" +
// " <FormattedTextBox {...props} fieldKey={'header'} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} pointerEvents='{this._headerPointerEvents||`none`}' fontSize='{this._headerFontSize}px' height='{this._headerHeight}px' background='{this._headerColor||this.target.mySharedDocs.userColor}' />" +
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 88bf6f36d..07b2b7dff 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -9,7 +9,7 @@ import { ScriptField } from "../../fields/ScriptField";
import { Cast, NumCast, ScriptCast, StrCast } from "../../fields/Types";
import { emptyFunction, returnTrue } from "../../Utils";
import { Docs, DocUtils } from "../documents/Documents";
-import * as globalCssVariables from "../views/globalCssVariables.scss";
+import * as globalCssVariables from "../views/global/globalCssVariables.scss";
import { UndoManager } from "./UndoManager";
import { SnappingManager } from "./SnappingManager";
import { DocumentView } from "../views/nodes/DocumentView";
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 01d00db30..ba935e3bf 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -208,7 +208,7 @@ export namespace InteractionUtils {
<polyline
points={strpts}
style={{
- filter: drawHalo ? "url(#inkSelectionHalo)" : undefined,
+ // filter: drawHalo ? "url(#inkSelectionHalo)" : undefined,
fill: fill ? fill : "none",
opacity: strokeWidth !== width ? 0.5 : undefined,
pointerEvents: pevents as any,
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index d8342ea56..c9db94419 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -1,4 +1,4 @@
-@import "../views/globalCssVariables";
+@import "../views/global/globalCssVariables";
.settings-interface {
//background-color: whitesmoke !important;
@@ -264,7 +264,7 @@
//margin-top: 4px;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
}
}
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index a275901be..2bac03af4 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -1,11 +1,11 @@
-@import "./globalCssVariables";
+@import "./global/globalCssVariables";
.antimodeMenu-cont {
position: absolute;
z-index: 10001;
height: $antimodemenu-height;
- background: #323232;
+ background: $dark-gray;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
// border-radius: 0px 6px 6px 6px;
z-index: 1001;
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index b514de5f2..795529780 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -1,10 +1,10 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
.contextMenu-cont {
position: absolute;
display: flex;
z-index: $contextMenu-zindex;
- box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+ box-shadow: $medium-gray 0.2vw 0.2vw 0.4vw;
flex-direction: column;
background: whitesmoke;
padding-top: 10px;
@@ -14,17 +14,17 @@
}
// .contextMenu-item:first-child {
-// background: $intermediate-color;
-// color: $light-color;
+// background: $medium-gray;
+// color: $white;
// }
// .contextMenu-item:first-child::placeholder {
-// color: $light-color;
+// color: $white;
// }
// .contextMenu-item:first-child:hover {
-// background: $intermediate-color;
-// color: $light-color;
+// background: $medium-gray;
+// color: $white;
// }
.contextMenu-subMenu-cont {
@@ -94,7 +94,7 @@
.contextMenu-item:hover {
border-width: .11px;
border-style: none;
- border-color: $intermediate-color; // rgb(187, 186, 186);
+ border-color: $medium-gray; // rgb(187, 186, 186);
border-bottom-style: solid;
border-top-style: solid;
@@ -122,7 +122,7 @@
transition: all .1s;
border-width: .11px;
border-style: none;
- border-color: $intermediate-color; // rgb(187, 186, 186);
+ border-color: $medium-gray; // rgb(187, 186, 186);
// padding: 10px 0px 10px 0px;
white-space: nowrap;
font-size: 13px;
@@ -137,7 +137,7 @@
.contextMenu-item:hover {
transition: all 0.1s ease;
- background: $lighter-alt-accent;
+ background: $light-blue;
}
.contextMenu-description {
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index da8af7cc0..0b70ce68d 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -119,7 +119,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
styleFromLayoutString = (scale: number) => {
const style: { [key: string]: any } = {};
- const divKeys = ["width", "height", "fontSize", "left", "background", "left", "right", "top", "bottom", "pointerEvents", "position"];
+ const divKeys = ["width", "height", "fontSize", "transform", "left", "background", "left", "right", "top", "bottom", "pointerEvents", "position"];
const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a property expression string: { script } into a value
return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: "number" })?.script.run({ self: this.rootDoc, this: this.layoutDoc, scale }).result as string || "";
};
diff --git a/src/client/views/DocumentButtonBar.scss b/src/client/views/DocumentButtonBar.scss
index 09ae14016..2a0b494f5 100644
--- a/src/client/views/DocumentButtonBar.scss
+++ b/src/client/views/DocumentButtonBar.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
$linkGap : 3px;
@@ -7,13 +7,13 @@ $linkGap : 3px;
}
.documentButtonBar-linkButton-empty:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
.documentButtonBar-linkButton-nonempty:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
@@ -25,8 +25,8 @@ $linkGap : 3px;
border-radius: 50%;
opacity: 0.9;
pointer-events: auto;
- background-color: $dark-color;
- color: $light-color;
+ background-color: $dark-gray;
+ color: $white;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 75%;
@@ -37,7 +37,7 @@ $linkGap : 3px;
align-items: center;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
@@ -64,12 +64,12 @@ $linkGap : 3px;
text-align: center;
border-radius: 50%;
pointer-events: auto;
- background-color: $dark-color;
+ background-color: $dark-gray;
border: none;
transition: 0.2s ease all;
&:hover {
- background-color: $main-accent;
+ background-color: $medium-gray;
}
}
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index db2d56aa8..1715f35e7 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
$linkGap : 3px;
@@ -49,7 +49,7 @@ $linkGap : 3px;
.documentDecorations-bottomResizer,
.documentDecorations-rightResizer {
pointer-events: auto;
- background: $alt-accent;
+ background: $medium-gray;
opacity: 0.1;
&:hover {
opacity: 1;
@@ -251,13 +251,13 @@ $linkGap : 3px;
}
.linkButton-empty:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
.linkButton-nonempty:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
@@ -271,7 +271,7 @@ $linkGap : 3px;
flex-direction: row;
z-index: 998;
position: absolute;
- background: $alt-accent;
+ background: $medium-gray;
}
.linkButtonWrapper {
@@ -286,8 +286,8 @@ $linkGap : 3px;
text-align: center;
border-radius: 50%;
pointer-events: auto;
- color: $dark-color;
- border: $dark-color 1px solid;
+ color: $dark-gray;
+ border: $dark-gray 1px solid;
}
.linkButton-linker:hover {
@@ -302,8 +302,8 @@ $linkGap : 3px;
border-radius: 50%;
opacity: 0.9;
pointer-events: auto;
- background-color: $dark-color;
- color: $light-color;
+ background-color: $dark-gray;
+ color: $white;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 75%;
@@ -314,7 +314,7 @@ $linkGap : 3px;
align-items: center;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
@@ -343,13 +343,13 @@ $linkGap : 3px;
border-radius: 50%;
opacity: 0.9;
font-size: 14;
- background-color: $dark-color;
- color: $light-color;
+ background-color: $dark-gray;
+ color: $white;
text-align: center;
cursor: pointer;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
}
}
@@ -365,7 +365,7 @@ $linkGap : 3px;
width: max-content;
font-family: $sans-serif;
font-size: 12px;
- background-color: $light-color-secondary;
+ background-color: $light-gray;
padding: 2px 12px;
list-style: none;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 65a97a49d..d24ab974c 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -201,7 +201,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
(e: PointerEvent, down: number[], delta: number[]) => {
const movement = { X: delta[0], Y: e.clientY - down[1] };
const angle = Math.max(1, Math.abs(movement.Y / 10));
- InkStrokeProperties.Instance?.rotate(2 * movement.X / angle * (Math.PI / 180));
+ InkStrokeProperties.Instance?.rotateInk(2 * movement.X / angle * (Math.PI / 180));
return false;
},
() => this._rotateUndo?.end(),
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index c4162a6bb..76eb4c142 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -114,7 +114,7 @@ export class KeyManager {
case "escape":
DocumentLinksButton.StartLink = undefined;
DocumentLinksButton.StartLinkView = undefined;
- InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = false);
+ InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlButton = false);
CurrentUserUtils.SelectedTool = InkTool.None;
var doDeselect = true;
if (SnappingManager.GetIsDragging()) {
diff --git a/src/client/views/InkControls.tsx b/src/client/views/InkControls.tsx
new file mode 100644
index 000000000..23f22c774
--- /dev/null
+++ b/src/client/views/InkControls.tsx
@@ -0,0 +1,135 @@
+import React = require("react");
+import { observable, action } from "mobx";
+import { observer } from "mobx-react";
+import { InkStrokeProperties } from "./InkStrokeProperties";
+import { setupMoveUpEvents, emptyFunction } from "../../Utils";
+import { UndoManager } from "../util/UndoManager";
+import { ControlPoint, InkData, PointData } from "../../fields/InkField";
+import { Transform } from "../util/Transform";
+
+export interface InkControlProps {
+ data: InkData;
+ addedPoints: PointData[];
+ format: number[];
+ ScreenToLocalTransform: () => Transform;
+}
+
+@observer
+export class InkControls extends React.Component<InkControlProps> {
+ @observable private _overControl = -1;
+ @observable private _overAddPoint = -1;
+
+ /**
+ * Handles the movement of a selected control point when the user clicks and drags.
+ * @param controlIndex The index of the currently selected control point.
+ */
+ @action
+ onControlDown = (e: React.PointerEvent, controlIndex: number): void => {
+ if (InkStrokeProperties.Instance) {
+ InkStrokeProperties.Instance.moveControl(0, 0, 1);
+ const controlUndo = UndoManager.StartBatch("DocDecs set radius");
+ const screenScale = this.props.ScreenToLocalTransform().Scale;
+ const order = controlIndex % 4;
+ const handleIndexA = order === 2 ? controlIndex - 1 : controlIndex - 2;
+ const handleIndexB = order === 2 ? controlIndex + 2 : controlIndex + 1;
+ setupMoveUpEvents(this, e,
+ (e: PointerEvent, down: number[], delta: number[]) => {
+ InkStrokeProperties.Instance?.moveControl(-delta[0] * screenScale, -delta[1] * screenScale, controlIndex);
+ return false;
+ },
+ () => controlUndo?.end(),
+ emptyFunction);
+ // action((e: PointerEvent, doubleTap: boolean | undefined) =>
+ // { if (doubleTap && InkStrokeProperties.Instance?._brokenIndices.includes(controlIndex)) {
+ // InkStrokeProperties.Instance?.snapHandleTangent(controlIndex, handleIndexA, handleIndexB);
+ // }}));
+ }
+ }
+
+ /**
+ * Deletes the currently selected point.
+ */
+ @action
+ onDelete = (e: KeyboardEvent) => {
+ if (["-", "Backspace", "Delete"].includes(e.key)) {
+ if (InkStrokeProperties.Instance?.deletePoints()) e.stopPropagation();
+ }
+ }
+
+ /**
+ * Changes the current selected control point.
+ */
+ @action
+ changeCurrPoint = (i: number) => {
+ if (InkStrokeProperties.Instance) {
+ InkStrokeProperties.Instance._currentPoint = i;
+ document.addEventListener("keydown", this.onDelete, true);
+ }
+ }
+
+ /**
+ * Updates whether a user has hovered over a particular control point or point that could be added
+ * on click.
+ */
+ @action onEnterControl = (i: number) => { this._overControl = i; };
+ @action onLeaveControl = () => { this._overControl = -1; };
+ @action onEnterAddPoint = (i: number) => { this._overAddPoint = i; };
+ @action onLeaveAddPoint = () => { this._overAddPoint = -1; };
+
+ render() {
+ const formatInstance = InkStrokeProperties.Instance;
+ if (!formatInstance) return (null);
+
+ // Accessing the current ink's data and extracting all control points.
+ const data = this.props.data;
+ const controlPoints: ControlPoint[] = [];
+ if (data.length >= 4) {
+ for (let 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 });
+ }
+ }
+ const addedPoints = this.props.addedPoints;
+ const [left, top, scaleX, scaleY, strokeWidth, dotsize] = this.props.format;
+
+ return (
+ <>
+ {addedPoints.map((pts, i) =>
+ <svg height="10" width="10" key={`add${i}`}>
+ <circle
+ cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ r={strokeWidth / 2}
+ stroke={this._overAddPoint === i ? "#1F85DE" : "transparent"}
+ strokeWidth={dotsize / 4} fill={this._overAddPoint === i ? "#1F85DE" : "transparent"}
+ onPointerDown={() => { formatInstance?.addPoints(pts.X, pts.Y, addedPoints, i, controlPoints); }}
+ onMouseEnter={() => this.onEnterAddPoint(i)}
+ onMouseLeave={this.onLeaveAddPoint}
+ pointerEvents="all"
+ cursor="all-scroll"
+ />
+ </svg>
+ )}
+ {controlPoints.map((control, i) =>
+ <svg height="10" width="10" key={`ctrl${i}`}>
+ <rect
+ x={(control.X - left - strokeWidth / 2) * scaleX}
+ y={(control.Y - top - strokeWidth / 2) * scaleY}
+ height={this._overControl === i ? strokeWidth * 1.5 : strokeWidth}
+ width={this._overControl === i ? strokeWidth * 1.5 : strokeWidth}
+ strokeWidth={strokeWidth / 6} stroke="#1F85DE"
+ fill={formatInstance?._currentPoint === control.I ? "#1F85DE" : "white"}
+ onPointerDown={(e) => {
+ this.changeCurrPoint(control.I);
+ this.onControlDown(e, control.I); }}
+ onMouseEnter={() => this.onEnterControl(i)}
+ onMouseLeave={this.onLeaveControl}
+ pointerEvents="all"
+ cursor="default"
+ />
+ </svg>
+ )}
+ </>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/InkHandles.tsx b/src/client/views/InkHandles.tsx
new file mode 100644
index 000000000..28b6dd820
--- /dev/null
+++ b/src/client/views/InkHandles.tsx
@@ -0,0 +1,122 @@
+import React = require("react");
+import { observable, action } from "mobx";
+import { observer } from "mobx-react";
+import { InkStrokeProperties } from "./InkStrokeProperties";
+import { setupMoveUpEvents, emptyFunction } from "../../Utils";
+import { UndoManager } from "../util/UndoManager";
+import { InkData, HandlePoint, HandleLine } from "../../fields/InkField";
+import { Transform } from "../util/Transform";
+import { Doc } from "../../fields/Doc";
+import { listSpec } from "../../fields/Schema";
+import { List } from "../../fields/List";
+import { Cast } from "../../fields/Types";
+
+export interface InkHandlesProps {
+ inkDoc: Doc;
+ data: InkData;
+ format: number[];
+ ScreenToLocalTransform: () => Transform;
+}
+
+@observer
+export class InkHandles extends React.Component<InkHandlesProps> {
+ /**
+ * Handles the movement of a selected handle point when the user clicks and drags.
+ * @param handleNum The index of the currently selected handle point.
+ */
+ onHandleDown = (e: React.PointerEvent, handleIndex: number): void => {
+ if (InkStrokeProperties.Instance) {
+ InkStrokeProperties.Instance.moveControl(0, 0, 1);
+ const controlUndo = UndoManager.StartBatch("DocDecs set radius");
+ const screenScale = this.props.ScreenToLocalTransform().Scale;
+ const order = handleIndex % 4;
+ const oppositeHandleIndex = order === 1 ? handleIndex - 3 : handleIndex + 3;
+ const controlIndex = order === 1 ? handleIndex - 1 : handleIndex + 2;
+ document.addEventListener("keydown", (e: KeyboardEvent) => this.onBreakTangent(e, controlIndex), true);
+ setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => {
+ InkStrokeProperties.Instance?.moveHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleIndex, oppositeHandleIndex, controlIndex);
+ return false;
+ }, () => controlUndo?.end(), emptyFunction
+ );
+ }
+ }
+
+ /**
+ * Breaks tangent handle movement when ‘Alt’ key is held down. Adds the current handle index and
+ * its matching (opposite) handle to a list of broken handle indices.
+ * @param handleNum The index of the currently selected handle point.
+ */
+ @action
+ onBreakTangent = (e: KeyboardEvent, controlIndex: number) => {
+ const doc: Doc = this.props.inkDoc;
+ if (["Alt"].includes(e.key)) {
+ if (doc) {
+ const brokenIndices = Cast(doc.brokenInkIndices, listSpec("number")) || new List;
+ if (brokenIndices && !brokenIndices.includes(controlIndex)) {
+ brokenIndices.push(controlIndex);
+ }
+ doc.brokenInkIndices = brokenIndices;
+ }
+ }
+ }
+
+ render() {
+ const formatInstance = InkStrokeProperties.Instance;
+ if (!formatInstance) return (null);
+
+ // Accessing the current ink's data and extracting all handle points and handle lines.
+ const data = this.props.data;
+ const handlePoints: HandlePoint[] = [];
+ const handleLines: HandleLine[] = [];
+ if (data.length >= 4) {
+ for (let i = 0; i <= data.length - 4; i += 4) {
+ 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 });
+ }
+ // Adding first and last (single) handle lines.
+ handleLines.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 });
+ handleLines.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 });
+ for (let i = 2; i < data.length - 4; i += 4) {
+ handleLines.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 });
+ }
+ }
+ const [left, top, scaleX, scaleY, strokeWidth, dotsize] = this.props.format;
+
+ return (
+ <>
+ {handlePoints.map((pts, i) =>
+ <svg height="10" width="10" key={`hdl${i}`}>
+ <circle
+ cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2}
+ cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2}
+ r={strokeWidth / 2}
+ strokeWidth={0}
+ fill="#1F85DE"
+ onPointerDown={(e) => this.onHandleDown(e, pts.I)}
+ pointerEvents="all"
+ cursor="default"
+ display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "inherit" : "none"} />
+ </svg>)}
+ {handleLines.map((pts, i) =>
+ <svg height="100" width="100" key={`line${i}`}>
+ <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="#1F85DE"
+ strokeWidth={dotsize / 8}
+ display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "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="#1F85DE"
+ strokeWidth={dotsize / 8}
+ display={(pts.dot1 === formatInstance._currentPoint || pts.dot2 === formatInstance._currentPoint) ? "inherit" : "none"} />
+ </svg>)}
+ </>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/InkStroke.scss b/src/client/views/InkStroke.scss
new file mode 100644
index 000000000..812a79bd5
--- /dev/null
+++ b/src/client/views/InkStroke.scss
@@ -0,0 +1,11 @@
+.inkStroke {
+ mix-blend-mode: multiply;
+ stroke-linejoin: round;
+ stroke-linecap: round;
+ overflow: visible !important;
+ transform-origin: top left;
+
+ svg:not(:root) {
+ overflow: visible !important;
+ }
+}
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index b13b04f68..1a3585f3e 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -1,124 +1,44 @@
import { action, computed, observable } from "mobx";
-import { ColorState } from 'react-color';
-import { Doc, Field, Opt } from "../../fields/Doc";
+import { Doc, DocListCast, Field, Opt } from "../../fields/Doc";
import { Document } from "../../fields/documentSchemas";
-import { InkField, InkData } from "../../fields/InkField";
+import { InkField, InkData, PointData, ControlPoint } from "../../fields/InkField";
+import { List } from "../../fields/List";
+import { listSpec } from "../../fields/Schema";
import { Cast, NumCast } from "../../fields/Types";
import { DocumentType } from "../documents/DocumentTypes";
import { SelectionManager } from "../util/SelectionManager";
import { undoBatch } from "../util/UndoManager";
-import { bool } from "sharp";
export class InkStrokeProperties {
static Instance: InkStrokeProperties | undefined;
- private _lastFill = "#D0021B";
- private _lastLine = "#D0021B";
- private _lastDash = "2";
- private _inkDocs: { x: number, y: number, width: number, height: number }[] = [];
-
@observable _lock = false;
- @observable _controlBtn = false;
- @observable _currPoint = -1;
+ @observable _controlButton = false;
+ @observable _currentPoint = -1;
- getField(key: string) {
- return this.selectedInk?.reduce((p, i) =>
- (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt<string>);
+ constructor() {
+ InkStrokeProperties.Instance = this;
}
@computed get selectedInk() {
const inks = SelectionManager.Views().filter(i => Document(i.rootDoc).type === DocumentType.INK);
return inks.length ? inks : undefined;
}
- @computed get unFilled() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; }
- @computed get unStrokd() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; }
- @computed get solidFil() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; }
- @computed get solidStk() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; }
- @computed get dashdStk() { return !this.unStrokd && this.getField("strokeDash") || ""; }
- @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
- @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
- @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
- @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
- @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
- @computed get shapeHgt() { return this.getField("_height"); }
- @computed get shapeWid() { return this.getField("_width"); }
- @computed get shapeXps() { return this.getField("x"); }
- @computed get shapeYps() { return this.getField("y"); }
- @computed get shapeRot() { return this.getField("rotation"); }
- set unFilled(value) { this.colorFil = value ? "" : this._lastFill; }
- set solidFil(value) { this.unFilled = !value; }
- set colorFil(value) { value && (this._lastFill = value); this.selectedInk?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); }
- set colorStk(value) { value && (this._lastLine = value); this.selectedInk?.forEach(i => i.rootDoc.color = value ? value : undefined); }
- set markHead(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeStartMarker = value); }
- set markTail(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeEndMarker = value); }
- set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
- set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
- set dashdStk(value) {
- value && (this._lastDash = value) && (this.unStrokd = false);
- this.selectedInk?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined);
- }
- set shapeXps(value) { this.selectedInk?.forEach(i => i.rootDoc.x = Number(value)); }
- set shapeYps(value) { this.selectedInk?.forEach(i => i.rootDoc.y = Number(value)); }
- set shapeRot(value) { this.selectedInk?.forEach(i => i.rootDoc.rotation = Number(value)); }
- set widthStk(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = Number(value)); }
- set shapeWid(value) {
- this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
- const oldWidth = NumCast(i.rootDoc._width);
- i.rootDoc._width = Number(value);
- this._lock && (i.rootDoc._height = (i.rootDoc._width * NumCast(i.rootDoc._height)) / oldWidth);
- });
- }
- set shapeHgt(value) {
- this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
- const oldHeight = NumCast(i.rootDoc._height);
- i.rootDoc._height = Number(value);
- this._lock && (i.rootDoc._width = (i.rootDoc._height * NumCast(i.rootDoc._width)) / oldHeight);
- });
- }
-
- constructor() {
- InkStrokeProperties.Instance = this;
- }
-
- @undoBatch
- @action
- addPoints = (x: number, y: number, pts: { X: number, Y: number }[], index: number, control: { X: number, Y: number }[]) => {
- this.selectedInk?.forEach(action(inkView => {
- if (this.selectedInk?.length === 1) {
- const doc = Document(inkView.rootDoc);
- if (doc.type === DocumentType.INK) {
- const ink = Cast(doc.data, InkField)?.inkData;
- if (ink) {
- const newPoints: { X: number, Y: number }[] = [];
- var counter = 0;
- for (var k = 0; k < index; k++) {
- control.forEach(pt => (pts[k].X === pt.X && pts[k].Y === pt.Y) && counter++);
- }
- //decide where to put the new coordinate
- const spNum = Math.floor(counter / 2) * 4 + 2;
-
- for (var i = 0; i < spNum; i++) {
- ink[i] && newPoints.push({ X: ink[i].X, Y: ink[i].Y });
- }
- for (var j = 0; j < 4; j++) {
- newPoints.push({ X: x, Y: y });
- }
- for (var i = spNum; i < ink.length; i++) {
- newPoints.push({ X: ink[i].X, Y: ink[i].Y });
- }
- this._currPoint = -1;
- Doc.GetProto(doc).data = new InkField(newPoints);
- }
- }
- }
- }));
+ getField(key: string) {
+ return this.selectedInk?.reduce((p, i) =>
+ (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt<string>);
}
- applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => {
+ /**
+ * Helper function that enables other functions to be applied to a particular ink instance.
+ * @param func The inputted function.
+ * @param requireCurrPoint Indicates whether the current selected point is needed.
+ */
+ applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => {
var appliedFunc = false;
this.selectedInk?.forEach(action(inkView => {
- if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currPoint !== -1)) {
+ if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currentPoint !== -1)) {
const doc = Document(inkView.rootDoc);
if (doc.type === DocumentType.INK && doc.width && doc.height) {
const ink = Cast(doc.data, InkField)?.inkData;
@@ -145,17 +65,136 @@ export class InkStrokeProperties {
return appliedFunc;
}
+ /**
+ * Adds a new control point to the ink instance when editing its format.
+ * @param index The index of the new point.
+ * @param control The list of all control points of the ink.
+ */
+ @undoBatch
+ @action
+ addPoints = (x: number, y: number, points: InkData, index: number, controls: { X: number, Y: number }[]) => {
+ this.applyFunction((doc: Doc, ink: InkData) => {
+ const newControl = { X: x, Y: y };
+ const newPoints: InkData = [];
+ let [counter, start, end] = [0, 0, 0];
+ for (let k = 0; k < points.length; k++) {
+ if (end === 0) {
+ controls.forEach((control) => {
+ if (control.X === points[k].X && control.Y === points[k].Y) {
+ if (k < index) {
+ counter++;
+ start = k;
+ } else if (k > index) {
+ end = k;
+ }
+ }
+ });
+ }
+ }
+ if (end === 0) end = points.length-1;
+ // Index of new control point with regards to the ink data.
+ const newIndex = Math.floor(counter / 2) * 4 + 2;
+ // Creating new ink data with the new control point and handle points inputted.
+ for (let i = 0; i < ink.length; i++) {
+ if (i === newIndex) {
+ const [handleA, handleB] = this.getNewHandlePoints(points.slice(start, index+1), points.slice(index, end), newControl);
+ newPoints.push(handleA, newControl, newControl, handleB);
+ // Adjusting the magnitude of the left handle line of the right neighboring control point.
+ const [rightControl, rightHandle] = [points[end], ink[i]];
+ const scaledVector = this.getScaledHandlePoint(false, start, end, index, rightControl, rightHandle);
+ rightHandle && newPoints.push({ X: rightControl.X - scaledVector.X, Y: rightControl.Y - scaledVector.Y });
+ } else if (i === newIndex - 1) {
+ // Adjusting the magnitude of the right handle line of the left neighboring control point.
+ const [leftControl, leftHandle] = [points[start], ink[i]];
+ const scaledVector = this.getScaledHandlePoint(true, start, end, index, leftControl, leftHandle);
+ leftHandle && newPoints.push({ X: leftControl.X - scaledVector.X, Y: leftControl.Y - scaledVector.Y });
+ } else {
+ ink[i] && newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+ }
+
+ }
+ let brokenIndices = Cast(doc.brokenInkIndices, listSpec("number"));
+ // Updating the indices of the control points whose handle tangency has been broken.
+ if (brokenIndices) {
+ brokenIndices = new List(brokenIndices.map((control) => {
+ if (control >= newIndex) {
+ return control + 4;
+ } else {
+ return control;
+ }
+ }));
+ }
+ doc.brokenInkIndices = brokenIndices;
+ this._currentPoint = -1;
+ return newPoints;
+ });
+ }
+
+ /**
+ * Scales a handle point of a control point that is adjacent to a newly added one.
+ * @param isLeft Determines if the current control point is on the left or right side of the newly added one.
+ * @param start Beginning index of curve from the left control point to the newly added one.
+ * @param end Final index of curve from the newly added control point to its right neighbor.
+ */
+ getScaledHandlePoint(isLeft: boolean, start: number, end: number, index: number, control: PointData, handle: PointData) {
+ const prevSize = end - start;
+ const newSize = isLeft ? index - start : end - index;
+ const handleVector = { X: control.X - handle.X, Y: control.Y - handle.Y };
+ const scaledVector = { X: handleVector.X * (newSize / prevSize), Y: handleVector.Y * (newSize / prevSize) };
+ return scaledVector;
+ }
+
+ /**
+ * Determines the position of the handle points of a newly added control point by finding the
+ * tangent vectors to the split curve at the new control. Given the properties of Bézier curves,
+ * the tangent vector to a control point is equivalent to the first/last (depending on the direction
+ * of the curve) leg of the Bézier curve's derivative.
+ * (Source: https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-der.html)
+ *
+ * @param C The curve represented by all points from the previous control until the newly added point.
+ * @param D The curve represented by all points from the newly added point to the next control.
+ * @param newControl The newly added control point.
+ */
+ getNewHandlePoints = (C: PointData[], D: PointData[], newControl: PointData) => {
+ const [m, n] = [C.length, D.length];
+ let handleSizeA = Math.sqrt((Math.pow(newControl.X - C[0].X, 2)) + (Math.pow(newControl.Y - C[0].Y, 2)));
+ let handleSizeB = Math.sqrt((Math.pow(D[n-1].X - newControl.X, 2)) + (Math.pow(D[n-1].Y - newControl.Y, 2)));
+ // Scaling adjustments to improve the ratio between the magnitudes of the two handle lines.
+ // (Ensures that the new point added doesn't augment the inital shape of the curve much).
+ if (handleSizeA < 75 && handleSizeB < 75) {
+ handleSizeA *= 3;
+ handleSizeB *= 3;
+ }
+ if (Math.abs(handleSizeA - handleSizeB) < 50) {
+ handleSizeA *= 5;
+ handleSizeB *= 5;
+ } else if (Math.abs(handleSizeA - handleSizeB) < 150) {
+ handleSizeA *= 2;
+ handleSizeB *= 2;
+ }
+ // Finding the last leg of the derivative curve of C.
+ const dC = { X: (handleSizeA / n) * (C[m-1].X - C[m-2].X), Y: (handleSizeA / n) * (C[m-1].Y - C[m-2].Y) };
+ // Finding the first leg of the derivative curve of D.
+ const dD = { X: (handleSizeB / m) * (D[1].X - D[0].X), Y: (handleSizeB / m) * (D[1].Y - D[0].Y) };
+ const handleA = { X: newControl.X - dC.X, Y: newControl.Y - dC.Y };
+ const handleB = { X: newControl.X + dD.X, Y: newControl.Y + dD.Y };
+ return [handleA, handleB];
+ }
+
+ /**
+ * Deletes the current control point of the selected ink instance.
+ */
@undoBatch
@action
deletePoints = () => this.applyFunction((doc: Doc, ink: InkData) => {
- var newPoints: { X: number, Y: number }[] = [];
- const toRemove = Math.floor(((this._currPoint + 2) / 4));
- for (var i = 0; i < ink.length; i++) {
+ const newPoints: { X: number, Y: number }[] = [];
+ const toRemove = Math.floor(((this._currentPoint + 2) / 4));
+ for (let i = 0; i < ink.length; i++) {
if (Math.floor((i + 2) / 4) !== toRemove && (toRemove !== 0 || i > 3)) {
newPoints.push({ X: ink[i].X, Y: ink[i].Y });
}
}
- this._currPoint = -1;
+ this._currentPoint = -1;
if (newPoints.length < 4) return undefined;
if (newPoints.length === 4) {
const newerPoints: { X: number, Y: number }[] = [];
@@ -166,12 +205,16 @@ export class InkStrokeProperties {
return newerPoints;
}
return newPoints;
- }, true);
+ }, true)
+ /**
+ * Rotates the entire selected ink instance.
+ * @param angle The angle at which to rotate the ink in radians.
+ */
@undoBatch
@action
- rotate = (angle: number) => {
- this.applyFunction((doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => {
+ rotateInk = (angle: number) => {
+ this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => {
const oldXrange = (xs => ({ coord: NumCast(doc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X));
const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y));
const centerPoint = { X: (oldXrange.min + oldXrange.max) / 2, Y: (oldYrange.min + oldYrange.max) / 2 };
@@ -186,42 +229,108 @@ export class InkStrokeProperties {
});
}
+ /**
+ * Handles the movement/scaling of a control point.
+ */
@undoBatch
@action
- control = (xDiff: number, yDiff: number, controlNum: number) =>
- this.applyFunction((doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => {
+ moveControl = (deltaX: number, deltaY: number, controlIndex: number) =>
+ this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => {
const newPoints: { X: number, Y: number }[] = [];
- const order = controlNum % 4;
+ const order = controlIndex % 4;
for (var i = 0; i < ink.length; i++) {
- newPoints.push(
- (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) ||
- ((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))
- ) ?
- { X: ink[i].X - xDiff / ptsXscale, Y: ink[i].Y - yDiff / ptsYscale } :
- { X: ink[i].X, Y: ink[i].Y });
+ const leftHandlePoint = order === 0 && i === controlIndex + 1;
+ const rightHandlePoint = order === 0 && controlIndex !== 0 && i === controlIndex - 2;
+ if (controlIndex === i ||
+ leftHandlePoint ||
+ rightHandlePoint ||
+ (order === 0 && controlIndex !== 0 && i === controlIndex - 1) ||
+ (order === 3 && i === controlIndex - 1) ||
+ (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 1) ||
+ (order === 3 && controlIndex !== ink.length - 1 && i === controlIndex + 2) ||
+ ((ink[0].X === ink[ink.length - 1].X) && (ink[0].Y === ink[ink.length - 1].Y) && (i === 0 || i === ink.length - 1) && (controlIndex === 0 || controlIndex === ink.length - 1))) {
+ newPoints.push({ X: ink[i].X - deltaX / xScale, Y: ink[i].Y - deltaY / yScale });
+ } else {
+ newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+ }
}
return newPoints;
+ })
+
+ snapHandleTangent = (controlIndex: number, handleIndexA: number, handleIndexB: number) => {
+ this.applyFunction((doc: Doc, ink: InkData) => {
+ // doc.brokenIndices.splice(this._brokenIndices.indexOf(controlIndex), 1);
+ const [controlPoint, handleA, handleB] = [ink[controlIndex], ink[handleIndexA], ink[handleIndexB]];
+ const oppositeHandleA = this.rotatePoint(handleA, controlPoint, Math.PI);
+ const angleDifference = this.angleChange(handleB, oppositeHandleA, controlPoint);
+ const newHandleB = this.rotatePoint(handleB, controlPoint, angleDifference);
+ ink[handleIndexB] = newHandleB;
+ return ink;
});
+ }
- @undoBatch
+ /**
+ * Rotates the target point about the origin point for a given angle (radians).
+ */
@action
- switchStk = (color: ColorState) => {
- const val = String(color.hex);
- this.colorStk = val;
- return true;
+ rotatePoint = (target: PointData, origin: PointData, angle: number) => {
+ target.X -= origin.X;
+ target.Y -= origin.Y;
+ const newX = Math.cos(angle) * target.X - Math.sin(angle) * target.Y;
+ const newY = Math.sin(angle) * target.X + Math.cos(angle) * target.Y;
+ target.X = newX + origin.X;
+ target.Y = newY + origin.Y;
+ return target;
+ }
+
+ /**
+ * Finds the angle (in radians) between two inputted vectors.
+ *
+ * α = arccos(a·b / |a|·|b|), where a and b are both vectors.
+ */
+ angleBetweenTwoVectors = (vectorA: PointData, vectorB: PointData) => {
+ const magnitudeA = Math.sqrt(vectorA.X * vectorA.X + vectorA.Y * vectorA.Y);
+ const magnitudeB = Math.sqrt(vectorB.X * vectorB.X + vectorB.Y * vectorB.Y);
+ // Normalizing the vectors.
+ vectorA = { X: vectorA.X / magnitudeA, Y: vectorA.Y / magnitudeA };
+ vectorB = { X: vectorB.X / magnitudeB, Y: vectorB.Y / magnitudeB };
+ const dotProduct = vectorB.X * vectorA.X + vectorB.Y * vectorA.Y;
+ return Math.acos(dotProduct);
}
+ /**
+ * Finds the angle difference (in radians) between two vectors relative to an arbitrary origin.
+ */
+ angleChange = (a: PointData, b: PointData, origin: PointData) => {
+ // Finding vector representation of inputted points relative to new origin.
+ const vectorA = { X: a.X - origin.X, Y: a.Y - origin.Y };
+ const vectorB = { X: b.X - origin.X, Y: b.Y - origin.Y };
+ const crossProduct = vectorB.X * vectorA.Y - vectorB.Y * vectorA.X;
+ // Determining whether rotation is clockwise or counterclockwise.
+ const sign = crossProduct < 0 ? 1 : -1;
+ const theta = this.angleBetweenTwoVectors(vectorA, vectorB);
+ return sign * theta;
+ }
+
+ /**
+ * Handles the movement/scaling of a handle point.
+ */
@undoBatch
@action
- switchFil = (color: ColorState) => {
- const val = String(color.hex);
- this.colorFil = val;
- return true;
- }
+ moveHandle = (deltaX: number, deltaY: number, handleIndex: number, oppositeHandleIndex: number, controlIndex: number) =>
+ this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => {
+ const oldHandlePoint = ink[handleIndex];
+ let oppositeHandlePoint = ink[oppositeHandleIndex];
+ const controlPoint = ink[controlIndex];
+ const newHandlePoint = { X: ink[handleIndex].X - deltaX / xScale, Y: ink[handleIndex].Y - deltaY / yScale };
+ ink[handleIndex] = newHandlePoint;
+ const brokenIndices = Cast(doc.brokenInkIndices, listSpec("number"));
+ // Rotate opposite handle if user hasn't held 'Alt' key or not first/final control (which have only 1 handle).
+ if ((!brokenIndices || !brokenIndices?.includes(controlIndex)) && handleIndex !== 1 && handleIndex !== ink.length - 2) {
+ const angle = this.angleChange(oldHandlePoint, newHandlePoint, controlPoint);
+ oppositeHandlePoint = this.rotatePoint(oppositeHandlePoint, controlPoint, angle);
+ ink[oppositeHandleIndex] = oppositeHandlePoint;
+ }
+ return ink;
+ })
} \ No newline at end of file
diff --git a/src/client/views/InkingStroke.scss b/src/client/views/InkingStroke.scss
deleted file mode 100644
index 30ab1967e..000000000
--- a/src/client/views/InkingStroke.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.inkingStroke {
- mix-blend-mode: multiply;
- stroke-linejoin: round;
- stroke-linecap: round;
- overflow: visible !important;
- transform-origin: top left;
-
- svg:not(:root) {
- overflow: visible !important;
- }
-} \ No newline at end of file
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 449019ca8..bd71aaf19 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -1,4 +1,5 @@
-import { action } from "mobx";
+import React = require("react");
+import { action, observable } from "mobx";
import { observer } from "mobx-react";
import { Doc } from "../../fields/Doc";
import { documentSchema } from "../../fields/documentSchemas";
@@ -10,180 +11,110 @@ import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
import { InteractionUtils } from "../util/InteractionUtils";
import { Scripting } from "../util/Scripting";
-import { UndoManager } from "../util/UndoManager";
import { ContextMenu } from "./ContextMenu";
import { ViewBoxBaseComponent } from "./DocComponent";
-import "./InkingStroke.scss";
+import "./InkStroke.scss";
import { FieldView, FieldViewProps } from "./nodes/FieldView";
-import React = require("react");
import { InkStrokeProperties } from "./InkStrokeProperties";
import { CurrentUserUtils } from "../util/CurrentUserUtils";
+import { InkControls } from "./InkControls";
+import { InkHandles } from "./InkHandles";
type InkDocument = makeInterface<[typeof documentSchema]>;
const InkDocument = makeInterface(documentSchema);
@observer
export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocument>(InkDocument) {
- private _controlUndo?: UndoManager.Batch;
+ static readonly MaskDim = 50000;
+ @observable private _properties?: InkStrokeProperties;
- public static LayoutString(fieldStr: string) { return FieldView.LayoutString(InkingStroke, fieldStr); }
+ constructor(props: FieldViewProps & InkDocument) {
+ super(props);
- private analyzeStrokes = () => {
+ this._properties = InkStrokeProperties.Instance;
+ }
+
+ public static LayoutString(fieldStr: string) {
+ return FieldView.LayoutString(InkingStroke, fieldStr);
+ }
+
+ analyzeStrokes() {
const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], [data]);
}
- public static toggleMask = action((inkDoc: Doc) => {
+ @action
+ public static toggleMask = (inkDoc: Doc) => {
inkDoc.isInkMask = !inkDoc.isInkMask;
inkDoc._backgroundColor = inkDoc.isInkMask ? "rgba(0,0,0,0.7)" : undefined;
inkDoc.mixBlendMode = inkDoc.isInkMask ? "hard-light" : undefined;
inkDoc.color = "#9b9b9bff";
inkDoc._stayInCollection = inkDoc.isInkMask ? true : undefined;
- });
-
- @action
- onControlDown = (e: React.PointerEvent, controlNum: number): void => {
- if (InkStrokeProperties.Instance) {
- InkStrokeProperties.Instance.control(0, 0, 1);
- const controlUndo = UndoManager.StartBatch("DocDecs set radius");
- const screenScale = this.props.ScreenToLocalTransform().Scale;
- setupMoveUpEvents(this, e,
- (e: PointerEvent, down: number[], delta: number[]) => {
- InkStrokeProperties.Instance?.control(-delta[0] * screenScale, -delta[1] * screenScale, controlNum);
- return false;
- },
- () => controlUndo?.end(), emptyFunction);
- }
- }
-
- @action
- changeCurrPoint = (i: number) => {
- if (InkStrokeProperties.Instance) {
- InkStrokeProperties.Instance._currPoint = i;
- document.addEventListener("keydown", this.delPts, true);
- }
- }
-
- @action
- delPts = (e: KeyboardEvent) => {
- if (["-", "Backspace", "Delete"].includes(e.key)) {
- if (InkStrokeProperties.Instance?.deletePoints()) e.stopPropagation();
- }
}
+ /**
+ * Handles the movement of the entire ink object when the user clicks and drags.
+ */
onPointerDown = (e: React.PointerEvent) => {
if (this.props.isSelected(true)) {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e: PointerEvent, doubleTap: boolean | undefined) =>
- doubleTap && InkStrokeProperties.Instance && (InkStrokeProperties.Instance._controlBtn = true)));
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction,
+ action((e: PointerEvent, doubleTap: boolean | undefined) =>
+ doubleTap && this._properties && (this._properties._controlButton = true))
+ );
}
}
- public static MaskDim = 50000;
render() {
TraceMobx();
- const formatInstance = InkStrokeProperties.Instance;
- if (!formatInstance) return (null);
+ // Extracting the ink data and formatting information of the current ink stroke.
const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? [];
- // const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth()));
+ const inkDoc: Doc = this.layoutDoc;
const strokeWidth = Number(this.layoutDoc.strokeWidth);
- const xs = data.map(p => p.X);
- const ys = data.map(p => p.Y);
- const lineTop = Math.min(...ys);
- const lineBot = Math.max(...ys);
- const lineLft = Math.min(...xs);
- const lineRgt = Math.max(...xs);
- const left = lineLft - strokeWidth / 2;
+ const lineTop = Math.min(...data.map(p => p.Y));
+ const lineBottom = Math.max(...data.map(p => p.Y));
+ const lineLeft = Math.min(...data.map(p => p.X));
+ const lineRight = Math.max(...data.map(p => p.X));
+ const left = lineLeft - strokeWidth / 2;
const top = lineTop - strokeWidth / 2;
- const right = lineRgt + strokeWidth / 2;
- const bottom = lineBot + strokeWidth / 2;
+ const right = lineRight + strokeWidth / 2;
+ const bottom = lineBottom + strokeWidth / 2;
const width = Math.max(1, right - left);
const height = Math.max(1, bottom - top);
const scaleX = width === strokeWidth ? 1 : (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth);
const scaleY = height === strokeWidth ? 1 : (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth);
const strokeColor = StrCast(this.layoutDoc.color, "");
+ const dotsize = Math.max(width * scaleX, height * scaleY) / 40;
- const points = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
+ // Visually renders the polygonal line made by the user.
+ const inkLine = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
- StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5 && lineBot - lineTop > 1 && lineRgt - lineLft > 1, 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, "none"),
- "none", "none", undefined, scaleX, scaleY, "", this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted", false, true);
-
- //points for adding
- const apoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth,
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none",
+ this.props.isSelected() && strokeWidth <= 5 && lineBottom - lineTop > 1 && lineRight - lineLeft > 1,
+ false);
+ // Thin blue line indicating that the current ink stroke is selected.
+ const selectedLine = InteractionUtils.CreatePolyline(
+ data, lineLeft - strokeWidth * 3, lineTop - strokeWidth * 3, "#1F85DE", strokeWidth / 6,
+ strokeWidth / 6, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
+ StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none",
+ this.props.isSelected() && strokeWidth <= 5 && lineBottom - lineTop > 1 && lineRight - lineLeft > 1,
+ false);
+ // Invisible polygonal line that enables the ink to be selected by the user.
+ const clickableLine = InteractionUtils.CreatePolyline(data, left, top,
+ this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth,
+ strokeWidth + 15, StrCast(this.layoutDoc.strokeBezier),
+ StrCast(this.layoutDoc.fillColor, "none"), "none", "none", undefined, scaleX, scaleY, "",
+ this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted", false, true);
+ // Set of points rendered upon the ink that can be added if a user clicks on one.
+ const addedPoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth,
StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
- StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false);
-
- 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 >= 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 - 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 });
-
- for (var i = 0; i <= data.length - 4; i += 4) {
- 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 });
- }
- }
- // 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 = Math.max(width * scaleX, height * scaleY) / 40;
-
- const addpoints = apoints.map((pts, i) =>
- <svg height="10" width="10" key={`add${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} stroke="invisible" strokeWidth={dotsize / 2} fill="invisible"
- onPointerDown={(e) => { formatInstance.addPoints(pts.X, pts.Y, apoints, i, controlPoints); }} pointerEvents="all" cursor="all-scroll"
- />
- </svg>);
- const handles = handlePoints.map((pts, i) =>
- <svg height="10" width="10" key={`hdl${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth} strokeWidth={0} fill="green"
- onPointerDown={(e) => this.onControlDown(e, pts.I)} pointerEvents="all" cursor="default" display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} />
- </svg>);
-
- const controls = controlPoints.map((pts, i) =>
- <svg height="10" width="10" key={`ctrl${i}`}>
- <circle cx={(pts.X - left - strokeWidth / 2) * scaleX + strokeWidth / 2} cy={(pts.Y - top - strokeWidth / 2) * scaleY + strokeWidth / 2} r={strokeWidth / 2} strokeWidth={0} fill="red"
- onPointerDown={(e) => { this.changeCurrPoint(pts.I); this.onControlDown(e, pts.I); }} pointerEvents="all" cursor="default"
- />
- </svg>);
- const handleLines = handleLine.map((pts, i) =>
- <svg height="100" width="100" key={`line${i}`} >
- <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="green" strokeWidth={dotsize / 6}
- display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._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="green" strokeWidth={dotsize / 6}
- display={(pts.dot1 === formatInstance._currPoint || pts.dot2 === formatInstance._currPoint) ? "inherit" : "none"} />
- </svg>);
-
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none",
+ this.props.isSelected() && strokeWidth <= 5, false);
return (
- <svg className="inkingStroke"
+ <svg className="inkStroke"
style={{
pointerEvents: this.props.Document.isInkMask && this.props.layerProvider?.(this.props.Document) !== false ? "all" : "none",
transform: this.props.Document.isInkMask ? `translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
@@ -196,19 +127,27 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
if (cm) {
!Doc.UserDoc().noviceMode && cm.addItem({ description: "Recognize Writing", event: this.analyzeStrokes, icon: "paint-brush" });
cm.addItem({ description: "Toggle Mask", event: () => InkingStroke.toggleMask(this.rootDoc), icon: "paint-brush" });
- cm.addItem({ description: "Edit Points", event: action(() => formatInstance._controlBtn = !formatInstance._controlBtn), icon: "paint-brush" });
- //cm.addItem({ description: "Format Shape...", event: this.formatShape, icon: "paint-brush" });
+ cm.addItem({ description: "Edit Points", event: action(() => { if (this._properties) { this._properties._controlButton = !this._properties._controlButton; } }), icon: "paint-brush" });
}
}}
- ><defs>
- </defs>
- {hpoints}
- {points}
- {formatInstance._controlBtn && this.props.isSelected() ? addpoints : ""}
- {formatInstance._controlBtn && this.props.isSelected() ? handleLines : ""}
- {formatInstance._controlBtn && this.props.isSelected() ? handles : ""}
- {formatInstance._controlBtn && this.props.isSelected() ? controls : ""}
-
+ >
+
+ {clickableLine}
+ {inkLine}
+ {this.props.isSelected() ? selectedLine : ""}
+ {this.props.isSelected() && this._properties?._controlButton ?
+ <>
+ <InkControls
+ data={data}
+ addedPoints={addedPoints}
+ format={[left, top, scaleX, scaleY, strokeWidth, dotsize]}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform} />
+ <InkHandles
+ inkDoc={inkDoc}
+ data={data}
+ format={[left, top, scaleX, scaleY, strokeWidth, dotsize]}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform} />
+ </> : ""}
</svg>
);
}
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index b1ad4868c..c8e64b5c4 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
@import "nodeModuleOverrides";
:root {
@@ -54,7 +54,7 @@ button {
background: black;
outline: none;
border: 0px;
- color: $light-color;
+ color: $white;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 75%;
@@ -63,7 +63,7 @@ button {
}
button:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 3f04a0f3a..07ca0257c 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
@import "nodeModuleOverrides";
@@ -56,50 +56,50 @@
touch-action: none;
.searchBox-container {
- background: lightgray;
+ background: $light-gray;
}
}
.mainView-container {
- color: black;
+ color: $dark-gray;
.lm_title {
- background: #cacaca;
- color: black;
+ background: $light-gray;
+ color: $dark-gray;
}
}
.mainView-container-dark {
- color: lightgray;
+ color: $light-gray;
.lm_goldenlayout {
- background: dimgray;
+ background: $medium-gray;
}
.lm_title {
- background: black;
+ background: $dark-gray;
color: unset;
}
.marquee {
- border-color: white;
+ border-color: $white;
}
#search-input {
- background: lightgray;
+ background: $light-gray;
}
.searchBox-container {
- background: rgb(45, 45, 45);
+ background: $dark-gray;
}
.contextMenu-cont,
.contextMenu-item {
- background: dimGray;
+ background: $medium-gray;
}
.contextMenu-item:hover {
- background: gray;
+ background: $medium-gray;
}
}
@@ -113,7 +113,7 @@
.mainView-propertiesDragger {
//background-color: rgb(140, 139, 139);
- background-color: lightgrey;
+ background-color: $light-gray;
height: 55px;
width: 17px;
position: absolute;
@@ -163,10 +163,10 @@
flex-direction: column;
position: relative;
height: 100%;
- background: dimgray;
+ background: $medium-gray;
.documentView-node-topmost {
- background: lightgrey;
+ background: $light-gray;
}
}
@@ -174,32 +174,32 @@
right: 0;
position: absolute;
z-index: 2;
- background-color: rgb(159, 159, 159);
+ background-color: $medium-gray;
.editable-title {
- background-color: lightgrey;
+ background-color: $light-gray;
}
}
}
.mainView-libraryHandle {
- background-color: lightgrey;
+ background-color: $light-gray;
}
.mainView-innerContent-dark
{
.propertiesView {
background-color: #252525;
input {
- background-color: dimgrey;
+ background-color: $medium-gray;
}
.propertiesView-sharingTable
{
- background-color: dimgrey;
+ background-color: $medium-gray;
}
.editable-title {
- background-color: dimgrey;
+ background-color: $medium-gray;
}
.propertiesView-field {
- background-color: dimgrey;
+ background-color: $medium-gray;
}
}
.mainView-propertiesDragger,
@@ -209,17 +209,17 @@
}
.mainView-container-dark {
.contextMenu-cont {
- background: dimgrey;
- color: white;
+ background: $medium-gray;
+ color: $white;
input::placeholder {
- color:white;
+ color:$white;
}
}
}
.mainView-menuPanel {
min-width: var(--menuPanelWidth);
- background-color: #121721;
+ background-color: $dark-gray;
.collectionStackingView {
scrollbar-width: none;
@@ -233,13 +233,13 @@
padding: 7px;
padding-left: 7px;
width: 100%;
- background: black;
+ background: $dark-gray;
.mainView-menuPanel-button-wrap {
width: 45px;
/* padding: 5px; */
touch-action: none;
- background: black;
+ background: $dark-gray;
transform-origin: top left;
/* margin-bottom: 5px; */
margin-top: 5px;
@@ -247,7 +247,7 @@
border-radius: 8px;
&:hover {
- background: rgb(61, 61, 61);
+ background: $black;
cursor: pointer;
}
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4eeb1fc95..f34851b00 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -40,7 +40,7 @@ import { ContextMenu } from './ContextMenu';
import { DictationOverlay } from './DictationOverlay';
import { DocumentDecorations } from './DocumentDecorations';
import { GestureOverlay } from './GestureOverlay';
-import { MENU_PANEL_WIDTH, SEARCH_PANEL_HEIGHT } from './globalCssVariables.scss';
+import { MENU_PANEL_WIDTH, SEARCH_PANEL_HEIGHT } from './global/globalCssVariables.scss';
import { KeyManager } from './GlobalKeyHandler';
import { InkStrokeProperties } from './InkStrokeProperties';
import { LightboxView } from './LightboxView';
@@ -180,8 +180,8 @@ export class MainView extends React.Component {
const targClass = targets[0].className.toString();
if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
const check = targets.some((thing) =>
- (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
- thing.className === "collectionSchema-header-menuOptions"));
+ (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+ thing.className === "collectionSchema-header-menuOptions"));
!check && SearchBox.Instance.resetSearch(true);
}
!targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 29d2bfcb7..484522bc7 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
$linkGap : 3px;
@@ -7,13 +7,13 @@ $linkGap : 3px;
}
.propertiesButtons-linkButton-empty:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
.propertiesButtons-linkButton-nonempty:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
@@ -24,7 +24,7 @@ $linkGap : 3px;
width: 29px;
border-radius: 6px;
pointer-events: auto;
- background-color: #121721;
+ background-color: $dark-gray;
color: #fcfbf7;
text-transform: uppercase;
letter-spacing: 2px;
@@ -38,18 +38,18 @@ $linkGap : 3px;
margin-left: 4px;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
}
.propertiesButtons-linkButton-empty.toggle-on {
background-color: white;
- color: black;
+ color: $dark-gray;
}
.propertiesButtons-linkButton-empty.toggle-hover {
background-color: gray;
- color: black;
+ color: $dark-gray;
}
.propertiesButtons-linkButton-empty.toggle-off {
color: white;
@@ -111,7 +111,7 @@ $linkGap : 3px;
margin-left: 4px;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index d09d949ff..4df3e4f00 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -86,7 +86,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable openSlideOptions: boolean = false;
@observable inOptions: boolean = false;
- @observable _controlBtn: boolean = false;
+ @observable _controlButton: boolean = false;
@observable _lock: boolean = false;
componentDidMount() {
@@ -540,7 +540,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const formatInstance = InkStrokeProperties.Instance;
return !formatInstance ? (null) : <div className="inking-button">
<Tooltip title={<div className="dash-tooltip">{"Edit points"}</div>}>
- <div className="inking-button-points" onPointerDown={action(() => formatInstance._controlBtn = !formatInstance._controlBtn)} style={{ backgroundColor: formatInstance._controlBtn ? "black" : "" }}>
+ <div className="inking-button-points" onPointerDown={action(() => formatInstance._controlButton = !formatInstance._controlButton)} style={{ backgroundColor: formatInstance._controlButton ? "black" : "" }}>
<FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
</div>
</Tooltip>
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 47a4a192c..55f6b8e3c 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -1,4 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Colors } from './global/globalEnums';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import 'golden-layout/src/css/goldenlayout-base.css';
import 'golden-layout/src/css/goldenlayout-dark-theme.css';
@@ -97,14 +98,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case StyleProp.Color:
const docColor: Opt<string> = StrCast(doc?.[fieldKey + "color"], StrCast(doc?._color));
if (docColor) return docColor;
- const backColor = backgroundCol();// || (darkScheme() ? "black" : "white");
+ const backColor = backgroundCol();
if (!backColor) return undefined;
const nonAlphaColor = backColor.startsWith("#") ? (backColor as string).substring(0, 7) :
backColor.startsWith("rgba") ? backColor.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : backColor
const col = Color(nonAlphaColor).rgb();
const colsum = (col.red() + col.green() + col.blue());
- if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black";
- return "white";
+ if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return Colors.DARK_GRAY;
+ return Colors.WHITE;
case StyleProp.Hidden: return BoolCast(doc?._hidden);
case StyleProp.BorderRounding: return StrCast(doc?.[fieldKey + "borderRounding"]);
case StyleProp.TitleHeight: return 15;
@@ -114,30 +115,30 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
case StyleProp.BackgroundColor: {
let docColor: Opt<string> = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor, isCaption ? "rgba(0,0,0,0.4)" : ""));
- if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey";
+ if (MainView.Instance.LastButton === doc) return darkScheme() ? Colors.MEDIUM_GRAY : Colors.LIGHT_GRAY;
switch (doc?.type) {
case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break;
- case DocumentType.PRES: docColor = docColor || (darkScheme() ? "#3e3e3e" : "white"); break;
- case DocumentType.FONTICON: docColor = docColor || "black"; break;
- case DocumentType.RTF: docColor = docColor || (darkScheme() ? "#2d2d2d" : "#f1efeb"); break;
- case DocumentType.FILTER: docColor = docColor || (darkScheme() ? "#2d2d2d" : "rgba(105, 105, 105, 0.432)"); break;
+ case DocumentType.PRES: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); break;
+ case DocumentType.FONTICON: docColor = docColor || Colors.DARK_GRAY; break;
+ case DocumentType.RTF: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break;
+ case DocumentType.FILTER: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : "rgba(105, 105, 105, 0.432)"); break;
case DocumentType.INK: docColor = doc?.isInkMask ? "rgba(0,0,0,0.7)" : undefined; break;
case DocumentType.SLIDER: break;
case DocumentType.EQUATION: docColor = docColor || "transparent"; break;
case DocumentType.LABEL: docColor = docColor || (doc.annotationOn !== undefined ? "rgba(128, 128, 128, 0.18)" : undefined); break;
- case DocumentType.BUTTON: docColor = docColor || (darkScheme() ? "#2d2d2d" : "lightgray"); break;
- case DocumentType.LINKANCHOR: docColor = isAnchor ? "lightblue" : "transparent"; break;
+ case DocumentType.BUTTON: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break;
+ case DocumentType.LINKANCHOR: docColor = isAnchor ? Colors.LIGHT_BLUE : "transparent"; break;
case DocumentType.LINK: docColor = (isAnchor ? docColor : "") || "transparent"; break;
case DocumentType.IMG:
case DocumentType.WEB:
case DocumentType.PDF:
case DocumentType.SCREENSHOT:
- case DocumentType.VID: docColor = docColor || (darkScheme() ? "#2d2d2d" : "lightgray"); break;
+ case DocumentType.VID: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break;
case DocumentType.COL:
if (StrCast(Doc.LayoutField(doc)).includes("SliderBox")) break;
- docColor = docColor ? docColor :
+ docColor = docColor ? Colors.DARK_GRAY :
doc?._isGroup ? "#00000004" : // very faint highlight to show bounds of group
- (Doc.IsSystem(doc) ? (darkScheme() ? "rgb(62,62,62)" : "lightgrey") : // system docs (seen in treeView) get a grayish background
+ (Doc.IsSystem(doc) ? (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY) : // system docs (seen in treeView) get a grayish background
isBackground() ? "cyan" : // ?? is there a good default for a background collection
doc.annotationOn ? "#00000015" : // faint interior for collections on PDFs, images, etc
StrCast((props?.renderDepth || 0) > 0 ?
@@ -145,7 +146,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
Doc.UserDoc().activeCollectionBackground));
break;
//if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)";
- default: docColor = docColor || (darkScheme() ? "black" : "white"); break;
+ default: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); break;
}
if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor.toLowerCase()).fade(0.5).toString();
return docColor;
@@ -159,7 +160,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case DocumentType.COL:
return StrCast(doc?.boxShadow,
isBackground() || doc?._isGroup || docProps?.LayoutTemplateString ? undefined : // groups have no drop shadow -- they're supposed to be "invisible". LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
- `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`);
+ `${darkScheme() ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`);
case DocumentType.LABEL:
if (doc?.annotationOn !== undefined) return "black 2px 2px 1px";
diff --git a/src/client/views/TemplateMenu.scss b/src/client/views/TemplateMenu.scss
index bbed8cd96..f81cbdaab 100644
--- a/src/client/views/TemplateMenu.scss
+++ b/src/client/views/TemplateMenu.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
.templating-menu {
position: absolute;
pointer-events: auto;
@@ -24,7 +24,7 @@
cursor: pointer;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
}
}
@@ -32,7 +32,7 @@
.template-list {
font-family: $sans-serif;
font-size: 12px;
- background-color: $light-color-secondary;
+ background-color: $light-gray;
padding: 2px 12px;
list-style: none;
position: relative;
diff --git a/src/client/views/_nodeModuleOverrides.scss b/src/client/views/_nodeModuleOverrides.scss
index b8a7db034..56346b68b 100644
--- a/src/client/views/_nodeModuleOverrides.scss
+++ b/src/client/views/_nodeModuleOverrides.scss
@@ -2,7 +2,7 @@
// goldenlayout stuff
div .lm_header {
- background: $dark-color;
+ background: $dark-gray;
}
.lm_tab {
diff --git a/src/client/views/animationtimeline/Keyframe.scss b/src/client/views/animationtimeline/Keyframe.scss
index 84c8de287..38eb103c6 100644
--- a/src/client/views/animationtimeline/Keyframe.scss
+++ b/src/client/views/animationtimeline/Keyframe.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
$timelineColor: #9acedf;
@@ -15,11 +15,11 @@ $timelineDark: #77a1aa;
height: 200px;
top: 50%;
position: relative;
- background-color: $light-color;
+ background-color: $white;
.menutable {
tr:nth-child(odd) {
- background-color: $light-color-secondary;
+ background-color: $light-gray;
}
}
}
@@ -67,7 +67,7 @@ $timelineDark: #77a1aa;
height: 100%;
position: absolute;
pointer-events: none;
- background: linear-gradient(to left, $timelineColor 10%, $light-color);
+ background: linear-gradient(to left, $timelineColor 10%, $white);
}
.fadeRight {
@@ -75,7 +75,7 @@ $timelineDark: #77a1aa;
height: 100%;
position: absolute;
pointer-events: none;
- background: linear-gradient(to right, $timelineColor 10%, $light-color);
+ background: linear-gradient(to right, $timelineColor 10%, $white);
}
.divider {
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index e84022366..82b0218bf 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import "./Keyframe.scss";
import "./Timeline.scss";
-import "../globalCssVariables.scss";
+import "../global/globalCssVariables.scss";
import { observer } from "mobx-react";
import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction, trace } from "mobx";
import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../fields/Doc";
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss
index f90249771..48422b789 100644
--- a/src/client/views/animationtimeline/Timeline.scss
+++ b/src/client/views/animationtimeline/Timeline.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
$timelineColor: #9acedf;
$timelineDark: #77a1aa;
@@ -161,7 +161,7 @@ $timelineDark: #77a1aa;
width: 100%;
height: 300px;
position: absolute;
- background-color: $light-color-secondary;
+ background-color: $light-gray;
border-bottom: 2px solid $timelineDark;
transition: transform 500ms ease;
@@ -251,7 +251,7 @@ $timelineDark: #77a1aa;
top: 0px;
width: 100px;
height: 30%;
- border: 1px solid $dark-color;
+ border: 1px solid $dark-gray;
font-size: 12px;
line-height: 11px;
background-color: $timelineDark;
diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss
index 7ee0a43d5..43a89419e 100644
--- a/src/client/views/animationtimeline/TimelineMenu.scss
+++ b/src/client/views/animationtimeline/TimelineMenu.scss
@@ -1,10 +1,10 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
.timeline-menu-container{
position: absolute;
display: flex;
- box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+ box-shadow: $medium-gray 0.2vw 0.2vw 0.4vw;
flex-direction: column;
background: whitesmoke;
z-index: 10000;
@@ -39,7 +39,7 @@
border-top-left-radius: 15px;
border-top-right-radius: 15px;
text-transform: uppercase;
- background: $dark-color;
+ background: $dark-gray;
letter-spacing: 2px;
.timeline-menu-header-desc{
@@ -79,10 +79,10 @@
.timeline-menu-item:hover {
border-width: .11px;
border-style: none;
- border-color: $intermediate-color;
+ border-color: $medium-gray;
border-bottom-style: solid;
border-top-style: solid;
- background: $darker-alt-accent;
+ background: $medium-blue;
}
.timeline-menu-desc {
diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss
index 283163ea7..c8d96c399 100644
--- a/src/client/views/animationtimeline/TimelineOverview.scss
+++ b/src/client/views/animationtimeline/TimelineOverview.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
$timelineColor: #9acedf;
$timelineDark: #77a1aa;
diff --git a/src/client/views/animationtimeline/Track.scss b/src/client/views/animationtimeline/Track.scss
index aec587a79..f45e0556d 100644
--- a/src/client/views/animationtimeline/Track.scss
+++ b/src/client/views/animationtimeline/Track.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
.track-container {
@@ -6,8 +6,8 @@
.inner {
top: 0px;
width: calc(100%);
- background-color: $light-color;
- border: 1px solid $dark-color;
+ background-color: $white;
+ border: 1px solid $dark-gray;
position: relative;
z-index: 100;
}
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index f4736eb29..a054f0ae1 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -1,4 +1,4 @@
-@import "../../views/globalCssVariables.scss";
+@import "../../views/global/globalCssVariables.scss";
.lm_title {
@@ -110,7 +110,7 @@
}
.flexlayout__splitter {
- background-color: black;
+ background-color: $dark-gray;
}
.flexlayout__splitter:hover {
@@ -179,7 +179,7 @@
position: absolute;
box-sizing: border-box;
background-color: #222;
- color: black;
+ color: $dark-gray;
}
.flexlayout__tab_button {
@@ -268,7 +268,7 @@
}
.flexlayout__tab_header_outer {
- background-color: black;
+ background-color: $dark-gray;
position: absolute;
left: 0;
right: 0;
@@ -332,28 +332,28 @@
}
.flexlayout__border_top {
- background-color: black;
+ background-color: $dark-gray;
border-bottom: 1px solid #ddd;
box-sizing: border-box;
overflow: hidden;
}
.flexlayout__border_bottom {
- background-color: black;
+ background-color: $dark-gray;
border-top: 1px solid #333;
box-sizing: border-box;
overflow: hidden;
}
.flexlayout__border_left {
- background-color: black;
+ background-color: $dark-gray;
border-right: 1px solid #333;
box-sizing: border-box;
overflow: hidden;
}
.flexlayout__border_right {
- background-color: black;
+ background-color: $dark-gray;
border-left: 1px solid #333;
box-sizing: border-box;
overflow: hidden;
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index ca72b98a5..ec8805907 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
@import "../_nodeModuleOverrides";
.collectionLinearView-outer {
@@ -12,8 +12,8 @@
align-items: center;
>span {
- background: $dark-color;
- color: $light-color;
+ background: $dark-gray;
+ color: $white;
border-radius: 18px;
margin-right: 6px;
cursor: pointer;
@@ -63,8 +63,8 @@
>label {
margin-top: "auto";
margin-bottom: "auto";
- background: $dark-color;
- color: $light-color;
+ background: $dark-gray;
+ color: $white;
display: inline-block;
border-radius: 18px;
font-size: 12.5px;
@@ -82,7 +82,7 @@
}
label:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.15);
}
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index dc5231a3a..c0fc774d3 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -1,5 +1,4 @@
-@import "../globalCssVariables";
-
+@import "../global/globalCssVariables";
.collectionMenu-cont {
position: relative;
@@ -8,8 +7,8 @@
opacity: 0.9;
z-index: 901;
transition: top .5s;
- background: #323232;
- color: white;
+ background: $dark-gray;
+ color: $white;
transform-origin: top left;
top: 0;
width: 100%;
@@ -18,7 +17,7 @@
border-radius: 100%;
width: 18px;
height: 18px;
- border: solid 1px #f5f5f5;
+ border: solid 1px $white;
display: flex;
align-items: center;
justify-content: center;
@@ -28,7 +27,7 @@
border-radius: 100%;
width: 70%;
height: 70%;
- background: white;
+ background: $white;
}
.collectionMenu {
@@ -43,7 +42,7 @@
margin-left: 3px;
margin-right: 3px;
width: 1.5px;
- background-color: #656060;
+ background-color: $medium-gray;
}
.collectionViewBaseChrome {
@@ -51,11 +50,11 @@
align-items: center;
.collectionViewBaseChrome-viewPicker {
- font-size: 75%;
- outline-color: black;
- color: white;
+ font-size: $small-text;
+ outline-color: $black;
+ color: $white;
border: none;
- background: #323232;
+ background: $dark-gray;
}
.collectionViewBaseChrome-viewPicker:focus {
@@ -64,16 +63,16 @@
}
.collectionViewBaseChrome-viewPicker:active {
- outline-color: black;
+ outline-color: $black;
}
.collectionViewBaseChrome-button {
- font-size: 75%;
+ font-size: $small-text;
text-transform: uppercase;
letter-spacing: 2px;
- background: rgb(238, 238, 238);
- color: purple;
- outline-color: black;
+ background: $white;
+ color: $pink;
+ outline-color: $black;
border: none;
padding: 12px 10px 11px 10px;
margin-left: 10px;
@@ -82,11 +81,11 @@
.collectionViewBaseChrome-cmdPicker {
margin-left: 3px;
margin-right: 0px;
- font-size: 75%;
+ font-size: $small-text;
text-transform: capitalize;
- color: white;
+ color: $white;
border: none;
- background: #323232;
+ background: $dark-gray;
}
.collectionViewBaseChrome-cmdPicker:focus {
@@ -105,7 +104,7 @@
overflow: hidden;
.commandEntry-drop {
- color: white;
+ color: $white;
width: 30px;
margin-top: auto;
margin-bottom: auto;
@@ -113,11 +112,11 @@
}
.commandEntry-outerDiv:hover{
- background-color: rgba(0,0,0,0.2);
+ background-color: $drop-shadow;
.collectionViewBaseChrome-viewPicker,
.collectionViewBaseChrome-cmdPicker{
- background: rgb(41,41,41);
+ background: $dark-gray;
}
}
@@ -142,7 +141,7 @@
height: 100%;
display: flex;
background: transparent;
- color: grey;
+ color: $medium-gray;
justify-content: center;
}
@@ -150,31 +149,31 @@
margin-left: 5px;
display: grid;
border: none;
- border-right: solid gray 1px;
+ border-right: solid $medium-gray 1px;
.collectionViewBaseChrome-filterIcon {
position: relative;
display: flex;
margin: auto;
- background: #323232;
- color: white;
+ background: $dark-gray;
+ color: $white;
width: 30px;
height: 30px;
align-items: center;
justify-content: center;
border: none;
- border-right: solid gray 1px;
+ border-right: solid $medium-gray 1px;
}
.collectionViewBaseChrome-viewSpecsInput {
padding: 12px 10px 11px 10px;
border: 0px;
- color: grey;
+ color: $medium-gray;
text-align: center;
letter-spacing: 2px;
- outline-color: black;
- font-size: 75%;
- background: rgb(238, 238, 238);
+ outline-color: $black;
+ font-size: $small-text;
+ background: $white;
height: 100%;
width: 75px;
}
@@ -187,8 +186,8 @@
z-index: 100;
display: flex;
flex-direction: column;
- background: rgb(238, 238, 238);
- box-shadow: grey 2px 2px 4px;
+ background: $white;
+ box-shadow: $medium-gray 2px 2px 4px;
.qs-datepicker {
left: unset;
@@ -204,13 +203,13 @@
.collectionViewBaseChrome-viewSpecsMenu-rowLeft,
.collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
.collectionViewBaseChrome-viewSpecsMenu-rowRight {
- font-size: 75%;
+ font-size: $small-text;
letter-spacing: 2px;
- color: grey;
+ color: $medium-gray;
margin-left: 10px;
padding: 5px;
border: none;
- outline-color: black;
+ outline-color: $black;
}
}
@@ -236,19 +235,19 @@
margin-left: 10;
.collectionGridViewChrome-viewPicker {
- font-size: 75%;
+ font-size: $small-text;
//text-transform: uppercase;
//letter-spacing: 2px;
- background: #121721;
- color: white;
- outline-color: black;
- color: white;
+ background: $dark-gray;
+ color: $white;
+ outline-color: $black;
+ color: $white;
border: none;
- border-right: solid gray 1px;
+ border-right: solid $medium-gray 1px;
}
.collectionGridViewChrome-viewPicker:active {
- outline-color: black;
+ outline-color: $black;
}
.grid-control {
@@ -268,11 +267,11 @@
.collectionGridViewChrome-entryBox {
width: 50%;
- color: black;
+ color: $black;
}
.collectionGridViewChrome-columnButton {
- color: black;
+ color: $black;
}
}
}
@@ -302,7 +301,7 @@
align-items: center;
display: flex;
grid-auto-columns: auto;
- font-size: 75%;
+ font-size: $small-text;
letter-spacing: 2px;
.collectionStackingViewChrome-pivotField-label,
@@ -311,7 +310,7 @@
grid-column: 1;
margin-right: 7px;
user-select: none;
- font-family: 'Roboto';
+ font-family: $sans-serif;
letter-spacing: normal;
}
@@ -329,13 +328,13 @@
}
.collectionStackingViewChrome-sortIcon:hover {
- background-color: rgba(0,0,0,0.2);
+ background-color: $drop-shadow;
}
.collectionStackingViewChrome-pivotField,
.collectionTreeViewChrome-pivotField,
.collection3DCarouselViewChrome-scrollSpeed {
- color: white;
+ color: $white;
grid-column: 2;
grid-row: 1;
width: 90%;
@@ -344,7 +343,7 @@
height: 80%;
border-radius: 7px;
align-items: center;
- background: #eeeeee;
+ background: $white;
.editable-view-input,
input,
@@ -352,16 +351,16 @@
.editableView-container-editing {
margin: auto;
border: 0px;
- color: grey !important;
+ color: $light-gray !important;
text-align: center;
letter-spacing: 2px;
- outline-color: black;
+ outline-color: $black;
height: 100%;
}
.react-autosuggest__container {
margin: 0;
- color: grey;
+ color: $medium-gray;
padding: 0px;
}
}
@@ -407,11 +406,11 @@
}
.switchToText {
- color: $main-accent;
+ color: $medium-gray;
}
.switchToText:hover {
- color: $dark-color;
+ color: $dark-gray;
}
}
@@ -424,11 +423,11 @@
.collectionMenu-urlInput {
padding: 12px 10px 11px 10px;
border: 0px;
- color: black;
- font-size: 10px;
+ color: $black;
+ font-size: $small-text;
letter-spacing: 2px;
- outline-color: black;
- background: rgb(238, 238, 238);
+ outline-color: $black;
+ background: $white;
width: 100%;
min-width: 350px;
margin-right: 10px;
@@ -477,10 +476,10 @@
width: 20;
height: 30;
bottom: 0;
- background: #323232;
+ background: $dark-gray;
display: inline-flex;
align-items: center;
- color: white;
+ color: $white;
}
.backKeyframe {
@@ -502,13 +501,13 @@
margin: auto;
}
- border-right: solid gray 1px;
+ border-right: solid $medium-gray 1px;
}
}
.collectionSchemaViewChrome-cont {
display: flex;
- font-size: 10.5px;
+ font-size: $small-text;
.collectionSchemaViewChrome-toggle {
display: flex;
@@ -527,19 +526,19 @@
.collectionSchemaViewChrome-toggler {
width: 100px;
height: 35px;
- background-color: black;
+ background-color: $black;
position: relative;
}
.collectionSchemaViewChrome-togglerButton {
width: 47px;
height: 30px;
- background-color: $light-color-secondary;
+ background-color: $light-gray;
// position: absolute;
transition: all 0.5s ease;
// top: 3px;
margin-top: 3px;
- color: gray;
+ color: $medium-gray;
letter-spacing: 2px;
text-transform: uppercase;
display: flex;
@@ -579,7 +578,7 @@
}
.react-autosuggest__input {
- border: 1px solid #aaa;
+ border: 1px solid $light-gray;
border-radius: 4px;
width: 100%;
}
@@ -603,11 +602,11 @@
overflow-y: auto;
max-height: 400px;
width: 180px;
- border: 1px solid #aaa;
- background-color: #fff;
- font-family: Helvetica, sans-serif;
+ border: 1px solid $light-gray;
+ background-color: $white;
+ font-family: $sans-serif;
font-weight: 300;
- font-size: 16px;
+ font-size: $large-header;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
z-index: 2;
@@ -625,5 +624,5 @@
}
.react-autosuggest__suggestion--highlighted {
- background-color: #ddd;
+ background-color: $light-gray;
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 8f2847139..e1e04915a 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -11,12 +11,13 @@ import { listSpec } from "../../../fields/Schema";
import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { Cast, NumCast } from "../../../fields/Types";
import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, emptyPath, returnFalse, setupMoveUpEvents, returnEmptyDoclist, returnTrue } from "../../../Utils";
+import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../Utils";
+import { DocUtils } from "../../documents/Documents";
import { SelectionManager } from "../../util/SelectionManager";
import { SnappingManager } from "../../util/SnappingManager";
import { Transform } from "../../util/Transform";
import { undoBatch } from "../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss';
+import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss';
import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
import '../DocumentDecorations.scss';
@@ -24,8 +25,7 @@ import { DocumentView } from "../nodes/DocumentView";
import { DefaultStyleProvider } from "../StyleProvider";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
-import { SchemaTable } from "./SchemaTable";
-import { DocUtils } from "../../documents/Documents";
+import { SchemaTable } from "../collections/collectionSchema/SchemaTable";
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
export enum ColumnType {
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 9f56a0c0e..4b123c8b6 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.collectionMasonryView {
display: inline;
@@ -96,8 +96,8 @@
height: 2vw;
width: 100%;
font-family: $sans-serif;
- background: $dark-color;
- color: $light-color;
+ background: $dark-gray;
+ color: $white;
}
.collectionStackingView-columnDragger {
@@ -128,7 +128,7 @@
margin-left: 2px;
margin-right: 2px;
margin-top: 2px;
- background: $main-accent;
+ background: $medium-gray;
height: 5px;
&.active {
@@ -180,11 +180,11 @@
.collectionStackingView-sectionHeader {
text-align: center;
margin: auto;
- background: $main-accent;
+ background: $medium-gray;
// overflow: hidden; overflow is visible so the color menu isn't hidden -ftong
.editableView-input {
- color: black;
+ color: $dark-gray;
}
.editableView-input:hover,
@@ -205,7 +205,7 @@
display: flex;
align-items: center;
justify-content: center;
- color: black;
+ color: $dark-gray;
.editableView-container-editing-oneLine,
.editableView-container-editing {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 30f8e0112..7aa8dfd56 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -480,7 +480,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
if (value && this.columnHeaders) {
const schemaHdrField = new SchemaHeaderField(value);
this.columnHeaders.push(schemaHdrField);
- DocUtils.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: schemaHdrField.color }]);
+ DocUtils.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: "schemaHdrField.color" }]);
return true;
}
return false;
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 72ab51784..ec461ab94 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.collectionTreeView-dropTarget {
border-width: $COLLECTION_BORDER_WIDTH;
@@ -12,7 +12,7 @@
top: 0;
padding-left: 10px;
padding-right: 10px;
- background: $light-color-secondary;
+ background: $light-gray;
font-size: 13px;
overflow: auto;
user-select: none;
@@ -40,7 +40,7 @@
}
.delete-button {
- color: $intermediate-color;
+ color: $medium-gray;
// float: right;
margin-left: 15px;
// margin-top: 3px;
@@ -71,7 +71,7 @@
.collectionTreeView-subtitle {
font-style: italic;
font-size: 8pt;
- color: $intermediate-color;
+ color: $medium-gray;
}
.docContainer {
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index a5aef86de..5db489c0a 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -1,8 +1,8 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.collectionView {
border-width: 0;
- border-color: $light-color-secondary;
+ border-color: $light-gray;
border-style: solid;
border-radius: 0 0 $border-radius $border-radius;
box-sizing: border-box;
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index 3f6fc8b0c..1ebc5873e 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.treeView-label {
max-height: 1.5em;
@@ -14,7 +14,7 @@
.bullet-outline {
position: relative;
width: $TREE_BULLET_WIDTH;
- color: $intermediate-color;
+ color: $medium-gray;
transform: scale(0.5);
display: inline-flex;
align-items: center;
@@ -45,7 +45,7 @@
.bullet {
position: relative;
width: $TREE_BULLET_WIDTH;
- color: $intermediate-color;
+ color: $medium-gray;
margin-top: 3px;
transform: scale(1.3, 1.3);
border: #80808030 1px solid;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index c1125c233..401bdcb02 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -20,7 +20,7 @@ import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch, UndoManager } from '../../util/UndoManager';
import { EditableView } from "../EditableView";
-import { TREE_BULLET_WIDTH } from '../globalCssVariables.scss';
+import { TREE_BULLET_WIDTH } from '../global/globalCssVariables.scss';
import { DocumentView, DocumentViewProps, StyleProviderFunc, DocumentViewInternal } from '../nodes/DocumentView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
index c5b8fc5e8..5fa01b102 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
.collectionFreeFormRemoteCursors-cont {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index eb0538c41..79e063f7f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -1,4 +1,4 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables";
.collectionfreeformview-none {
position: inherit;
@@ -226,7 +226,7 @@
// linear-gradient(to bottom, $light-color-secondary 1px, transparent 1px);
// background-size: 30px 30px;
// }
- border: 0px solid $light-color-secondary;
+ border: 0px solid $light-gray;
border-radius: inherit;
box-sizing: border-box;
position: absolute;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index accb80c5a..a4e310e6c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -28,7 +28,7 @@ import { SelectionManager } from "../../../util/SelectionManager";
import { SnappingManager } from "../../../util/SnappingManager";
import { Transform } from "../../../util/Transform";
import { undoBatch } from "../../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
+import { COLLECTION_BORDER_WIDTH } from "../../../views/global/globalCssVariables.scss";
import { Timeline } from "../../animationtimeline/Timeline";
import { ContextMenu } from "../../ContextMenu";
import { DocumentDecorations } from "../../DocumentDecorations";
@@ -834,10 +834,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
map(doc => ({ ...this.childDataProvider(doc, ""), ...this.childSizeProvider(doc, "") }));
if (measuredDocs.length) {
const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) => // computes range of content
- ({
- xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) },
- yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) }
- })
+ ({
+ xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) },
+ yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) }
+ })
, {
xrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE },
yrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE }
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
index f75179cea..90f64f163 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx
@@ -26,7 +26,7 @@ import { SnappingManager } from "../../../util/SnappingManager";
import { undoBatch } from "../../../util/UndoManager";
import '../../../views/DocumentDecorations.scss';
import { EditableView } from "../../EditableView";
-import { MAX_ROW_HEIGHT } from '../../globalCssVariables.scss';
+import { MAX_ROW_HEIGHT } from '../../global/globalCssVariables.scss';
import { DocumentIconContainer } from "../../nodes/DocumentIcon";
import { OverlayView } from "../../OverlayView";
import "./CollectionSchemaView.scss";
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index b57fee0e4..40cdcd14b 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -1,7 +1,7 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables.scss";
.collectionSchemaView-container {
border-width: $COLLECTION_BORDER_WIDTH;
- border-color: $intermediate-color;
+ border-color: $medium-gray;
border-style: solid;
border-radius: $border-radius;
box-sizing: border-box;
@@ -33,13 +33,13 @@
cursor: col-resize;
}
// .documentView-node:first-child {
- // background: $light-color;
+ // background: $white;
// }
}
.collectionSchemaView-searchContainer {
border-width: $COLLECTION_BORDER_WIDTH;
- border-color: $intermediate-color;
+ border-color: $medium-gray;
border-style: solid;
border-radius: $border-radius;
box-sizing: border-box;
@@ -72,7 +72,7 @@
cursor: col-resize;
}
// .documentView-node:first-child {
- // background: $light-color;
+ // background: $white;
// }
}
@@ -245,7 +245,7 @@ button.add-column {
}
}
label {
- color: $main-accent;
+ color: $medium-gray;
font-weight: normal;
letter-spacing: 2px;
text-transform: uppercase;
@@ -260,11 +260,11 @@ button.add-column {
background-color: white;
transition: background-color 0.2s;
&:hover {
- background-color: $light-color-secondary;
+ background-color: $light-gray;
}
&.active {
font-weight: bold;
- border: 2px solid $light-color-secondary;
+ border: 2px solid $light-gray;
}
svg {
color: gray;
@@ -277,7 +277,7 @@ button.add-column {
//width: 100%;
background-color: white;
input {
- border: 2px solid $light-color-secondary;
+ border: 2px solid $light-gray;
padding: 3px;
height: 28px;
font-weight: bold;
@@ -303,7 +303,7 @@ button.add-column {
border-top: 0;
}
&:hover {
- background-color: $light-color-secondary;
+ background-color: $light-gray;
}
}
}
@@ -329,7 +329,7 @@ button.add-column {
height: 100%;
background-color: white;
&.row-focused .rt-td {
- background-color: #bfffc0; //$light-color-secondary;
+ background-color: #bfffc0; //$light-gray;
}
&.row-wrapped {
.rt-td {
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index ef28f75c8..585cda729 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -11,21 +11,21 @@ import { listSpec } from "../../../../fields/Schema";
import { PastelSchemaPalette, SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
import { Cast, NumCast } from "../../../../fields/Types";
import { TraceMobx } from "../../../../fields/util";
-import { emptyFunction, emptyPath, returnFalse, setupMoveUpEvents, returnEmptyDoclist, returnTrue } from "../../../../Utils";
+import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents } from "../../../../Utils";
+import { DocUtils } from "../../../documents/Documents";
import { SelectionManager } from "../../../util/SelectionManager";
import { SnappingManager } from "../../../util/SnappingManager";
import { Transform } from "../../../util/Transform";
import { undoBatch } from "../../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../globalCssVariables.scss';
+import '../../../views/DocumentDecorations.scss';
import { ContextMenu } from "../../ContextMenu";
import { ContextMenuProps } from "../../ContextMenuItem";
-import '../../../views/DocumentDecorations.scss';
+import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../global/globalCssVariables.scss';
import { DocumentView } from "../../nodes/DocumentView";
import { DefaultStyleProvider } from "../../StyleProvider";
-import "./CollectionSchemaView.scss";
import { CollectionSubView } from "../CollectionSubView";
+import "./CollectionSchemaView.scss";
import { SchemaTable } from "./SchemaTable";
-import { DocUtils } from "../../../documents/Documents";
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
export enum ColumnType {
diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx
index 0d5c9e077..de08c327a 100644
--- a/src/client/views/collections/collectionSchema/SchemaTable.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx
@@ -21,7 +21,7 @@ import { DocumentType } from "../../../documents/DocumentTypes";
import { CompileScript, Transformer, ts } from "../../../util/Scripting";
import { Transform } from "../../../util/Transform";
import { undoBatch } from "../../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../globalCssVariables.scss';
+import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../global/globalCssVariables.scss';
import { ContextMenu } from "../../ContextMenu";
import '../../../views/DocumentDecorations.scss';
import { DocumentView } from "../../nodes/DocumentView";
diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index ccc9306c4..ead5e166e 100644
--- a/src/client/views/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -1,28 +1,37 @@
@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Crimson+Text:400,400i,700");
// colors
-$light-color: #fcfbf7;
-$light-color-secondary:#f1efeb;
-//$main-accent: #61aaa3;
-$main-accent: #aaaaa3;
-// $alt-accent: #cdd5ec;
-// $alt-accent: #cdeceb;
-//$alt-accent: #59dff7;
-$alt-accent: #c2c2c5;
-$lighter-alt-accent: rgb(207, 220, 240);
-$darker-alt-accent: #b2cef8;
-$intermediate-color: #9c9396;
-$dark-color: #121721;
-$link-color: #add8e6;
-$antimodemenu-height: 35px;
+$white: #ffffff;
+$light-gray:#dfdfdf;
+$medium-gray: #9F9F9F;
+$dark-gray: #323232;
+$black: #000000;
+
+$light-blue: #BDDDF5;
+$medium-blue: #4476F7;
+$pink: #E0217D;
+$yellow: #F5D747;
+
+$drop-shadow: "#32323215";
+
+//padding
+$minimum-padding: 4px;
+$medium-padding: 16px;
+$large-padding: 32px;
+
+//icon sizes
+$icon-size: 28px;
+
+$antimodemenu-height: 36px;
+
// fonts
-$sans-serif: "Noto Sans",
-sans-serif;
+$sans-serif: "Noto Sans", sans-serif;
+$large-header: 16px;
+$body-text: 12px;
+$small-text: 9px;
// $sans-serif: "Roboto Slab", sans-serif;
-$serif: "Crimson Text",
-serif;
+
// misc values
$border-radius: 0.3em;
-//
$search-thumnail-size: 130;
// dragged items
@@ -35,7 +44,7 @@ $docDecorations-zindex: 998; // then doc decorations appear over everything else
$remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right?
$COLLECTION_BORDER_WIDTH: 0;
$SCHEMA_DIVIDER_WIDTH: 4;
-$MINIMIZED_ICON_SIZE:25;
+$MINIMIZED_ICON_SIZE:24;
$MAX_ROW_HEIGHT: 44px;
$DFLT_IMAGE_NATIVE_DIM: 900px;
$MENU_PANEL_WIDTH: 60px;
diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/global/globalCssVariables.scss.d.ts
index 11e62e1eb..11e62e1eb 100644
--- a/src/client/views/globalCssVariables.scss.d.ts
+++ b/src/client/views/global/globalCssVariables.scss.d.ts
diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx
new file mode 100644
index 000000000..1e0381c33
--- /dev/null
+++ b/src/client/views/global/globalEnums.tsx
@@ -0,0 +1,34 @@
+export enum Colors {
+ BLACK = "#000000",
+ DARK_GRAY = "#323232",
+ MEDIUM_GRAY = "#9F9F9F",
+ LIGHT_GRAY = "#DFDFDF",
+ WHITE = "#FFFFFF",
+ MEDIUM_BLUE = "#4476F7",
+ LIGHT_BLUE = "#BDDDF5",
+ PINK = "#E0217D",
+ YELLOW = "#F5D747",
+ DROP_SHADOW = "#32323215",
+}
+
+export enum FontSizes {
+ //Bolded
+ LARGE_HEADER = "16px",
+
+ //Bolded or unbolded
+ BODY_TEXT = "12px",
+
+ //Bolded
+ SMALL_TEXT = "9px",
+}
+
+export enum Padding {
+ MINIMUM_PADDING = "4px",
+ SMALL_PADDING = "8px",
+ MEDIUM_PADDING = "16px",
+ LARGE_PADDING = "32px",
+}
+
+export enum IconSizes {
+ ICON_SIZE = "28px",
+} \ No newline at end of file
diff --git a/src/client/views/linking/LinkEditor.scss b/src/client/views/linking/LinkEditor.scss
index 7e6999cdc..839ebf894 100644
--- a/src/client/views/linking/LinkEditor.scss
+++ b/src/client/views/linking/LinkEditor.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.linkEditor {
width: 100%;
@@ -20,7 +20,7 @@
}
.linkEditor-info {
- //border-bottom: 0.5px solid $light-color-secondary;
+ //border-bottom: 0.5px solid $light-gray;
//padding-bottom: 1px;
padding-top: 5px;
padding-left: 5px;
@@ -195,7 +195,7 @@
}
.linkEditor-group {
- background-color: $light-color-secondary;
+ background-color: $light-gray;
padding: 6px;
margin: 3px 0;
border-radius: 3px;
@@ -254,8 +254,8 @@
}
.linkEditor-option {
- background-color: $light-color-secondary;
- border: 1px solid $intermediate-color;
+ background-color: $light-gray;
+ border: 1px solid $medium-gray;
border-top: 0;
padding: 3px;
cursor: pointer;
@@ -272,7 +272,7 @@
.linkEditor-typeButton {
background-color: transparent;
- color: $dark-color;
+ color: $dark-gray;
height: 20px;
padding: 0 3px;
padding-bottom: 2px;
@@ -285,7 +285,7 @@
width: calc(100% - 40px);
&:hover {
- background-color: $light-color;
+ background-color: $white;
}
}
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index a90bf8b0a..a2ea42999 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.linkMenu {
width: auto;
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index 4e13ef8c8..4f9881565 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -1,7 +1,7 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.linkMenu-item {
- // border-top: 0.5px solid $main-accent;
+ // border-top: 0.5px solid $medium-gray;
position: relative;
display: flex;
border-bottom: 0.5px solid black;
@@ -102,7 +102,7 @@
.link-metadata {
padding: 0 10px 0 16px;
margin-bottom: 4px;
- color: $main-accent;
+ color: $medium-gray;
font-style: italic;
font-size: 10.5px;
}
@@ -143,8 +143,8 @@
padding-right: 6px;
border-radius: 50%;
pointer-events: auto;
- background-color: $dark-color;
- color: $light-color;
+ background-color: $dark-gray;
+ color: $white;
font-size: 65%;
transition: transform 0.2s;
text-align: center;
@@ -162,7 +162,7 @@
}
&:hover {
- background: $main-accent;
+ background: $medium-gray;
cursor: pointer;
}
}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index a0a40becb..9b75cd8f9 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -64,6 +64,7 @@ interface HTMLtagProps {
htmltag: string;
onClick?: ScriptField;
onInput?: ScriptField;
+ scaling: number;
}
//"<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} overflow='hidden' position='absolute' width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'> <ImageBox {...props} fieldKey={'data'}/> <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px' transform='translate(-40px, 45px) rotate(-45deg)' position='absolute' color='{this.bannerColor===`green`?`light`:`dark`}blue' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'> {this.title}</HTMLspan></HTMLdiv>"
@@ -82,7 +83,7 @@ interface HTMLtagProps {
export class HTMLtag extends React.Component<HTMLtagProps> {
click = (e: React.MouseEvent) => {
const clickScript = (this.props as any).onClick as Opt<ScriptField>;
- clickScript?.script.run({ this: this.props.Document, self: this.props.RootDoc });
+ clickScript?.script.run({ this: this.props.Document, self: this.props.RootDoc, scale: this.props.scaling });
}
onInput = (e: React.FormEvent<HTMLDivElement>) => {
const onInputScript = (this.props as any).onInput as Opt<ScriptField>;
@@ -90,9 +91,9 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
}
render() {
const style: { [key: string]: any } = {};
- const divKeys = OmitKeys(this.props, ["children", "htmltag", "RootDoc", "Document", "key", "onInput", "onClick", "__proto__"]).omit;
+ const divKeys = OmitKeys(this.props, ["children", "htmltag", "RootDoc", "scaling", "Document", "key", "onInput", "onClick", "__proto__"]).omit;
const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
- return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.props.RootDoc, this: this.props.Document }).result as string || "";
+ return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: "number" })?.script.run({ self: this.props.RootDoc, this: this.props.Document, scale: this.props.scaling }).result as string || "";
};
Object.keys(divKeys).map((prop: string) => {
const p = (this.props as any)[prop] as string;
@@ -184,7 +185,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
// replace HTML<tag> with corresponding HTML tag as in: <HTMLdiv> becomes <HTMLtag Document={props.Document} htmltag='div'>
const replacer2 = (match: any, p1: string, offset: any, string: any) => {
- return `<HTMLtag RootDoc={props.RootDoc} Document={props.Document} htmltag='${p1}'`;
+ return `<HTMLtag RootDoc={props.RootDoc} Document={props.Document} scaling='${this.props.scaling?.() || 1}' htmltag='${p1}'`;
};
layoutFrame = layoutFrame.replace(/<HTML([a-zA-Z0-9_-]+)/g, replacer2);
@@ -200,7 +201,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
if (splits.length > 1) {
const code = XRegExp.matchRecursive(splits[1], "{", "}", "", { valueNames: ["between", "left", "match", "right", "between"] });
layoutFrame = splits[0] + ` ${func}={props.${func}} ` + splits[1].substring(code[1].end + 1);
- return ScriptField.MakeScript(code[1].value, { this: Doc.name, self: Doc.name, value: "string" });
+ return ScriptField.MakeScript(code[1].value, { this: Doc.name, self: Doc.name, scale: "number", value: "string" });
}
return undefined;
// add input function to props
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index 735aa669f..daffaf9e7 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables.scss";
+@import "../global/globalCssVariables.scss";
.documentLinksButton-cont {
@@ -37,7 +37,7 @@
font-weight: bold;
&:hover {
- background: $main-accent;
+ background: $medium-gray;
transform: scale(1.05);
cursor: pointer;
}
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index bdbece621..8f86417d6 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.documentView-effectsWrapper {
border-radius: inherit;
@@ -22,7 +22,7 @@
transition: outline .3s linear;
cursor: grab;
- // background: $light-color; //overflow: hidden;
+ // background: $white; //overflow: hidden;
transform-origin: left top;
&.minimized {
@@ -218,6 +218,6 @@
.documentView-node:first-child {
position: relative;
- background: "#B59B66"; //$light-color;
+ background: "#B59B66"; //$white;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
index 33ac85a0e..718af2c16 100644
--- a/src/client/views/nodes/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox.scss
@@ -1,5 +1,7 @@
+@import "../global/globalCssVariables";
+
.fontIconBox-label {
- color: white;
+ color: $white;
margin-right: 4px;
margin-top: 1px;
position: relative;
@@ -22,8 +24,8 @@
position: absolute;
top: -10px;
right: -10px;
- color: white;
- background: #f44b42;
+ color: $white;
+ background: $pink;
font-weight: 300;
border-radius: 100%;
width: 25px;
@@ -37,7 +39,7 @@
.menuButton-circle,
.menuButton-round {
border-radius: 100%;
- background-color: black;
+ background-color: $dark-gray;
padding: 0;
.fontIconBox-label {
@@ -47,13 +49,14 @@
}
&:hover {
- background-color: #aaaaa3;
+ background-color: $light-gray;
}
}
.menuButton-square {
padding-top: 3px;
padding-bottom: 3px;
+ background-color: $dark-gray;
.fontIconBox-label {
border-radius: 0px;
diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss
index eb7c2f32b..ffcba4981 100644
--- a/src/client/views/nodes/KeyValueBox.scss
+++ b/src/client/views/nodes/KeyValueBox.scss
@@ -1,10 +1,10 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.keyValueBox-cont {
overflow-y: scroll;
width:100%;
height: 100%;
- background-color: $light-color;
- border: 1px solid $intermediate-color;
+ background-color: $white;
+ border: 1px solid $medium-gray;
border-radius: $border-radius;
box-sizing: border-box;
display: inline-block;
@@ -56,8 +56,8 @@ $header-height: 30px;
width:100%;
position: relative;
display: inline-block;
- background: $intermediate-color;
- color: $light-color;
+ background: $medium-gray;
+ color: $white;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 12px;
@@ -66,7 +66,7 @@ $header-height: 30px;
th {
font-weight: normal;
&:first-child {
- border-right: 1px solid $light-color;
+ border-right: 1px solid $white;
}
}
}
@@ -76,9 +76,9 @@ $header-height: 30px;
display: flex;
width:100%;
height:$header-height;
- background: $light-color;
+ background: $white;
.formattedTextBox-cont {
- background: $light-color;
+ background: $white;
}
}
.keyValueBox-cont {
@@ -116,8 +116,8 @@ $header-height: 30px;
display: flex;
width:100%;
height:30px;
- background: $light-color-secondary;
+ background: $light-gray;
.formattedTextBox-cont {
- background: $light-color-secondary;
+ background: $light-gray;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss
index f78767234..5b660e582 100644
--- a/src/client/views/nodes/KeyValuePair.scss
+++ b/src/client/views/nodes/KeyValuePair.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.keyValuePair-td-key {
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 0f46da294..72dec6e4c 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -7,7 +7,7 @@
overflow: hidden;
cursor: auto;
transform-origin: top left;
- z-index: 0;
+ //z-index: 0;
.pdfBox-ui {
position: absolute;
@@ -30,6 +30,7 @@
justify-content: center;
border-radius: 3px;
pointer-events: all;
+ z-index: 1; // so it appears on top of the document's title, if shown
}
.pdfBox-pageNums {
@@ -223,7 +224,7 @@
.pdfBox {
width: 100%;
height: 100%;
- pointer-events: none;
+ //pointer-events: none;
.pdfViewerDash-text {
.textLayer {
display: none;
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 1ba86232b..5d1c5f4eb 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -1,7 +1,4 @@
-$light-blue: #AEDDF8;
-$dark-blue: #5B9FDD;
-$light-background: #ececec;
-$dark-grey: #656565;
+@import "../global/globalCssVariables";
.presBox-cont {
cursor: auto;
@@ -10,7 +7,6 @@ $dark-grey: #656565;
pointer-events: inherit;
z-index: 2;
font-family: Roboto;
- box-shadow: #AAAAAA .2vw .2vw .4vw;
width: 100%;
min-width: 20px;
height: 100%;
@@ -47,8 +43,8 @@ $dark-grey: #656565;
align-items: center;
height: 30px;
width: 100%;
- color: white;
- background-color: #323232;
+ color: $white;
+ background-color: $dark-gray;
.toolbar-button {
cursor: pointer;
@@ -110,7 +106,7 @@ $dark-grey: #656565;
}
.toolbar-divider {
- border-left: solid #ffffff70 0.5px;
+ border-left: solid $medium-gray 0.5px;
height: 20px;
}
}
@@ -118,7 +114,7 @@ $dark-grey: #656565;
.dropdown {
font-size: 10;
margin-left: 5px;
- color: darkgrey;
+ color: $medium-gray;
transition: 0.5s ease;
}
@@ -174,7 +170,7 @@ $dark-grey: #656565;
.ribbon-colorBox {
cursor: pointer;
- border: solid 1px black;
+ border: solid 1px $black;
display: flex;
margin-left: 5px;
margin-top: 5px;
@@ -191,9 +187,9 @@ $dark-grey: #656565;
font-size: 11;
font-weight: 200;
height: 20;
- background-color: #ececec;
- color: black;
- border: solid 1px black;
+ background-color: $white;
+ color: $black;
+ border: solid 1px $black;
display: flex;
margin-left: 5px;
margin-top: 5px;
@@ -220,11 +216,11 @@ $dark-grey: #656565;
align-items: center;
height: 100%;
width: 100%;
- background: black;
+ background: $black;
}
.ribbon-propertyUpDownItem:hover {
- background: darkgrey;
+ background: $medium-gray;
transform: scale(1.05);
}
}
@@ -239,7 +235,7 @@ $dark-grey: #656565;
.multiThumb-slider {
display: grid;
- background-color: $light-background;
+ background-color: $white;
height: 10px;
border-radius: 10px;
overflow: hidden;
@@ -257,8 +253,8 @@ $dark-grey: #656565;
-webkit-appearance: none;
height: 10px;
cursor: ew-resize;
- background: $dark-blue;
- box-shadow: -100vw 0 0 100vw $light-background;
+ background: $medium-blue;
+ box-shadow: -100vw 0 0 100vw $white;
}
.toolbar-slider.end::-webkit-slider-thumb {
@@ -267,7 +263,7 @@ $dark-grey: #656565;
-webkit-appearance: none;
height: 10px;
cursor: ew-resize;
- background: $dark-blue;
+ background: $medium-blue;
box-shadow: -100vw 0 0 100vw $light-blue;
}
}
@@ -282,7 +278,7 @@ $dark-grey: #656565;
height: 10px;
border-radius: 10px;
-webkit-appearance: none;
- background-color: $light-background;
+ background-color: $white;
}
.toolbar-slider:focus {
@@ -301,7 +297,7 @@ $dark-grey: #656565;
-webkit-appearance: none;
height: 10px;
cursor: ew-resize;
- background: $dark-blue;
+ background: $medium-blue;
box-shadow: -100vw 0 0 100vw $light-blue;
}
@@ -318,7 +314,7 @@ $dark-grey: #656565;
width: 15px;
min-width: 15px;
cursor: pointer;
- background: $light-background;
+ background: $white;
}
.presBox-checkbox:focus {
@@ -326,7 +322,7 @@ $dark-grey: #656565;
}
.presBox-checkbox:hover {
- background: #c0c0c0;
+ background: $light-gray;
}
.presBox-checkbox:checked {
@@ -381,9 +377,9 @@ $dark-grey: #656565;
text-align: center;
font-size: 16;
width: 90%;
- color: black;
+ color: $black;
transform: translate(5%, 0px);
- border-bottom: solid 2px darkgrey;
+ border-bottom: solid 2px $medium-gray;
}
@@ -396,8 +392,8 @@ $dark-grey: #656565;
justify-self: left;
margin-top: 5px;
padding-left: 10px;
- background-color: $light-background;
- border: solid 1px black;
+ background-color: $white;
+ border: solid 1px $black;
min-width: 80px;
max-width: 200px;
width: 100%;
@@ -416,7 +412,7 @@ $dark-grey: #656565;
}
.ribbon-frameSelector {
- border: black solid 1px;
+ border: $black solid 1px;
width: 60px;
height: 20px;
margin-top: 5px;
@@ -433,12 +429,12 @@ $dark-grey: #656565;
cursor: pointer;
position: relative;
height: 100%;
- background: $light-background;
+ background: $white;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
- color: black;
+ color: $black;
}
.numKeyframe {
@@ -446,7 +442,7 @@ $dark-grey: #656565;
font-size: 10;
font-weight: 600;
position: relative;
- color: black;
+ color: $black;
display: flex;
width: 100%;
height: 100%;
@@ -489,7 +485,7 @@ $dark-grey: #656565;
padding-left: 10;
padding-right: 10;
border-radius: 10px;
- background-color: #979797;
+ background-color: $medium-gray;
}
.ribbon-final-button:hover {
@@ -508,13 +504,13 @@ $dark-grey: #656565;
align-items: center;
margin-bottom: 5px;
height: 25px;
- color: lightgrey;
+ color: $light-gray;
width: 100%;
max-width: 120;
padding-left: 10;
padding-right: 10;
border-radius: 10px;
- background-color: black;
+ background-color: $black;
}
.ribbon-final-button-hidden:hover {
@@ -525,15 +521,15 @@ $dark-grey: #656565;
.ribbon-frameList {
width: calc(100% - 5px);
height: 50px;
- background-color: #ececec;
- border: 1px solid #9f9f9f;
+ background-color: $white;
+ border: 1px solid $medium-gray;
grid-template-rows: max-content;
.frameList-header {
display: grid;
width: 100%;
height: 20px;
- background-color: #9f9f9f;
+ background-color: $medium-gray;
.frameList-headerButtons {
display: flex;
@@ -588,7 +584,7 @@ $dark-grey: #656565;
font-size: 10.5;
font-weight: 300;
height: 20;
- background-color: #979797;
+ background-color: $medium-gray;
color: white;
display: flex;
margin-top: 5px;
@@ -607,8 +603,8 @@ $dark-grey: #656565;
transition: all 0.4s;
font-weight: 400;
opacity: 1;
- color: white;
- background-color: black;
+ color: $white;
+ background-color: $black;
}
.ribbon-toggle {
@@ -616,10 +612,10 @@ $dark-grey: #656565;
font-size: 10.5;
font-weight: 200;
height: 20;
- background-color: $light-background;
+ background-color: $white;
border: solid 1px rgba(0, 0, 0, 0.5);
display: flex;
- color: black;
+ color: $black;
margin-top: 5px;
margin-bottom: 5px;
border-radius: 5px;
@@ -660,13 +656,13 @@ $dark-grey: #656565;
position: relative;
font-size: 13;
padding-bottom: 10px;
- border-bottom: solid 1px $dark-grey;
+ border-bottom: solid 1px $dark-gray;
.presBox-dropdown:hover {
- border: solid 1px $dark-blue;
+ border: solid 1px $medium-blue;
.presBox-dropdownIcon {
- color: $dark-blue;
+ color: $medium-blue;
}
}
@@ -675,12 +671,12 @@ $dark-grey: #656565;
display: grid;
grid-template-columns: auto 20%;
position: relative;
- border: solid 1px black;
- background-color: $light-background;
+ border: solid 1px $black;
+ background-color: $light-gray;
border-radius: 5px;
font-size: 10;
height: 25;
- color: black;
+ color: $black;
padding-left: 5px;
align-items: center;
margin-top: 5px;
@@ -744,7 +740,7 @@ $dark-grey: #656565;
height: 100px;
padding-top: 5px;
padding-bottom: 5px;
- border: solid 1px black;
+ border: solid 1px $black;
// overflow: auto;
::-webkit-scrollbar {
@@ -794,7 +790,7 @@ $dark-grey: #656565;
cursor: pointer;
position: relative;
text-align: center;
- border-left: solid 1px darkgrey;
+ border-left: solid 1px $medium-gray;
width: 20%;
height: 100%;
display: flex;
@@ -825,7 +821,7 @@ $dark-grey: #656565;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
z-index: 200;
background-color: white;
- color: black;
+ color: $black;
position: absolute;
overflow: hidden;
}
@@ -841,12 +837,12 @@ $dark-grey: #656565;
align-items: center;
justify-content: center;
transform: translate(0px, -1px);
- background-color: $light-background;
+ background-color: $white;
width: 40px;
height: 15px;
align-self: center;
justify-self: center;
- border: solid 1px black;
+ border: solid 1px $black;
border-top: 0px;
border-bottom-right-radius: 7px;
border-bottom-left-radius: 7px;
@@ -855,15 +851,15 @@ $dark-grey: #656565;
.layout-container {
padding: 5px;
display: grid;
- background-color: $light-background;
+ background-color: $white;
grid-template-columns: repeat(auto-fit, minmax(90px, 100px));
width: 100%;
- border: solid 1px black;
+ border: solid 1px $black;
min-width: 100px;
overflow: hidden;
.layout:hover {
- border: solid 2px #5c9edd;
+ border: solid 2px $medium-blue;
}
.layout {
@@ -878,7 +874,7 @@ $dark-grey: #656565;
width: 90px;
overflow: hidden;
background-color: white;
- border: solid darkgrey 1px;
+ border: solid $medium-gray 1px;
display: grid;
grid-template-rows: auto;
align-items: center;
@@ -893,7 +889,7 @@ $dark-grey: #656565;
height: 13;
font-size: 12;
display: flex;
- background-color: #f1efec;
+ background-color: #white;
}
.subtitle {
@@ -906,7 +902,7 @@ $dark-grey: #656565;
height: 13;
font-size: 9;
display: flex;
- background-color: #f1efec;
+ background-color: $white;
}
.content {
@@ -919,7 +915,7 @@ $dark-grey: #656565;
height: 13;
font-size: 10;
display: flex;
- background-color: #f1efec;
+ background-color: $white;
height: 33;
text-align: left;
font-size: 8px;
@@ -960,8 +956,8 @@ $dark-grey: #656565;
select {
- background: #323232;
- color: white;
+ background: $dark-gray;
+ color: $white;
}
.presBox-button {
@@ -975,8 +971,8 @@ $dark-grey: #656565;
text-align: center;
letter-spacing: normal;
width: inherit;
- background: #323232;
- color: white;
+ background: $dark-gray;
+ color: $white;
}
.presBox-button.active {
@@ -984,7 +980,7 @@ $dark-grey: #656565;
}
.presBox-button.active:hover {
- background-color: #233163;
+ background-color: $medium-blue;
}
.presBox-button.edit {
@@ -1053,8 +1049,8 @@ $dark-grey: #656565;
font-size: 100;
display: flex;
align-items: center;
- background: #323232;
- color: white;
+ background: $dark-gray;
+ color: $white;
}
.presBox-viewPicker {
@@ -1086,7 +1082,7 @@ $dark-grey: #656565;
top: 10;
opacity: 0.1;
transition: all 0.4s;
- color: white;
+ color: $white;
}
.miniPres:hover {
@@ -1094,8 +1090,8 @@ $dark-grey: #656565;
}
.presPanelOverlay {
- background-color: #323232;
- color: white;
+ background-color: $dark-gray;
+ color: $white;
border-radius: 5px;
grid-template-rows: 100%;
height: 25;
@@ -1129,7 +1125,7 @@ $dark-grey: #656565;
.presPanel-divider {
width: 0.5px;
height: 80%;
- border-right: solid 1px #5a5a5a;
+ border-right: solid 1px $medium-gray;
}
.presPanel-button-frame {
@@ -1161,12 +1157,12 @@ $dark-grey: #656565;
}
.presPanel-button:hover {
- background-color: #5a5a5a;
+ background-color: $medium-gray;
transform: scale(1.2);
}
.presPanel-button-text:hover {
- background-color: #5a5a5a;
+ background-color: $medium-gray;
}
diff --git a/src/client/views/nodes/RadialMenu.scss b/src/client/views/nodes/RadialMenu.scss
index daa620d12..312b51013 100644
--- a/src/client/views/nodes/RadialMenu.scss
+++ b/src/client/views/nodes/RadialMenu.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.radialMenu-cont {
position: absolute;
@@ -53,7 +53,7 @@ s
transition: all .1s;
border-width: .11px;
border-style: none;
- border-color: $intermediate-color; // rgb(187, 186, 186);
+ border-color: $medium-gray; // rgb(187, 186, 186);
// padding: 10px 0px 10px 0px;
white-space: nowrap;
font-size: 13px;
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index ca82c049c..19b69ff5a 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables.scss";
+@import "../global/globalCssVariables.scss";
.webBox {
@@ -17,6 +17,7 @@
justify-content: center;
border-radius: 3px;
pointer-events: all;
+ z-index: 1; // so it appears on top of the document's title, if shown
}
.pdfViewerDash-dragAnnotationBox {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 53aceb533..3cedab1a4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -1,4 +1,4 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables";
.ProseMirror {
width: 100%;
@@ -31,7 +31,7 @@ audiotag:hover {
padding: 0;
border-width: 0px;
border-radius: inherit;
- border-color: $intermediate-color;
+ border-color: $medium-gray;
box-sizing: border-box;
background-color: inherit;
border-style: solid;
@@ -363,7 +363,7 @@ footnote::after {
@media only screen and (max-width: 1000px) {
- @import "../../globalCssVariables";
+ @import "../../global/globalCssVariables";
.ProseMirror {
width: 100%;
@@ -381,7 +381,7 @@ footnote::after {
padding: 0;
border-width: 0px;
border-radius: inherit;
- border-color: $intermediate-color;
+ border-color: $medium-gray;
box-sizing: border-box;
background-color: inherit;
border-style: solid;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 95d8f555c..6dd63fb47 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -71,6 +71,7 @@ export interface FormattedTextBoxProps {
xPadding?: number; // used to override document's settings for xMargin --- see CollectionCarouselView
yPadding?: number;
noSidebar?: boolean;
+ dontScale?: boolean;
dontSelectOnLoad?: boolean; // suppress selecting the text box when loaded (and mark as not being associated with scrollTop document field)
}
export const GoogleRef = "googleDocId";
@@ -126,7 +127,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get scrollHeight() { return NumCast(this.rootDoc[this.fieldKey + "-scrollHeight"]); }
@computed get sidebarHeight() { return !this.sidebarWidth() ? 0 : NumCast(this.rootDoc[this.SidebarKey + "-height"]); }
@computed get titleHeight() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0; }
- @computed get autoHeightMargins() { return this.titleHeight + (this.layoutDoc._autoHeightMargins && !this.props.dontSelectOnLoad ? NumCast(this.layoutDoc._autoHeightMargins) : 0); }
+ @computed get autoHeightMargins() { return this.titleHeight + NumCast(this.layoutDoc._autoHeightMargins); }
@computed get _recording() { return this.dataDoc?.mediaState === "recording"; }
set _recording(value) {
!this.dataDoc.recordingSource && (this.dataDoc.mediaState = value ? "recording" : undefined);
@@ -1524,10 +1525,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
<div className="formattedTextBox-cont"
onWheel={e => this.isContentActive() && e.stopPropagation()}
style={{
- transform: `scale(${scale})`,
- transformOrigin: "top left",
- width: `${100 / scale}%`,
- height: `${100 / scale}%`,
+ transform: this.props.dontScale ? undefined : `scale(${scale})`,
+ transformOrigin: this.props.dontScale ? undefined : "top left",
+ width: this.props.dontScale ? undefined : `${100 / scale}%`,
+ height: this.props.dontScale ? undefined : `${100 / scale}%`,
// overflowY: this.layoutDoc._autoHeight ? "hidden" : undefined,
...this.styleFromLayoutString(scale) // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' >
}}>
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.scss b/src/client/views/nodes/formattedText/RichTextMenu.scss
index 1d24d6833..c94e93541 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.scss
+++ b/src/client/views/nodes/formattedText/RichTextMenu.scss
@@ -1,4 +1,4 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables";
.button-dropdown-wrapper {
position: relative;
@@ -24,7 +24,7 @@
top: 35px;
left: 0;
background-color: #323232;
- color: $light-color-secondary;
+ color: $light-gray;
border: 1px solid #4d4d4d;
border-radius: 0 6px 6px 6px;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
diff --git a/src/client/views/nodes/formattedText/TooltipTextMenu.scss b/src/client/views/nodes/formattedText/TooltipTextMenu.scss
index 0e4b752ac..8c4d77da9 100644
--- a/src/client/views/nodes/formattedText/TooltipTextMenu.scss
+++ b/src/client/views/nodes/formattedText/TooltipTextMenu.scss
@@ -1,4 +1,4 @@
-@import "../views/globalCssVariables";
+@import "../views/global/globalCssVariables";
.ProseMirror-menu-dropdown-wrap {
display: inline-block;
position: relative;
@@ -50,7 +50,7 @@
padding: 3px;
&:hover {
- background-color: $light-color-secondary;
+ background-color: $light-gray;
}
}
}
@@ -294,9 +294,9 @@
top: 31px;
background-color: #323232;
border: 1px solid #4d4d4d;
- color: $light-color-secondary;
+ color: $light-gray;
// border: none;
- // border: 1px solid $light-color-secondary;
+ // border: 1px solid $light-gray;
border-radius: 0 6px 6px 6px;
padding: 3px;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
@@ -323,7 +323,7 @@
}
.separated-button {
- border-top: 1px solid $light-color-secondary;
+ border-top: 1px solid $light-gray;
padding-top: 6px;
}
diff --git a/src/client/views/search/CheckBox.scss b/src/client/views/search/CheckBox.scss
index cc858bec6..2a0085ade 100644
--- a/src/client/views/search/CheckBox.scss
+++ b/src/client/views/search/CheckBox.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.checkboxfilter {
display: flex;
@@ -13,7 +13,7 @@
margin-top: 0px;
.check-container:hover~.check-box {
- background-color: $darker-alt-accent;
+ background-color: $medium-blue;
}
.check-container {
@@ -40,7 +40,7 @@
overflow: visible;
background-color: transparent;
border-style: solid;
- border-color: $alt-accent;
+ border-color: $medium-gray;
border-width: 2px;
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
diff --git a/src/client/views/search/CollectionFilters.scss b/src/client/views/search/CollectionFilters.scss
index b54cdcbd1..845b16f67 100644
--- a/src/client/views/search/CollectionFilters.scss
+++ b/src/client/views/search/CollectionFilters.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.collection-filters {
display: flex;
diff --git a/src/client/views/search/IconBar.scss b/src/client/views/search/IconBar.scss
index 013dcd57e..6aaf7918d 100644
--- a/src/client/views/search/IconBar.scss
+++ b/src/client/views/search/IconBar.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.icon-bar {
display: flex;
diff --git a/src/client/views/search/IconButton.scss b/src/client/views/search/IconButton.scss
index 4ec03c7c9..3cb08d756 100644
--- a/src/client/views/search/IconButton.scss
+++ b/src/client/views/search/IconButton.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.type-outer {
display: flex;
@@ -9,7 +9,7 @@
.type-icon {
height: 30px;
width: 30px;
- color: $light-color;
+ color: $white;
// background-color: rgb(194, 194, 197);
background-color: gray;
border-radius: 50%;
@@ -43,7 +43,7 @@
.type-icon:hover {
transform: scale(1.1);
- background-color: $darker-alt-accent;
+ background-color: $medium-blue;
opacity: 1;
+.filter-description {
diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx
index 349690b20..2dd6b1b79 100644
--- a/src/client/views/search/IconButton.tsx
+++ b/src/client/views/search/IconButton.tsx
@@ -4,7 +4,7 @@ import { action, IReactionDisposer, observable, reaction, runInAction } from 'mo
import { observer } from 'mobx-react';
import * as React from 'react';
import { DocumentType } from "../../documents/DocumentTypes";
-import '../globalCssVariables.scss';
+import '../global/globalCssVariables.scss';
import { IconBar } from './IconBar';
import "./IconButton.scss";
import "./SearchBox.scss";
@@ -104,7 +104,7 @@ export class IconButton extends React.Component<IconButtonProps>{
hoverStyle = {
opacity: 1,
backgroundColor: "rgb(128, 128, 128)"
- //backgroundColor: "rgb(178, 206, 248)" //$darker-alt-accent
+ //backgroundColor: "rgb(178, 206, 248)" //$medium-blue
};
render() {
diff --git a/src/client/views/search/NaviconButton.scss b/src/client/views/search/NaviconButton.scss
index c23bab461..8a70b29de 100644
--- a/src/client/views/search/NaviconButton.scss
+++ b/src/client/views/search/NaviconButton.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
$height-icon: 15px;
$width-line: 30px;
@@ -20,7 +20,7 @@ $translateX: 0;
.line {
display: block;
- background: $alt-accent;
+ background: $medium-gray;
width: $width-line;
height: $height-line;
position: absolute;
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 4f5b7e41a..6a2fe6f19 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
@import "./NaviconButton.scss";
.searchBox-container {
@@ -20,7 +20,7 @@
display: flex;
justify-content: center;
align-items: center;
- background-color: black;
+ background-color: $dark-gray;
.searchBox-lozenges {
position: absolute;
@@ -86,7 +86,7 @@
&.searchBox-input {
margin:5px;
border-radius:20px;
- border:black;
+ border:$dark-gray;
display: block;
width: 130px;
-webkit-transition: width 0.4s;
@@ -114,7 +114,7 @@
}
&.searchBox-close {
- color: $light-color;
+ color: $white;
max-height: $searchpanel-height;
}
}
@@ -132,7 +132,7 @@
.no-result {
width: 500px;
- background: $light-color-secondary;
+ background: $light-gray;
padding: 10px;
height: 50px;
text-transform: uppercase;
diff --git a/src/client/views/search/SelectorContextMenu.scss b/src/client/views/search/SelectorContextMenu.scss
index 48cacc608..a114f679c 100644
--- a/src/client/views/search/SelectorContextMenu.scss
+++ b/src/client/views/search/SelectorContextMenu.scss
@@ -1,7 +1,7 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.parents {
- background: $lighter-alt-accent;
+ background: $light-blue;
padding: 10px;
// width: 300px;
@@ -10,7 +10,7 @@
}
.collection {
- border-color: $darker-alt-accent;
+ border-color: $medium-blue;
border-bottom-style: solid;
}
} \ No newline at end of file
diff --git a/src/client/views/search/ToggleBar.scss b/src/client/views/search/ToggleBar.scss
index 79f866acb..3a164f133 100644
--- a/src/client/views/search/ToggleBar.scss
+++ b/src/client/views/search/ToggleBar.scss
@@ -1,9 +1,9 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.toggle-title {
display: flex;
align-items: center;
- color: $light-color;
+ color: $white;
text-transform: uppercase;
flex-direction: row;
justify-content: space-around;
@@ -25,7 +25,7 @@
// height: 50px;
height: 30px;
width: 100px;
- background-color: $alt-accent;
+ background-color: $medium-gray;
border-radius: 10px;
padding: 5px;
display: flex;
@@ -36,6 +36,6 @@
width: 40px;
height: 100%;
border-radius: 10px;
- background-color: $light-color;
+ background-color: $white;
}
} \ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index 41307a808..249aee9d6 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
.webcam-cont {
background: whitesmoke;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index bd0ba3ad7..464a8ad05 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -803,6 +803,27 @@ export namespace Doc {
return undefined;
}
+ // Makes a delegate of a document by first creating a delegate where data should be stored
+ // (ie, the 'data' doc), and then creates another delegate of that (ie, the 'layout' doc).
+ // This is appropriate if you're trying to create a document that behaves like all
+ // regularly created documents (e.g, text docs, pdfs, etc which all have data/layout docs)
+ export function MakeDelegateWithProto(doc: Doc, id?: string, title?: string): Doc {
+ const delegateProto = new Doc();
+ delegateProto[Initializing] = true;
+ delegateProto.proto = doc;
+ delegateProto.author = Doc.CurrentUserEmail;
+ delegateProto.isPrototype = true;
+ title && (delegateProto.title = title);
+ const delegate = new Doc(id, true);
+ delegate[Initializing] = true;
+ delegate.proto = delegateProto;
+ delegate.author = Doc.CurrentUserEmail;
+ Doc.AddDocToList(delegateProto[DataSym], "aliases", delegate);
+ delegate[Initializing] = false;
+ delegateProto[Initializing] = false;
+ return delegate;
+ }
+
let _applyCount: number = 0;
export function ApplyTemplate(templateDoc: Doc) {
if (templateDoc) {
@@ -1150,8 +1171,7 @@ export namespace Doc {
return ndoc;
}
export function delegateDragFactory(dragFactory: Doc) {
- const ndoc = Doc.MakeDelegate(dragFactory);
- ndoc.isPrototype = true;
+ const ndoc = Doc.MakeDelegateWithProto(dragFactory);
if (ndoc && dragFactory["dragFactory-count"] !== undefined) {
dragFactory["dragFactory-count"] = NumCast(dragFactory["dragFactory-count"]) + 1;
Doc.GetProto(ndoc).title = ndoc.title + " " + NumCast(dragFactory["dragFactory-count"]).toString();
diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts
index dbe51b24a..1270a2dab 100644
--- a/src/fields/InkField.ts
+++ b/src/fields/InkField.ts
@@ -4,6 +4,7 @@ import { ObjectField } from "./ObjectField";
import { Copy, ToScriptString, ToString, Update } from "./FieldSymbols";
import { Scripting } from "../client/util/Scripting";
+// Helps keep track of the current ink tool in use.
export enum InkTool {
None = "none",
Pen = "pen",
@@ -12,13 +13,41 @@ export enum InkTool {
Stamp = "stamp"
}
+
+// Defines a point in an ink as a pair of x- and y-coordinates.
export interface PointData {
X: number;
Y: number;
}
+// Defines an ink as an array of points.
export type InkData = Array<PointData>;
+export interface ControlPoint {
+ X: number;
+ Y: number;
+ I: number;
+}
+
+export interface HandlePoint {
+ X: number;
+ Y: number;
+ I: number;
+ dot1: number;
+ dot2: number;
+}
+
+export interface HandleLine {
+ X1: number;
+ Y1: number;
+ X2: number;
+ Y2: number;
+ X3: number;
+ Y3: number;
+ dot1: number;
+ dot2: number;
+}
+
const pointSchema = createSimpleSchema({
X: true, Y: true
});
@@ -32,8 +61,6 @@ const strokeDataSchema = createSimpleSchema({
export class InkField extends ObjectField {
@serializable(list(object(strokeDataSchema)))
readonly inkData: InkData;
- // inkData: InkData;
-
constructor(data: InkData) {
super();
diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss
index 6e64d9e2e..dce0c724f 100644
--- a/src/mobile/AudioUpload.scss
+++ b/src/mobile/AudioUpload.scss
@@ -1,4 +1,4 @@
-@import "../client/views/globalCssVariables.scss";
+@import "../client/views/global/globalCssVariables.scss";
.audioUpload_cont {
display: flex;
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index 890258918..6669a3d21 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -1,4 +1,4 @@
-@import "../client/views/globalCssVariables.scss";
+@import "../client/views/global/globalCssVariables.scss";
.imgupload_cont {
display: flex;
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 2183d2172..98696496f 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -5,7 +5,7 @@ import * as rp from 'request-promise';
import { DocServer } from '../client/DocServer';
import { Docs } from '../client/documents/Documents';
import { Networking } from '../client/Network';
-import { DFLT_IMAGE_NATIVE_DIM } from '../client/views/globalCssVariables.scss';
+import { DFLT_IMAGE_NATIVE_DIM } from '../client/views/global/globalCssVariables.scss';
import { MainViewModal } from '../client/views/MainViewModal';
import { Doc, Opt } from '../fields/Doc';
import { List } from '../fields/List';
diff --git a/src/server/DashSession/Session/agents/server_worker.ts b/src/server/DashSession/Session/agents/server_worker.ts
index 6a19bfa5d..60fc181c7 100644
--- a/src/server/DashSession/Session/agents/server_worker.ts
+++ b/src/server/DashSession/Session/agents/server_worker.ts
@@ -1,10 +1,10 @@
-import { ExitHandler } from "./applied_session_agent";
import { isMaster } from "cluster";
-import { manage, ErrorLike } from "./promisified_ipc_manager";
-import IPCMessageReceiver from "./process_message_router";
-import { red, green, white, yellow } from "colors";
+import { green, red, white, yellow } from "colors";
import { get } from "request-promise";
+import { ExitHandler } from "./applied_session_agent";
import { Monitor } from "./monitor";
+import IPCMessageReceiver from "./process_message_router";
+import { ErrorLike, manage } from "./promisified_ipc_manager";
/**
* Effectively, each worker repairs the connection to the server by reintroducing a consistent state