aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts48
-rw-r--r--src/client/documents/Documents.ts35
-rw-r--r--src/client/util/CurrentUserUtils.ts288
-rw-r--r--src/client/util/LinkManager.ts7
-rw-r--r--src/client/util/Scripting.ts8
-rw-r--r--src/client/util/SettingsManager.scss5
-rw-r--r--src/client/views/ContextMenu.scss10
-rw-r--r--src/client/views/ContextMenuItem.tsx2
-rw-r--r--src/client/views/DocumentButtonBar.tsx5
-rw-r--r--src/client/views/DocumentDecorations.scss6
-rw-r--r--src/client/views/EditableView.tsx3
-rw-r--r--src/client/views/GestureOverlay.tsx5
-rw-r--r--src/client/views/InkingStroke.tsx4
-rw-r--r--src/client/views/MainView.scss5
-rw-r--r--src/client/views/MainView.tsx3
-rw-r--r--src/client/views/MainViewModal.scss4
-rw-r--r--src/client/views/StyleProvider.tsx11
-rw-r--r--src/client/views/collections/CollectionMenu.scss1255
-rw-r--r--src/client/views/collections/CollectionMenu.tsx109
-rw-r--r--src/client/views/collections/TabDocView.scss30
-rw-r--r--src/client/views/collections/TabDocView.tsx14
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/index.ts7
-rw-r--r--src/client/views/collections/collectionGrid/index.ts2
-rw-r--r--src/client/views/collections/collectionLinearView/CollectionLinearView.scss (renamed from src/client/views/collections/CollectionLinearView.scss)63
-rw-r--r--src/client/views/collections/collectionLinearView/CollectionLinearView.tsx (renamed from src/client/views/collections/CollectionLinearView.tsx)84
-rw-r--r--src/client/views/collections/collectionLinearView/index.ts1
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx8
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx6
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.scss120
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTable.tsx4
-rw-r--r--src/client/views/global/globalCssVariables.scss15
-rw-r--r--src/client/views/global/globalEnums.tsx5
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx2
-rw-r--r--src/client/views/nodes/DocumentLinksButton.scss1
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx22
-rw-r--r--src/client/views/nodes/DocumentView.tsx39
-rw-r--r--src/client/views/nodes/FontIconBox.scss103
-rw-r--r--src/client/views/nodes/FontIconBox.tsx96
-rw-r--r--src/client/views/nodes/button/ButtonScripts.ts14
-rw-r--r--src/client/views/nodes/button/FontIconBadge.tsx36
-rw-r--r--src/client/views/nodes/button/FontIconBox.scss383
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx761
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx1
-rw-r--r--src/client/views/topbar/TopBar.scss22
-rw-r--r--src/client/views/topbar/TopBar.tsx2
-rw-r--r--src/fields/InkField.ts6
47 files changed, 2554 insertions, 1108 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 102ac520b..b7e6b83a0 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -3,6 +3,8 @@ import v5 = require("uuid/v5");
import { ColorState } from 'react-color';
import { Socket } from 'socket.io';
import { Message } from './server/Message';
+import { Colors } from './client/views/global/globalEnums';
+import Color = require('color');
export namespace Utils {
export let DRAG_THRESHOLD = 4;
@@ -574,46 +576,12 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe
}
export function lightOrDark(color: any) {
-
- // Variables for red, green, blue values
- var r, g, b, hsp;
-
- // Check the format of the color, HEX or RGB?
- if (color.match(/^rgb/)) {
-
- // If RGB --> store the red, green, blue values in separate variables
- color = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
-
- r = color[1];
- g = color[2];
- b = color[3];
- }
- else {
-
- // If hex --> Convert it to RGB: http://gist.github.com/983661
- color = +("0x" + color.slice(1).replace(
- color.length < 5 && /./g, '$&$&'));
-
- r = color >> 16;
- g = color >> 8 & 255;
- b = color & 255;
- }
-
- // HSP (Highly Sensitive Poo) equation from http://alienryderflex.com/hsp.html
- hsp = Math.sqrt(
- 0.299 * (r * r) +
- 0.587 * (g * g) +
- 0.114 * (b * b)
- );
-
- // Using the HSP value, determine whether the color is light or dark
- if (hsp > 127.5) {
- return 'light';
- }
- else {
-
- return 'dark';
- }
+ const nonAlphaColor = color.startsWith("#") ? (color as string).substring(0, 7) :
+ color.startsWith("rgba") ? color.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : color;
+ const col = Color(nonAlphaColor).rgb();
+ const colsum = (col.red() + col.green() + col.blue());
+ if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return Colors.DARK_GRAY;
+ else return Colors.WHITE;
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index db1e67203..ee3a38a0a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -39,7 +39,7 @@ import { DocFocusOptions } from "../views/nodes/DocumentView";
import { EquationBox } from "../views/nodes/EquationBox";
import { FieldViewProps } from "../views/nodes/FieldView";
import { FilterBox } from "../views/nodes/FilterBox";
-import { FontIconBox } from "../views/nodes/FontIconBox";
+import { FontIconBox } from "../views/nodes/button/FontIconBox";
import { FormattedTextBox } from "../views/nodes/formattedText/FormattedTextBox";
import { FunctionPlotBox } from "../views/nodes/FunctionPlotBox";
import { ImageBox } from "../views/nodes/ImageBox";
@@ -214,7 +214,29 @@ export class DocumentOptions {
annotationOn?: Doc;
isPushpin?: boolean;
_removeDropProperties?: List<string>; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document
+
+ //BUTTONS
iconShape?: string; // shapes of the fonticon border
+ btnType?: string;
+ btnList?: List<string>;
+ docColorBtn?: string;
+ userColorBtn?: string;
+ canClick?: string;
+ script?: string;
+ numBtnType?: string;
+ numBtnMax?: number;
+ numBtnMin?: number;
+ switchToggle?: boolean;
+
+ //LINEAR VIEW
+ linearViewIsExpanded?: boolean; // is linear view expanded
+ linearViewExpandable?: boolean; // can linear view be expanded
+ linearViewToggleButton?: string; // button to open close linear view group
+ linearViewSubMenu?: boolean;
+ linearViewFloating?: boolean;
+ flexGap?: number; // Linear view flex gap
+ flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse";
+
layout_linkView?: Doc; // view template for a link document
layout_keyValue?: string; // view tempalte for key value docs
linkRelationship?: string; // type of relatinoship a link represents
@@ -261,11 +283,9 @@ export class DocumentOptions {
text?: string;
textTransform?: string; // is linear view expanded
letterSpacing?: string; // is linear view expanded
- flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse";
selectedIndex?: number; // which item in a linear view has been selected using the "thumb doc" ui
clipboard?: Doc;
searchQuery?: string; // for quersyBox
- linearViewIsExpanded?: boolean; // is linear view expanded
useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox
border?: string; //for searchbox
hoverBackgroundColor?: string; // background color of a label when hovered
@@ -679,14 +699,14 @@ export namespace Docs {
return linkDoc;
}
- export function InkDocument(color: string, tool: string, strokeWidth: string, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, points: { X: number, Y: number }[], options: DocumentOptions = {}) {
+ export function InkDocument(color: string, tool: string, strokeWidth: number, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, points: { X: number, Y: number }[], options: DocumentOptions = {}) {
const I = new Doc();
I[Initializing] = true;
I.type = DocumentType.INK;
I.layout = InkingStroke.LayoutString("data");
I.color = color;
I.fillColor = fillColor;
- I.strokeWidth = Number(strokeWidth);
+ I.strokeWidth = strokeWidth;
I.strokeBezier = strokeBezier;
I.strokeStartMarker = arrowStart;
I.strokeEndMarker = arrowEnd;
@@ -1136,6 +1156,7 @@ export namespace DocUtils {
description: ":" + StrCast(note.title),
event: undoBatch((args: { x: number, y: number }) => {
const textDoc = Docs.Create.TextDocument("", {
+ _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
_width: 200, x, y, _autoHeight: note._autoHeight !== false,
title: StrCast(note.title) + "#" + (note.aliasCount = NumCast(note.aliasCount) + 1)
});
@@ -1162,7 +1183,7 @@ export namespace DocUtils {
}, icon: "compress-arrows-alt"
});
ContextMenu.Instance.addItem({
- description: "Add Template Doc ...",
+ description: "Create document",
subitems: DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({
description: ":" + StrCast(dragDoc.title),
event: undoBatch((args: { x: number, y: number }) => {
@@ -1175,7 +1196,7 @@ export namespace DocUtils {
docAdder?.(newDoc);
}
}),
- icon: "eye"
+ icon: Doc.toIcon(Cast(dragDoc.type, Doc, null)),
})) as ContextMenuProps[],
icon: "eye"
});
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 1f37163d7..7d1cbebdf 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -37,7 +37,24 @@ import { ColorScheme } from "./SettingsManager";
import { SharingManager } from "./SharingManager";
import { SnappingManager } from "./SnappingManager";
import { UndoManager } from "./UndoManager";
-
+import { ButtonType, NumButtonType } from "../views/nodes/button/FontIconBox";
+import { IconName } from "@fortawesome/fontawesome-svg-core";
+
+interface Button {
+ title?: string;
+ toolTip?: string;
+ icon?: string;
+ btnType?: ButtonType;
+ click?: string;
+ numBtnType?: NumButtonType;
+ numBtnMin?: number;
+ numBtnMax?: number;
+ switchToggle?: boolean;
+ script?: string;
+ width?: number;
+ list?: string[];
+ ignoreClick?: boolean;
+}
export let resolvedPorts: { server: number, socket: number };
const headerViewVersion = "0.1";
@@ -69,13 +86,14 @@ export class CurrentUserUtils {
[this.ficon({
ignoreClick: true,
icon: "mobile",
+ btnType: ButtonType.ToolButton,
backgroundColor: "transparent"
}),
this.mobileTextContainer({},
[this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
doc["template-mobile-button"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile"
+ dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile", btnType: ButtonType.ToolButton,
});
}
@@ -83,14 +101,15 @@ export class CurrentUserUtils {
const slideTemplate = Docs.Create.MultirowDocument(
[
Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }),
- Docs.Create.TextDocument("", { title: "text", _height: 100, system: true })
+ Docs.Create.TextDocument("", { title: "text", _height: 100, system: true, _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize) })
],
{ _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
);
slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
doc["template-button-slides"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card"
+ dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card",
+ btnType: ButtonType.ToolButton
});
}
@@ -136,7 +155,8 @@ export class CurrentUserUtils {
doc["template-button-link"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true
+ dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true,
+ btnType: ButtonType.ToolButton
});
}
@@ -167,7 +187,8 @@ export class CurrentUserUtils {
doc["template-button-switch"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true
+ dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true,
+ btnType: ButtonType.ToolButton
});
}
@@ -216,7 +237,11 @@ export class CurrentUserUtils {
doc["template-button-detail"] = CurrentUserUtils.ficon({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
- dragFactory: new PrefetchProxy(detailView) as any as Doc, title: "detailView", icon: "window-maximize", system: true
+ dragFactory: new PrefetchProxy(detailView) as any as Doc,
+ title: "detailView",
+ icon: "window-maximize",
+ system: true,
+ btnType: ButtonType.ToolButton,
});
}
@@ -248,24 +273,28 @@ export class CurrentUserUtils {
// setup the different note type skins
static setupNoteTemplates(doc: Doc) {
if (doc["template-note-Note"] === undefined) {
- const noteView = Docs.Create.TextDocument("", { title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true });
+ const noteView = Docs.Create.TextDocument("", { title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true,
+ _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize), });
noteView.isTemplateDoc = makeTemplate(noteView, true, "Note");
doc["template-note-Note"] = new PrefetchProxy(noteView);
}
if (doc["template-note-Idea"] === undefined) {
- const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "pink", system: true });
+ const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "pink", system: true,
+ _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize), });
noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea");
doc["template-note-Idea"] = new PrefetchProxy(noteView);
}
if (doc["template-note-Topic"] === undefined) {
- const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "lightblue", system: true });
+ const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "lightblue", system: true,
+ _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize), });
noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic");
doc["template-note-Topic"] = new PrefetchProxy(noteView);
}
if (doc["template-note-Todo"] === undefined) {
const noteView = Docs.Create.TextDocument("", {
title: "text", backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption",
- layout: FormattedTextBox.LayoutString("Todo"), caption: RichTextField.DashField("taskStatus"), system: true
+ layout: FormattedTextBox.LayoutString("Todo"), caption: RichTextField.DashField("taskStatus"), system: true,
+ _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
});
noteView.isTemplateDoc = makeTemplate(noteView, true, "Todo");
doc["template-note-Todo"] = new PrefetchProxy(noteView);
@@ -449,7 +478,9 @@ export class CurrentUserUtils {
((doc.emptyAudio as Doc).proto as Doc)["dragFactory-count"] = 0;
}
if (doc.emptyNote === undefined) {
- doc.emptyNote = Docs.Create.TextDocument("", { _width: 200, title: "text note", _autoHeight: true, system: true, cloneFieldFilter: new List<string>(["system"]) });
+ doc.emptyNote = Docs.Create.TextDocument("", { _width: 200, title: "text note", _autoHeight: true, system: true,
+ _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
+ cloneFieldFilter: new List<string>(["system"]) });
((doc.emptyNote as Doc).proto as Doc)["dragFactory-count"] = 0;
}
if (doc.emptyImage === undefined) {
@@ -502,11 +533,13 @@ export class CurrentUserUtils {
icon,
title,
toolTip,
+ btnType: ButtonType.ToolButton,
ignoreClick,
_dropAction: "alias",
onDragStart: drag ? ScriptField.MakeFunction(drag) : undefined,
onClick: click ? ScriptField.MakeScript(click) : undefined,
- backgroundColor,
+ backgroundColor: backgroundColor ? backgroundColor : Colors.DARK_GRAY,
+ color: Colors.WHITE,
_hideContextMenu: true,
_removeDropProperties: new List<string>(["_stayInCollection"]),
_stayInCollection: true,
@@ -537,7 +570,7 @@ export class CurrentUserUtils {
{ title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
{ title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' },
{ title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc },
- { title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
+ // { title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
// { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' },
// { title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' },
{ title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' },
@@ -550,7 +583,7 @@ export class CurrentUserUtils {
const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments }) =>
Docs.Create.FontIconDocument({
icon,
- iconShape: "square",
+ btnType: ButtonType.MenuButton,
_stayInCollection: true,
_hideContextMenu: true,
system: true,
@@ -644,7 +677,7 @@ export class CurrentUserUtils {
onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
backgroundColor: data.backgroundColor, system: true
},
- [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
+ [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
);
}
@@ -754,7 +787,7 @@ export class CurrentUserUtils {
if (doc.myTools === undefined) {
const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], {
- title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _forceActive: true,
+ title: "My Tools", _showTitle: "title", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _forceActive: true,
system: true, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, boxShadow: "0 0",
})) as any as Doc;
@@ -881,10 +914,10 @@ export class CurrentUserUtils {
CurrentUserUtils.setupUserDoc(doc);
}
- static blist = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, {
- ...opts, _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", _forceActive: true,
+ static linearButtonList = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, {
+ ...opts, _gridGap: 5, _xMargin: 5, _yMargin: 5, boxShadow: "0 0", _forceActive: true,
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
- backgroundColor: "black", _lockedPosition: true, linearViewIsExpanded: true, system: true
+ _lockedPosition: true, linearViewIsExpanded: true, system: true, flexDirection: "row"
})) as any as Doc
static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
@@ -894,18 +927,206 @@ export class CurrentUserUtils {
/// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
static setupDockedButtons(doc: Doc) {
if (doc["dockedBtn-undo"] === undefined) {
- doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), dontUndo: true, _stayInCollection: true, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "click to undo", title: "undo", icon: "undo-alt", system: true });
+ doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true });
}
if (doc["dockedBtn-redo"] === undefined) {
- doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), dontUndo: true, _stayInCollection: true, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "click to redo", title: "redo", icon: "redo-alt", system: true });
+ doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true });
}
if (doc.dockedBtns === undefined) {
- doc.dockedBtns = CurrentUserUtils.blist({ title: "docked buttons", ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]);
+ doc.dockedBtns = CurrentUserUtils.linearButtonList({ title: "docked buttons", _height: 40, flexGap: 5, linearViewExpandable: true, ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]);
}
(doc["dockedBtn-undo"] as Doc).dontUndo = true;
(doc["dockedBtn-redo"] as Doc).dontUndo = true;
}
+ static textTools(doc: Doc) {
+ const tools:Button[] =
+ [
+ {
+ title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true,
+ list: ["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia",
+ "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"],
+ script: 'setFont'
+ },
+ { title: "Font size", toolTip: "Font size", width: 75, btnType: ButtonType.NumberButton, numBtnMax: 200, numBtnMin: 0, numBtnType: NumButtonType.DropdownOptions, ignoreClick: true, script: 'setFontSize'},
+ { title: "Font color", toolTip: "Font color", btnType: ButtonType.ColorButton, icon: "font", ignoreClick: true, script:'setFontColor' },
+ { title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", click: 'toggleBold()', script: 'toggleBold' },
+ { title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", click: 'toggleItalic()', script: 'toggleItalic' },
+ { title: "Underline", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", click: 'toggleUnderline()', script: 'toggleUnderline' },
+ // { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", click: 'toggleStrikethrough()'},
+ // { title: "Superscript", tooltip: "Superscript", btnType: ButtonType.ToggleButton, icon: "superscript", click: 'toggleSuperscript()'},
+ // { title: "Subscript", tooltip: "Subscript", btnType: ButtonType.ToggleButton, icon: "subscript", click: 'toggleSubscript()'},
+ { title: "Left align", toolTip: "Left align", btnType: ButtonType.ToggleButton, icon: "align-left", ignoreClick: true, script:'setAlignment("left")' },
+ { title: "Center align", toolTip: "Center align", btnType: ButtonType.ToggleButton, icon: "align-center", ignoreClick: true, script:'setAlignment("center")' },
+ { title: "Right align", toolTip: "Right align", btnType: ButtonType.ToggleButton, icon: "align-right", ignoreClick: true, script:'setAlignment("right")' },
+ ];
+ return tools;
+ }
+
+ static inkTools(doc: Doc) {
+ const tools:Button[] = [
+ { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("pen")', script: 'setActiveInkTool("pen" , true)'},
+ { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", click: 'setActiveInkTool("highlighter")', script:'setActiveInkTool("highlighter", true)' },
+ { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", click: 'setActiveInkTool("circle")', script: 'setActiveInkTool("circle" , true)' },
+ { title: "Square", toolTip: "Square (Ctrl+Shift+S)", btnType: ButtonType.ToggleButton, icon: "square", click: 'setActiveInkTool("square")', script: 'setActiveInkTool("square" , true)' },
+ { title: "Line", toolTip: "Line (Ctrl+Shift+L)", btnType: ButtonType.ToggleButton, icon: "minus", click: 'setActiveInkTool("line")', script: 'setActiveInkTool("line" , true)' },
+ { title: "Stroke width", toolTip: "Stroke width", btnType: ButtonType.NumberButton, numBtnType: NumButtonType.Slider, ignoreClick: true, script: 'setStrokeWidth'},
+ { title: "Stroke color", toolTip: "Stroke color", btnType: ButtonType.ColorButton, icon: "minus", ignoreClick: true, script:'setStrokeColor' },
+
+ ];
+ return tools;
+ }
+
+ static schemaTools(doc: Doc) {
+ const tools:Button[] =
+ [
+ {
+ title: "Show preview",
+ toolTip: "Show preview of selected document",
+ btnType: ButtonType.ToggleButton,
+ width: 50,
+ switchToggle: true,
+ icon: "eye",
+ ignoreClick: true,
+ script: 'toggleSchemaShow'
+ },
+ ];
+ return tools;
+ }
+
+ static webTools(doc: Doc) {
+ const tools:Button[] =
+ [
+ { title: "Back", toolTip: "Go back", btnType: ButtonType.ClickButton, icon: "arrow-left", click: 'webBack()' },
+ { title: "Forward", toolTip: "Go forward", btnType: ButtonType.ClickButton, icon: "arrow-right", click: 'webForward()' },
+ { title: "Reload", toolTip: "Reload webpage", btnType: ButtonType.ClickButton, icon: "redo-alt", click: 'webReload()' },
+ { title: "URL", toolTip: "URL", width: 150, btnType: ButtonType.EditableText, icon: "lock", ignoreClick: true, script: 'webSetURL' },
+ ];
+
+ return tools;
+ }
+
+ static async contextMenuTools(doc: Doc) {
+ return [
+ {
+ title: "Perspective", toolTip: "View", width: 100, btnType: ButtonType.DropdownList, ignoreClick: true,
+ list: [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Tree,
+ CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn,
+ CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel,
+ CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map,
+ CollectionViewType.Grid],
+ script: 'setView',
+ }, // Always show
+ {
+ title: "Background", toolTip: "Background", btnType: ButtonType.ColorButton, ignoreClick: true, icon: "fill-drip",
+ script: "setBackgroundColor", hidden:'selectedDocumentType()'
+ }, // Only when a document is selected
+ { title: "Overlay", toolTip: "Overlay", btnType: ButtonType.ToggleButton, icon: "layer-group", click: 'toggleOverlay()', script:'toggleOverlay', hidden:'selectedDocumentType(undefined, "freeform", true)'}, // Only when floating document is selected in freeform
+ { title: "Alias", btnType: ButtonType.ClickButton, icon: "copy", hidden:'selectedDocumentType()' }, // Only when a document is selected
+ { title: "Text", type: "textTools", subMenu: true, expanded:'selectedDocumentType("rtf")' }, // Always available
+ { title: "Ink & GFX", type: "inkTools", subMenu: true, expanded:'selectedDocumentType("ink")' }, // Always available
+ { title: "Web", type: "webTools", subMenu: true, hidden:'selectedDocumentType("web")' }, // Only when Web is selected
+ { title: "Schema", type: "schemaTools", subMenu: true, hidden:'selectedDocumentType(undefined, "schema")' } // Only when Schema is selected
+ ];
+ }
+
+ // Sets up the default context menu buttons
+ static async setupContextMenuButtons(doc: Doc) {
+ const docList: Doc[] = [];
+
+ (await CurrentUserUtils.contextMenuTools(doc)).map(({ title, width, list, toolTip, ignoreClick, icon, type, btnType, click, script, subMenu, hidden, expanded }) => {
+ const menuDocList: Doc[] = [];
+ if (subMenu) {
+ // default is textTools
+ let tools: Button[];
+ switch(type){
+ case "inkTools":
+ tools = CurrentUserUtils.inkTools(doc);
+ break;
+ case "schemaTools":
+ tools = CurrentUserUtils.schemaTools(doc);
+ break;
+ case "webTools":
+ tools = CurrentUserUtils.webTools(doc);
+ break;
+ case "textTools":
+ tools = CurrentUserUtils.textTools(doc);
+ break;
+ default:
+ tools = CurrentUserUtils.textTools(doc);
+ break;
+ }
+ tools.map(({ title, toolTip, icon, btnType, numBtnType, click, script, width, list, ignoreClick, switchToggle }) => {
+ menuDocList.push(Docs.Create.FontIconDocument({
+ _nativeWidth: width ? width : 25,
+ _nativeHeight: 25,
+ _width: width ? width : 25,
+ _height: 25,
+ icon,
+ toolTip,
+ numBtnType,
+ script,
+ btnType: btnType,
+ btnList: new List<string>(list),
+ ignoreClick: ignoreClick,
+ _stayInCollection: true,
+ _hideContextMenu: true,
+ _lockedPosition: true,
+ system: true,
+ dontUndo: true,
+ title,
+ switchToggle,
+ color: Colors.WHITE,
+ backgroundColor: "transparent",
+ _dropAction: "alias",
+ _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
+ onClick: click ? ScriptField.MakeScript(click, { doc: Doc.name }) : undefined
+ }));
+ });
+ docList.push(CurrentUserUtils.linearButtonList({
+ linearViewSubMenu: true,
+ flexGap: 5,
+ ignoreClick: true,
+ linearViewExpandable: true,
+ icon:title,
+ _height: 30,
+ backgroundColor: "transparent",
+ linearViewIsExpanded: expanded ? ComputedField.MakeFunction(expanded) as any : undefined,
+ hidden: hidden ? ComputedField.MakeFunction(hidden) as any : undefined,
+ }, menuDocList));
+ } else {
+ docList.push(Docs.Create.FontIconDocument({
+ _nativeWidth: width ? width : 25,
+ _nativeHeight: 25,
+ _width: width ? width : 25,
+ _height: 25,
+ icon,
+ toolTip,
+ script,
+ btnType: btnType,
+ btnList: new List<string>(list),
+ ignoreClick: ignoreClick,
+ _stayInCollection: true,
+ _hideContextMenu: true,
+ _lockedPosition: true,
+ system: true,
+ dontUndo: true,
+ title,
+ color: Colors.WHITE,
+ backgroundColor: "transparent",
+ _dropAction: "alias",
+ hidden: hidden ? ComputedField.MakeFunction(hidden) as any : undefined,
+ _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
+ onClick: click ? ScriptField.MakeScript(click, { scriptContext: "any" }) : undefined
+ }));
+ }
+ });
+
+ if (doc.contextMenuBtns === undefined) {
+ doc.contextMenuBtns = CurrentUserUtils.linearButtonList({ title: "menu buttons", flexGap: 0, ignoreClick: true, linearViewExpandable: false, _height: 35 }, docList);
+ }
+ }
+
// sets up the default set of documents to be shown in the Overlay layer
static setupOverlays(doc: Doc) {
if (doc.myOverlayDocs === undefined) {
@@ -967,7 +1188,7 @@ export class CurrentUserUtils {
}
if (doc.myImportPanel === undefined) {
const uploads = Cast(doc.myImportDocs, Doc, null);
- const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true });
+ const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", btnType: ButtonType.ToolButton, icon: "upload", system: true });
doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, _showTitle: "title", ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true, boxShadow: "0 0" }));
}
}
@@ -1047,8 +1268,8 @@ export class CurrentUserUtils {
doc._raiseWhenDragged = true;
doc._showLabel = false;
doc._showMenuLabel = true;
- doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)");
- doc.activeInkWidth = StrCast(doc.activeInkWidth, "1");
+ doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0, 0)");
+ doc.activeInkWidth = NumCast(doc.activeInkWidth, 1);
doc.activeInkBezier = StrCast(doc.activeInkBezier, "0");
doc.activeFillColor = StrCast(doc.activeFillColor, "");
doc.activeArrowStart = StrCast(doc.activeArrowStart, "");
@@ -1069,10 +1290,11 @@ export class CurrentUserUtils {
doc.filterDocCount = 0;
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupDocTemplates(doc); // sets up the template menu of templates
- this.setupImportSidebar(doc);
+ this.setupImportSidebar(doc); // sets up the import sidebar
this.setupSearchSidebar(doc); // sets up the search sidebar
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
this.setupOverlays(doc); // documents in overlay layer
+ this.setupContextMenuButtons(doc); // set up context menu buttons
this.setupDockedButtons(doc); // the bottom bar of font icons
await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels
await this.setupMenuPanel(doc, sharingDocumentId, linkDatabaseId);
@@ -1356,3 +1578,15 @@ Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) {
}
return [];
});
+Scripting.addGlobal(function selectedDocumentType(docType?:DocumentType, colType?:CollectionViewType, checkParent?:boolean) {
+ let selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+ if (selected && checkParent){
+ const parentDoc: Doc = Cast(selected.context, Doc, null);
+ selected = parentDoc;
+ }
+ console.log(selected, docType, colType);
+ if (selected && docType && selected.type === docType) return false;
+ else if (selected && colType && selected.viewType === colType) return false;
+ else if (selected && !colType && !docType) return false;
+ else return true;
+});
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 84ff3a3ff..f0c055049 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -120,7 +120,12 @@ export class LinkManager {
public getAllRelatedLinks(anchor: Doc) { return this.relatedLinker(anchor); } // finds all links that contain the given anchor
public getAllDirectLinks(anchor: Doc): Doc[] {
- return Array.from(Doc.GetProto(anchor)[DirectLinksSym]);
+ // FIXME:glr Why is Doc undefined?
+ if (Doc.GetProto(anchor)[DirectLinksSym]){
+ return Array.from(Doc.GetProto(anchor)[DirectLinksSym]);
+ } else {
+ return [];
+ }
} // finds all links that contain the given anchor
relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] {
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index f981f84cd..efee37419 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -12,7 +12,7 @@ export { ts };
import * as typescriptlib from '!!raw-loader!./type_decls.d';
import { Doc, Field } from '../../fields/Doc';
-export interface ScriptSucccess {
+export interface ScriptSuccess {
success: true;
result: any;
}
@@ -23,7 +23,7 @@ export interface ScriptError {
result: any;
}
-export type ScriptResult = ScriptSucccess | ScriptError;
+export type ScriptResult = ScriptSuccess | ScriptError;
export type ScriptParam = { [name: string]: string };
@@ -171,10 +171,12 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
if (!options.editable) {
batch = Doc.MakeReadOnly();
}
+
const result = compiledFunction.apply(thisParam, params).apply(thisParam, argsArray);
if (batch) {
batch.end();
}
+
return { success: true, result };
} catch (error) {
@@ -315,7 +317,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
}
const paramString = paramList.join(", ");
const funcScript = `(function(${paramString})${requiredType ? `: ${requiredType}` : ''} {
- ${addReturn ? `return ${script};` : script}
+ ${addReturn ? `return ${script};` : `return ${script};`}
})`;
host.writeFile("file.ts", funcScript);
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index c9db94419..b7199f433 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -360,17 +360,18 @@
flex-direction: row;
position: relative;
min-height: 250px;
+ height: 100%;
width: 100%;
.settings-content {
- background-color: #fdfdfd;
+ background-color: $off-white;
}
}
.settings-panel {
position: relative;
min-width: 150px;
- background-color: #e4e4e4;
+ background-color: $light-blue;
.settings-user {
position: absolute;
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 795529780..41a6dc569 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -3,14 +3,12 @@
.contextMenu-cont {
position: absolute;
display: flex;
- z-index: $contextMenu-zindex;
- box-shadow: $medium-gray 0.2vw 0.2vw 0.4vw;
+ z-index: 100000;
+ box-shadow: 0px 3px 4px rgba(0,0,0,30%);
flex-direction: column;
background: whitesmoke;
- padding-top: 10px;
- padding-bottom: 10px;
- border-radius: 15px;
- border: solid #BBBBBBBB 1px;
+ border-radius: 3px;
+ border: solid $light-gray 1px;
}
// .contextMenu-item:first-child {
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 6fe2abd21..168fcb888 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -90,7 +90,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
</span>
) : null}
<div className="contextMenu-description">
- {this.props.description}
+ {this.props.description.replace(":","")}
</div>
</div>
);
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 5f09a322c..5640e5132 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -27,6 +27,7 @@ import React = require("react");
import { PresBox } from './nodes/trails/PresBox';
import { undoBatch } from '../util/UndoManager';
import { CollectionViewType } from './collections/CollectionView';
+import { Colors } from './global/globalEnums';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -187,9 +188,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
get followLinkButton() {
const targetDoc = this.view0?.props.Document;
return !targetDoc ? (null) : <Tooltip title={
- <div className="dash-tooltip">{"follow primary link on click"}</div>}>
+ <div className="dash-tooltip">{"Set onClick to follow primary link"}</div>}>
<div className="documentButtonBar-icon"
- style={{ color: targetDoc.isLinkButton ? "black" : "white" }}
+ style={{ backgroundColor: targetDoc.isLinkButton ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: targetDoc.isLinkButton ? Colors.BLACK : Colors.WHITE }}
onClick={undoBatch(e => this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, false, false)))}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="hand-point-right" />
</div>
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index 316f63240..d34efd01a 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -51,6 +51,7 @@ $linkGap : 3px;
pointer-events: auto;
background: $medium-gray;
opacity: 0.1;
+
&:hover {
opacity: 1;
}
@@ -94,6 +95,7 @@ $linkGap : 3px;
position: absolute;
}
}
+
.documentDecorations-rotation {
background: transparent;
right: -15;
@@ -189,6 +191,7 @@ $linkGap : 3px;
margin-left: 5px;
height: 22px;
position: absolute;
+
.documentDecorations-titleSpan {
width: 100%;
border-radius: 8px;
@@ -263,7 +266,7 @@ $linkGap : 3px;
}
.link-button-container {
- border-radius: 10px;
+ border-radius: 13px;
width: max-content;
height: auto;
display: flex;
@@ -338,6 +341,7 @@ $linkGap : 3px;
.documentdecorations-icon {
margin: 0px;
}
+
.templating-button,
.docDecs-tagButton {
width: 20px;
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 03d9efff3..83336c180 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -155,7 +155,10 @@ export class EditableView extends React.Component<EditableProps> {
return wasFocused !== this._editing;
}
+
+
renderEditor() {
+ console.log("render editor", this.props.autosuggestProps);
return this.props.autosuggestProps
? <Autosuggest
{...this.props.autosuggestProps.autosuggestProps}
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index bbf21f22c..24f9501ce 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -14,6 +14,7 @@ import { DocUtils } from "../documents/Documents";
import { CurrentUserUtils } from "../util/CurrentUserUtils";
import { InteractionUtils } from "../util/InteractionUtils";
import { Scripting } from "../util/Scripting";
+import { SelectionManager } from "../util/SelectionManager";
import { Transform } from "../util/Transform";
import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
import "./GestureOverlay.scss";
@@ -23,7 +24,6 @@ import { RadialMenu } from "./nodes/RadialMenu";
import HorizontalPalette from "./Palette";
import { Touchable } from "./Touchable";
import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
-import { SelectionManager } from "../util/SelectionManager";
@observer
export class GestureOverlay extends Touchable {
@@ -588,8 +588,9 @@ export class GestureOverlay extends Touchable {
this.makePolygon(this.InkShape, false);
this.dispatchGesture(GestureUtils.Gestures.Stroke);
this._points = [];
- if (!CollectionFreeFormViewChrome.Instance._keepPrimitiveMode) {
+ if (!CollectionFreeFormViewChrome.Instance?._keepPrimitiveMode) {
this.InkShape = "";
+ Doc.UserDoc().activeInkTool = InkTool.None;
}
}
// if we're not drawing in a toolglass try to recognize as gesture
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 5fc159f14..db09849fd 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -5,7 +5,7 @@ import { Doc } from "../../fields/Doc";
import { documentSchema } from "../../fields/documentSchemas";
import { InkData, InkField, InkTool } from "../../fields/InkField";
import { makeInterface } from "../../fields/Schema";
-import { Cast, StrCast } from "../../fields/Types";
+import { Cast, StrCast, NumCast } from "../../fields/Types";
import { TraceMobx } from "../../fields/util";
import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
@@ -168,7 +168,7 @@ export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activ
export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ""); }
export function ActiveArrowEnd(): string { return StrCast(ActiveInkPen()?.activeArrowEnd, ""); }
export function ActiveDash(): string { return StrCast(ActiveInkPen()?.activeDash, "0"); }
-export function ActiveInkWidth(): string { return StrCast(ActiveInkPen()?.activeInkWidth, "1"); }
+export function ActiveInkWidth(): number { return NumCast(ActiveInkPen()?.activeInkWidth); }
export function ActiveInkBezierApprox(): string { return StrCast(ActiveInkPen()?.activeInkBezier); }
Scripting.addGlobal(function activateBrush(pen: any, width: any, color: any, fill: any, arrowStart: any, arrowEnd: any, dash: any) {
CurrentUserUtils.SelectedTool = pen ? InkTool.Highlighter : InkTool.None;
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index d913f2069..817e45699 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -265,11 +265,6 @@
height: 35px;
padding: 5px;
}
-
- svg {
- width: 95% !important;
- height: 95%;
- }
}
.mainView-searchPanel {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 6a388c5b4..dcdf6b9c3 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -331,7 +331,7 @@ export class MainView extends React.Component {
PanelHeight={this.getContentsHeight}
renderDepth={0}
isContentActive={returnTrue}
- scriptContext={CollectionDockingView.Instance.props.Document}
+ scriptContext={CollectionDockingView.Instance?.props.Document}
focus={DocUtils.DefaultFocus}
whenChildContentsActiveChanged={emptyFunction}
bringToFront={emptyFunction}
@@ -439,6 +439,7 @@ export class MainView extends React.Component {
this._flyoutWidth = (this._flyoutWidth || 250);
this._sidebarContent.proto = button.target as any;
this.LastButton = button;
+ console.log(button.title);
});
closeFlyout = action(() => {
diff --git a/src/client/views/MainViewModal.scss b/src/client/views/MainViewModal.scss
index 5f19590b4..03cb5cc84 100644
--- a/src/client/views/MainViewModal.scss
+++ b/src/client/views/MainViewModal.scss
@@ -4,6 +4,7 @@
z-index: 10000;
width: 100%;
height: 100%;
+
.dialogue-box {
position: absolute;
z-index: 1000;
@@ -11,11 +12,8 @@
justify-content: center;
align-self: center;
align-content: center;
- padding: 20px;
- // background: gainsboro;
background: white;
border-radius: 10px;
- border: 0.5px solid black;
box-shadow: #00000044 5px 5px 10px;
transform: translate(-50%, -50%);
top: 50%;
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index c9e532745..470ae7c77 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -21,6 +21,7 @@ import "./nodes/FilterBox.scss";
import "./StyleProvider.scss";
import React = require("react");
import Color = require('color');
+import { lightOrDark } from '../../Utils';
export enum StyleLayers {
Background = "background"
@@ -96,16 +97,12 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
!Doc.IsSystem(doc) && doc.type === DocumentType.RTF ?
(doc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : "") || "";
case StyleProp.Color:
+ if (MainView.Instance.LastButton === doc) return Colors.DARK_GRAY;
const docColor: Opt<string> = StrCast(doc?.[fieldKey + "color"], StrCast(doc?._color));
if (docColor) return docColor;
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 Colors.DARK_GRAY;
- return Colors.WHITE;
+ return lightOrDark(backColor)
case StyleProp.Hidden: return BoolCast(doc?._hidden);
case StyleProp.BorderRounding: return StrCast(doc?.[fieldKey + "borderRounding"], doc?._viewType === CollectionViewType.Pile ? "50%" : "");
case StyleProp.TitleHeight: return 15;
@@ -114,8 +111,8 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) ||
doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
case StyleProp.BackgroundColor: {
+ if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
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() ? Colors.MEDIUM_GRAY : Colors.LIGHT_GRAY;
switch (doc?.type) {
case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break;
case DocumentType.PRES: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); break;
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index f04b19ef7..c35f088a6 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -1,628 +1,659 @@
@import "../global/globalCssVariables";
-.collectionMenu-cont {
- position: relative;
- display: inline-flex;
- width: 100%;
- opacity: 0.9;
- z-index: 901;
- transition: top .5s;
- background: $dark-gray;
- color: $white;
- transform-origin: top left;
- top: 0;
- width: 100%;
-
- .recordButtonOutline {
- border-radius: 100%;
- width: 18px;
- height: 18px;
- border: solid 1px $white;
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- .recordButtonInner {
- border-radius: 100%;
- width: 70%;
- height: 70%;
- background: $white;
- }
-
- .collectionMenu {
- display: flex;
- height: 100%;
- overflow: visible;
- z-index: 901;
- border: unset;
-
- .collectionMenu-divider {
- height: 100%;
- margin-left: 3px;
- margin-right: 3px;
- width: 2px;
- background-color: $medium-gray;
- }
-
- .collectionViewBaseChrome {
- display: flex;
- align-items: center;
-
- .collectionViewBaseChrome-viewPicker {
- font-size: $small-text;
- outline-color: $black;
- color: $white;
- border: none;
- background: $dark-gray;
- }
-
- .collectionViewBaseChrome-viewPicker:focus {
- outline: none;
- border: none;
- }
-
- .collectionViewBaseChrome-viewPicker:active {
- outline-color: $black;
- }
-
- .collectionViewBaseChrome-button {
- font-size: $small-text;
- text-transform: uppercase;
- letter-spacing: 2px;
- background: $white;
- color: $pink;
- outline-color: $black;
- border: none;
- padding: 12px 10px 11px 10px;
- margin-left: 10px;
- }
-
- .collectionViewBaseChrome-cmdPicker {
- margin-left: 3px;
- margin-right: 0px;
- font-size: $small-text;
- text-transform: capitalize;
- color: $white;
- border: none;
- background: $dark-gray;
- }
-
- .collectionViewBaseChrome-cmdPicker:focus {
- border: none;
- outline: none;
- }
-
- .commandEntry-outerDiv {
- pointer-events: all;
- background-color: transparent;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- height: 100%;
- overflow: hidden;
-
- .commandEntry-drop {
- color: $white;
- width: 30px;
- margin-top: auto;
- margin-bottom: auto;
- }
- }
-
- .commandEntry-outerDiv:hover{
- background-color: $drop-shadow;
-
- .collectionViewBaseChrome-viewPicker,
- .collectionViewBaseChrome-cmdPicker{
- background: $dark-gray;
- }
- }
-
- .collectionViewBaseChrome-collapse {
- transition: all .5s, opacity 0.3s;
- position: absolute;
- width: 30px;
- transform-origin: top left;
- pointer-events: all;
- // margin-top: 10px;
- }
-
- @media only screen and (max-device-width: 480px) {
- .collectionViewBaseChrome-collapse {
- display: none;
- }
- }
-
- .collectionViewBaseChrome-template,
- .collectionViewBaseChrome-viewModes {
- align-items: center;
- height: 100%;
- display: flex;
- background: transparent;
- color: $medium-gray;
- justify-content: center;
- }
-
- .collectionViewBaseChrome-viewSpecs {
- margin-left: 5px;
- display: grid;
- border: none;
- border-right: solid $medium-gray 1px;
-
- .collectionViewBaseChrome-filterIcon {
- position: relative;
- display: flex;
- margin: auto;
- background: $dark-gray;
- color: $white;
- width: 30px;
- height: 30px;
- align-items: center;
- justify-content: center;
- border: none;
- border-right: solid $medium-gray 1px;
- }
-
- .collectionViewBaseChrome-viewSpecsInput {
- padding: 12px 10px 11px 10px;
- border: 0px;
- color: $medium-gray;
- text-align: center;
- letter-spacing: 2px;
- outline-color: $black;
- font-size: $small-text;
- background: $white;
- height: 100%;
- width: 75px;
- }
-
- .collectionViewBaseChrome-viewSpecsMenu {
- overflow: hidden;
- transition: height .5s, display .5s;
- position: absolute;
- top: 60px;
- z-index: 100;
- display: flex;
- flex-direction: column;
- background: $white;
- box-shadow: $medium-gray 2px 2px 4px;
-
- .qs-datepicker {
- left: unset;
- right: 0;
- }
-
- .collectionViewBaseChrome-viewSpecsMenu-row {
- display: grid;
- grid-template-columns: 150px 200px 150px;
- margin-top: 10px;
- margin-right: 10px;
-
- .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
- .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
- .collectionViewBaseChrome-viewSpecsMenu-rowRight {
- font-size: $small-text;
- letter-spacing: 2px;
- color: $medium-gray;
- margin-left: 10px;
- padding: 5px;
- border: none;
- outline-color: $black;
- }
- }
-
- .collectionViewBaseChrome-viewSpecsMenu-lastRow {
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- grid-gap: 10px;
- margin: 10px;
- }
- }
- }
- }
-
- .collectionStackingViewChrome-cont,
- .collectionTreeViewChrome-cont,
- .collection3DCarouselViewChrome-cont {
- display: flex;
- justify-content: space-between;
- }
-
- .collectionGridViewChrome-cont {
- display: flex;
- margin-left: 10;
-
- .collectionGridViewChrome-viewPicker {
- font-size: $small-text;
- //text-transform: uppercase;
- //letter-spacing: 2px;
- background: $dark-gray;
- color: $white;
- outline-color: $black;
- color: $white;
- border: none;
- border-right: solid $medium-gray 1px;
- }
-
- .collectionGridViewChrome-viewPicker:active {
- outline-color: $black;
- }
-
- .grid-control {
- align-self: center;
- display: flex;
- flex-direction: row;
- margin-right: 5px;
-
- .grid-icon {
- margin-right: 5px;
- align-self: center;
- }
-
- .flexLabel {
- margin-bottom: 0;
- }
-
- .collectionGridViewChrome-entryBox {
- width: 50%;
- color: $black;
- }
-
- .collectionGridViewChrome-columnButton {
- color: $black;
- }
- }
- }
-
- .collectionStackingViewChrome-sort,
- .collectionTreeViewChrome-sort {
- display: flex;
- align-items: center;
- justify-content: space-between;
-
- .collectionStackingViewChrome-sortIcon,
- .collectionTreeViewChrome-sortIcon {
- transition: transform .5s;
- margin-left: 10px;
- }
- }
-
- button:hover {
- transform: scale(1);
- }
-
-
- .collectionStackingViewChrome-pivotField-cont,
- .collectionTreeViewChrome-pivotField-cont,
- .collection3DCarouselViewChrome-scrollSpeed-cont {
- justify-self: right;
- align-items: center;
- display: flex;
- grid-auto-columns: auto;
- font-size: $small-text;
- letter-spacing: 2px;
-
- .collectionStackingViewChrome-pivotField-label,
- .collectionTreeViewChrome-pivotField-label,
- .collection3DCarouselViewChrome-scrollSpeed-label {
- grid-column: 1;
- margin-right: 7px;
- user-select: none;
- font-family: $sans-serif;
- letter-spacing: normal;
- }
-
- .collectionStackingViewChrome-sortIcon {
- transition: transform .5s;
- grid-column: 3;
- text-align: center;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- width: 25px;
- height: 25px;
- border-radius: 100%;
- }
-
- .collectionStackingViewChrome-sortIcon:hover {
- background-color: $drop-shadow;
- }
-
- .collectionStackingViewChrome-pivotField,
- .collectionTreeViewChrome-pivotField,
- .collection3DCarouselViewChrome-scrollSpeed {
- color: $white;
- grid-column: 2;
- grid-row: 1;
- width: 90%;
- min-width: 100px;
- display: flex;
- height: 80%;
- border-radius: 7px;
- align-items: center;
- background: $white;
-
- .editable-view-input,
- input,
- .editableView-container-editing-oneLine,
- .editableView-container-editing {
- margin: auto;
- border: 0px;
- color: $light-gray !important;
- text-align: center;
- letter-spacing: 2px;
- outline-color: $black;
- height: 100%;
- }
-
- .react-autosuggest__container {
- margin: 0;
- color: $medium-gray;
- padding: 0px;
- }
- }
- }
-
- .collectionStackingViewChrome-pivotField:hover,
- .collectionTreeViewChrome-pivotField:hover,
- .collection3DCarouselViewChrome-scrollSpeed:hover {
- cursor: text;
- }
-
- }
-}
-
-.collectionMenu-webUrlButtons {
- margin-left: 44;
- background: lightGray;
+.collectionMenu-container {
display: flex;
-}
-
-.webBox-urlEditor {
- position: relative;
- opacity: 0.9;
- z-index: 901;
- transition: top .5s;
-
- .urlEditor {
- display: grid;
- grid-template-columns: 1fr auto;
- padding-bottom: 10px;
- overflow: hidden;
- margin-top: 5px;
- height: 35px;
-
- .editorBase {
- display: flex;
-
- .editor-collapse {
- transition: all .5s, opacity 0.3s;
- position: absolute;
- width: 40px;
- transform-origin: top left;
- }
-
- .switchToText {
- color: $medium-gray;
- }
-
- .switchToText:hover {
- color: $dark-gray;
- }
- }
-
- button:hover {
- transform: scale(1);
- }
- }
-}
-
-.collectionMenu-urlInput {
- padding: 12px 10px 11px 10px;
- border: 0px;
- color: $black;
- font-size: $small-text;
- letter-spacing: 2px;
- outline-color: $black;
- background: $white;
- width: 100%;
- min-width: 350px;
- margin-right: 10px;
- height: 100%;
-}
-
-.collectionFreeFormMenu-cont {
- display: inline-flex;
position: relative;
+ align-content: center;
+ justify-content: space-between;
+ background-color: $dark-gray;
+ height: 35px;
+ border-bottom: $standard-border;
+ padding-right: 5px;
align-items: center;
- height: 100%;
-
- .color-previewI {
- width: 60%;
- top: 80%;
- position: absolute;
- height: 4px;
- }
-
- .color-previewII {
- width: 80%;
- height: 80%;
- margin-left: 10%;
- position: absolute;
- bottom: 5;
- }
-
- .btn-group {
- display: grid;
- grid-template-columns: auto auto auto auto;
- margin: auto;
- /* Make the buttons appear below each other */
- }
- .btn-draw {
- display: inline-flex;
- margin: auto;
- /* Make the buttons appear below each other */
- }
-
- .fwdKeyframe,
- .numKeyframe,
- .backKeyframe {
+ .collectionMenu-hardCodedButton {
cursor: pointer;
- position: relative;
- width: 20;
- height: 30;
- bottom: 0;
- background: $dark-gray;
- display: inline-flex;
- align-items: center;
color: $white;
- }
-
- .backKeyframe {
- svg {
- display: block;
- margin: auto;
- }
- }
-
-
- .numKeyframe {
- flex-direction: column;
- padding-top: 5px;
- }
-
- .fwdKeyframe {
- svg {
- display: block;
- margin: auto;
- }
-
- border-right: solid $medium-gray 1px;
- }
-}
-
-.collectionSchemaViewChrome-cont {
- display: flex;
- font-size: $small-text;
-
- .collectionSchemaViewChrome-toggle {
- display: flex;
- margin-left: 10px;
- }
-
- .collectionSchemaViewChrome-label {
- text-transform: uppercase;
- letter-spacing: 2px;
- margin-right: 5px;
+ width: 25px;
+ height: 25px;
+ padding: 5;
+ text-align: center;
display: flex;
- flex-direction: column;
justify-content: center;
- }
-
- .collectionSchemaViewChrome-toggler {
- width: 100px;
- height: 35px;
- background-color: $black;
+ align-items: center;
position: relative;
- }
-
- .collectionSchemaViewChrome-togglerButton {
- width: 47px;
- height: 30px;
- background-color: $light-gray;
- // position: absolute;
- transition: all 0.5s ease;
- // top: 3px;
- margin-top: 3px;
- color: $medium-gray;
- letter-spacing: 2px;
- text-transform: uppercase;
- display: flex;
- flex-direction: column;
- justify-content: center;
- text-align: center;
+ transition: 0.2s;
+ border-radius: 3px;
- &.on {
- margin-left: 3px;
- }
-
- &.off {
- margin-left: 50px;
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.2);
}
}
}
-
-.commandEntry-outerDiv {
- display: flex;
- flex-direction: column;
- height: 40px;
-}
-
-.commandEntry-inputArea {
- display: flex;
- flex-direction: row;
- width: 150px;
- margin: auto auto auto auto;
-}
-
-.react-autosuggest__container {
- position: relative;
- width: 100%;
- margin-left: 5px;
- margin-right: 5px;
-}
-
-.react-autosuggest__input {
- border: 1px solid $light-gray;
- border-radius: 4px;
- width: 100%;
-}
-
-.react-autosuggest__input--focused {
- outline: none;
-}
-
-.react-autosuggest__input--open {
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-.react-autosuggest__suggestions-container {
- display: none;
-}
-
-.react-autosuggest__suggestions-container--open {
- display: block;
- position: fixed;
- overflow-y: auto;
- max-height: 400px;
- width: 180px;
- border: 1px solid $light-gray;
- background-color: $white;
- font-family: $sans-serif;
- font-weight: 300;
- font-size: $large-header;
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
- z-index: 2;
-}
-
-.react-autosuggest__suggestions-list {
- margin: 0;
- padding: 0;
- list-style-type: none;
-}
-
-.react-autosuggest__suggestion {
- cursor: pointer;
- padding: 10px 20px;
-}
-
-.react-autosuggest__suggestion--highlighted {
- background-color: $light-gray;
-} \ No newline at end of file
+// .collectionMenu-cont {
+// position: relative;
+// display: inline-flex;
+// width: 100%;
+// opacity: 0.9;
+// z-index: 901;
+// transition: top .5s;
+// background: $dark-gray;
+// color: $white;
+// transform-origin: top left;
+// top: 0;
+// width: 100%;
+
+// .recordButtonOutline {
+// border-radius: 100%;
+// width: 18px;
+// height: 18px;
+// border: solid 1px $white;
+// display: flex;
+// align-items: center;
+// justify-content: center;
+// }
+
+// .recordButtonInner {
+// border-radius: 100%;
+// width: 70%;
+// height: 70%;
+// background: $white;
+// }
+
+// .collectionMenu {
+// display: flex;
+// height: 100%;
+// overflow: visible;
+// z-index: 901;
+// border: unset;
+
+// .collectionMenu-divider {
+// height: 100%;
+// margin-left: 3px;
+// margin-right: 3px;
+// width: 2px;
+// background-color: $medium-gray;
+// }
+
+// .collectionViewBaseChrome {
+// display: flex;
+// align-items: center;
+
+// .collectionViewBaseChrome-viewPicker {
+// font-size: $small-text;
+// outline-color: $black;
+// color: $white;
+// border: none;
+// background: $dark-gray;
+// }
+
+// .collectionViewBaseChrome-viewPicker:focus {
+// outline: none;
+// border: none;
+// }
+
+// .collectionViewBaseChrome-viewPicker:active {
+// outline-color: $black;
+// }
+
+// .collectionViewBaseChrome-button {
+// font-size: $small-text;
+// text-transform: uppercase;
+// letter-spacing: 2px;
+// background: $white;
+// color: $pink;
+// outline-color: $black;
+// border: none;
+// padding: 12px 10px 11px 10px;
+// margin-left: 10px;
+// }
+
+// .collectionViewBaseChrome-cmdPicker {
+// margin-left: 3px;
+// margin-right: 0px;
+// font-size: $small-text;
+// text-transform: capitalize;
+// color: $white;
+// border: none;
+// background: $dark-gray;
+// }
+
+// .collectionViewBaseChrome-cmdPicker:focus {
+// border: none;
+// outline: none;
+// }
+
+// .commandEntry-outerDiv {
+// pointer-events: all;
+// background-color: transparent;
+// display: flex;
+// flex-direction: row;
+// align-items: center;
+// justify-content: center;
+// height: 100%;
+// overflow: hidden;
+
+// .commandEntry-drop {
+// color: $white;
+// width: 30px;
+// margin-top: auto;
+// margin-bottom: auto;
+// }
+// }
+
+// .commandEntry-outerDiv:hover{
+// background-color: $drop-shadow;
+
+// .collectionViewBaseChrome-viewPicker,
+// .collectionViewBaseChrome-cmdPicker{
+// background: $dark-gray;
+// }
+// }
+
+// .collectionViewBaseChrome-collapse {
+// transition: all .5s, opacity 0.3s;
+// position: absolute;
+// width: 30px;
+// transform-origin: top left;
+// pointer-events: all;
+// // margin-top: 10px;
+// }
+
+// @media only screen and (max-device-width: 480px) {
+// .collectionViewBaseChrome-collapse {
+// display: none;
+// }
+// }
+
+// .collectionViewBaseChrome-template,
+// .collectionViewBaseChrome-viewModes {
+// align-items: center;
+// height: 100%;
+// display: flex;
+// background: transparent;
+// color: $medium-gray;
+// justify-content: center;
+// }
+
+// .collectionViewBaseChrome-viewSpecs {
+// margin-left: 5px;
+// display: grid;
+// border: none;
+// border-right: solid $medium-gray 1px;
+
+// .collectionViewBaseChrome-filterIcon {
+// position: relative;
+// display: flex;
+// margin: auto;
+// background: $dark-gray;
+// color: $white;
+// width: 30px;
+// height: 30px;
+// align-items: center;
+// justify-content: center;
+// border: none;
+// border-right: solid $medium-gray 1px;
+// }
+
+// .collectionViewBaseChrome-viewSpecsInput {
+// padding: 12px 10px 11px 10px;
+// border: 0px;
+// color: $medium-gray;
+// text-align: center;
+// letter-spacing: 2px;
+// outline-color: $black;
+// font-size: $small-text;
+// background: $white;
+// height: 100%;
+// width: 75px;
+// }
+
+// .collectionViewBaseChrome-viewSpecsMenu {
+// overflow: hidden;
+// transition: height .5s, display .5s;
+// position: absolute;
+// top: 60px;
+// z-index: 100;
+// display: flex;
+// flex-direction: column;
+// background: $white;
+// box-shadow: $medium-gray 2px 2px 4px;
+
+// .qs-datepicker {
+// left: unset;
+// right: 0;
+// }
+
+// .collectionViewBaseChrome-viewSpecsMenu-row {
+// display: grid;
+// grid-template-columns: 150px 200px 150px;
+// margin-top: 10px;
+// margin-right: 10px;
+
+// .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
+// .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
+// .collectionViewBaseChrome-viewSpecsMenu-rowRight {
+// font-size: $small-text;
+// letter-spacing: 2px;
+// color: $medium-gray;
+// margin-left: 10px;
+// padding: 5px;
+// border: none;
+// outline-color: $black;
+// }
+// }
+
+// .collectionViewBaseChrome-viewSpecsMenu-lastRow {
+// display: grid;
+// grid-template-columns: 1fr 1fr 1fr;
+// grid-gap: 10px;
+// margin: 10px;
+// }
+// }
+// }
+// }
+
+// .collectionStackingViewChrome-cont,
+// .collectionTreeViewChrome-cont,
+// .collection3DCarouselViewChrome-cont {
+// display: flex;
+// justify-content: space-between;
+// }
+
+// .collectionGridViewChrome-cont {
+// display: flex;
+// margin-left: 10;
+
+// .collectionGridViewChrome-viewPicker {
+// font-size: $small-text;
+// //text-transform: uppercase;
+// //letter-spacing: 2px;
+// background: $dark-gray;
+// color: $white;
+// outline-color: $black;
+// color: $white;
+// border: none;
+// border-right: solid $medium-gray 1px;
+// }
+
+// .collectionGridViewChrome-viewPicker:active {
+// outline-color: $black;
+// }
+
+// .grid-control {
+// align-self: center;
+// display: flex;
+// flex-direction: row;
+// margin-right: 5px;
+
+// .grid-icon {
+// margin-right: 5px;
+// align-self: center;
+// }
+
+// .flexLabel {
+// margin-bottom: 0;
+// }
+
+// .collectionGridViewChrome-entryBox {
+// width: 50%;
+// color: $black;
+// }
+
+// .collectionGridViewChrome-columnButton {
+// color: $black;
+// }
+// }
+// }
+
+// .collectionStackingViewChrome-sort,
+// .collectionTreeViewChrome-sort {
+// display: flex;
+// align-items: center;
+// justify-content: space-between;
+
+// .collectionStackingViewChrome-sortIcon,
+// .collectionTreeViewChrome-sortIcon {
+// transition: transform .5s;
+// margin-left: 10px;
+// }
+// }
+
+// button:hover {
+// transform: scale(1);
+// }
+
+
+// .collectionStackingViewChrome-pivotField-cont,
+// .collectionTreeViewChrome-pivotField-cont,
+// .collection3DCarouselViewChrome-scrollSpeed-cont {
+// justify-self: right;
+// align-items: center;
+// display: flex;
+// grid-auto-columns: auto;
+// font-size: $small-text;
+// letter-spacing: 2px;
+
+// .collectionStackingViewChrome-pivotField-label,
+// .collectionTreeViewChrome-pivotField-label,
+// .collection3DCarouselViewChrome-scrollSpeed-label {
+// grid-column: 1;
+// margin-right: 7px;
+// user-select: none;
+// font-family: $sans-serif;
+// letter-spacing: normal;
+// }
+
+// .collectionStackingViewChrome-sortIcon {
+// transition: transform .5s;
+// grid-column: 3;
+// text-align: center;
+// display: flex;
+// justify-content: center;
+// align-items: center;
+// cursor: pointer;
+// width: 25px;
+// height: 25px;
+// border-radius: 100%;
+// }
+
+// .collectionStackingViewChrome-sortIcon:hover {
+// background-color: $drop-shadow;
+// }
+
+// .collectionStackingViewChrome-pivotField,
+// .collectionTreeViewChrome-pivotField,
+// .collection3DCarouselViewChrome-scrollSpeed {
+// color: $white;
+// grid-column: 2;
+// grid-row: 1;
+// width: 90%;
+// min-width: 100px;
+// display: flex;
+// height: 80%;
+// border-radius: 7px;
+// align-items: center;
+// background: $white;
+
+// .editable-view-input,
+// input,
+// .editableView-container-editing-oneLine,
+// .editableView-container-editing {
+// margin: auto;
+// border: 0px;
+// color: $light-gray !important;
+// text-align: center;
+// letter-spacing: 2px;
+// outline-color: $black;
+// height: 100%;
+// }
+
+// .react-autosuggest__container {
+// margin: 0;
+// color: $medium-gray;
+// padding: 0px;
+// }
+// }
+// }
+
+// .collectionStackingViewChrome-pivotField:hover,
+// .collectionTreeViewChrome-pivotField:hover,
+// .collection3DCarouselViewChrome-scrollSpeed:hover {
+// cursor: text;
+// }
+
+// }
+// }
+
+// .collectionMenu-webUrlButtons {
+// margin-left: 44;
+// background: lightGray;
+// display: flex;
+// }
+
+// .webBox-urlEditor {
+// position: relative;
+// opacity: 0.9;
+// z-index: 901;
+// transition: top .5s;
+
+// .urlEditor {
+// display: grid;
+// grid-template-columns: 1fr auto;
+// padding-bottom: 10px;
+// overflow: hidden;
+// margin-top: 5px;
+// height: 35px;
+
+// .editorBase {
+// display: flex;
+
+// .editor-collapse {
+// transition: all .5s, opacity 0.3s;
+// position: absolute;
+// width: 40px;
+// transform-origin: top left;
+// }
+
+// .switchToText {
+// color: $medium-gray;
+// }
+
+// .switchToText:hover {
+// color: $dark-gray;
+// }
+// }
+
+// button:hover {
+// transform: scale(1);
+// }
+// }
+// }
+
+// .collectionMenu-urlInput {
+// padding: 12px 10px 11px 10px;
+// border: 0px;
+// color: $black;
+// font-size: $small-text;
+// letter-spacing: 2px;
+// outline-color: $black;
+// background: $white;
+// width: 100%;
+// min-width: 350px;
+// margin-right: 10px;
+// height: 100%;
+// }
+
+// .collectionFreeFormMenu-cont {
+// display: inline-flex;
+// position: relative;
+// align-items: center;
+// height: 100%;
+
+// .color-previewI {
+// width: 60%;
+// top: 80%;
+// position: absolute;
+// height: 4px;
+// }
+
+// .color-previewII {
+// width: 80%;
+// height: 80%;
+// margin-left: 10%;
+// position: absolute;
+// bottom: 5;
+// }
+
+// .btn-group {
+// display: grid;
+// grid-template-columns: auto auto auto auto;
+// margin: auto;
+// /* Make the buttons appear below each other */
+// }
+
+// .btn-draw {
+// display: inline-flex;
+// margin: auto;
+// /* Make the buttons appear below each other */
+// }
+
+// .fwdKeyframe,
+// .numKeyframe,
+// .backKeyframe {
+// cursor: pointer;
+// position: relative;
+// width: 20;
+// height: 30;
+// bottom: 0;
+// background: $dark-gray;
+// display: inline-flex;
+// align-items: center;
+// color: $white;
+// }
+
+// .backKeyframe {
+// svg {
+// display: block;
+// margin: auto;
+// }
+// }
+
+
+// .numKeyframe {
+// flex-direction: column;
+// padding-top: 5px;
+// }
+
+// .fwdKeyframe {
+// svg {
+// display: block;
+// margin: auto;
+// }
+
+// border-right: solid $medium-gray 1px;
+// }
+// }
+
+// .collectionSchemaViewChrome-cont {
+// display: flex;
+// font-size: $small-text;
+
+// .collectionSchemaViewChrome-toggle {
+// display: flex;
+// margin-left: 10px;
+// }
+
+// .collectionSchemaViewChrome-label {
+// text-transform: uppercase;
+// letter-spacing: 2px;
+// margin-right: 5px;
+// display: flex;
+// flex-direction: column;
+// justify-content: center;
+// }
+
+// .collectionSchemaViewChrome-toggler {
+// width: 100px;
+// height: 35px;
+// background-color: $black;
+// position: relative;
+// }
+
+// .collectionSchemaViewChrome-togglerButton {
+// width: 47px;
+// height: 30px;
+// background-color: $light-gray;
+// // position: absolute;
+// transition: all 0.5s ease;
+// // top: 3px;
+// margin-top: 3px;
+// color: $medium-gray;
+// letter-spacing: 2px;
+// text-transform: uppercase;
+// display: flex;
+// flex-direction: column;
+// justify-content: center;
+// text-align: center;
+
+// &.on {
+// margin-left: 3px;
+// }
+
+// &.off {
+// margin-left: 50px;
+// }
+// }
+// }
+
+
+// .commandEntry-outerDiv {
+// display: flex;
+// flex-direction: column;
+// height: 40px;
+// }
+
+// .commandEntry-inputArea {
+// display: flex;
+// flex-direction: row;
+// width: 150px;
+// margin: auto auto auto auto;
+// }
+
+// .react-autosuggest__container {
+// position: relative;
+// width: 100%;
+// margin-left: 5px;
+// margin-right: 5px;
+// }
+
+// .react-autosuggest__input {
+// border: 1px solid $light-gray;
+// border-radius: 4px;
+// width: 100%;
+// }
+
+// .react-autosuggest__input--focused {
+// outline: none;
+// }
+
+// .react-autosuggest__input--open {
+// border-bottom-left-radius: 0;
+// border-bottom-right-radius: 0;
+// }
+
+// .react-autosuggest__suggestions-container {
+// display: none;
+// }
+
+// .react-autosuggest__suggestions-container--open {
+// display: block;
+// position: fixed;
+// overflow-y: auto;
+// max-height: 400px;
+// width: 180px;
+// border: 1px solid $light-gray;
+// background-color: $white;
+// font-family: $sans-serif;
+// font-weight: 300;
+// font-size: $large-header;
+// border-bottom-left-radius: 4px;
+// border-bottom-right-radius: 4px;
+// z-index: 2;
+// }
+
+// .react-autosuggest__suggestions-list {
+// margin: 0;
+// padding: 0;
+// list-style-type: none;
+// }
+
+// .react-autosuggest__suggestion {
+// cursor: pointer;
+// padding: 10px 20px;
+// }
+
+// .react-autosuggest__suggestion--highlighted {
+// background-color: $light-gray;
+// } \ No newline at end of file
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 8f4df4a92..77e5132fc 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -15,29 +15,32 @@ import { RichTextField } from "../../../fields/RichTextField";
import { listSpec } from "../../../fields/Schema";
import { ScriptField } from "../../../fields/ScriptField";
import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils";
+import { Docs } from "../../documents/Documents";
import { DocumentType } from "../../documents/DocumentTypes";
import { CurrentUserUtils } from "../../util/CurrentUserUtils";
import { DragManager } from "../../util/DragManager";
import { Scripting } from "../../util/Scripting";
import { SelectionManager } from "../../util/SelectionManager";
+import { Transform } from "../../util/Transform";
import { undoBatch } from "../../util/UndoManager";
import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu";
import { EditableView } from "../EditableView";
import { GestureOverlay } from "../GestureOverlay";
-import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, ActiveArrowStart, ActiveArrowEnd } from "../InkingStroke";
+import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "../InkingStroke";
+import { LightboxView } from "../LightboxView";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { DocumentView } from "../nodes/DocumentView";
+import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
import { RichTextMenu } from "../nodes/formattedText/RichTextMenu";
import { PresBox } from "../nodes/trails/PresBox";
+import { DefaultStyleProvider } from "../StyleProvider";
+import { CollectionDockingView } from "./CollectionDockingView";
+import { CollectionLinearView } from "./CollectionLinearView";
import "./CollectionMenu.scss";
import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
import { TabDocView } from "./TabDocView";
-import { LightboxView } from "../LightboxView";
-import { Docs } from "../../documents/Documents";
-import { DocumentManager } from "../../util/DocumentManager";
-import { CollectionDockingView } from "./CollectionDockingView";
-import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
+import { Colors } from "../global/globalEnums";
@observer
export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -46,6 +49,8 @@ export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable SelectedCollection: DocumentView | undefined;
@observable FieldKey: string;
+ private _docBtnRef = React.createRef<HTMLDivElement>();
+
constructor(props: any) {
super(props);
this.FieldKey = "";
@@ -82,30 +87,87 @@ export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
}
}
+ buttonBarXf = () => {
+ if (!this._docBtnRef.current) return Transform.Identity();
+ const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ return new Transform(-translateX, -translateY, 1 / scale);
+ }
+
+ @computed get contMenuButtons() {
+ const selDoc = Doc.UserDoc().contextMenuBtns;
+ return !(selDoc instanceof Doc) ? (null) : <div className="collectionMenu-contMenuButtons" ref={this._docBtnRef} style={{ height: "35px" }} >
+ <CollectionLinearView
+ Document={selDoc}
+ DataDoc={undefined}
+ fieldKey={"data"}
+ dropAction={"alias"}
+ setHeight={returnFalse}
+ styleProvider={DefaultStyleProvider}
+ layerProvider={undefined}
+ rootSelected={returnTrue}
+ bringToFront={emptyFunction}
+ select={emptyFunction}
+ isContentActive={returnFalse}
+ isSelected={returnFalse}
+ docViewPath={returnEmptyDoclist}
+ moveDocument={returnFalse}
+ CollectionView={undefined}
+ addDocument={returnFalse}
+ addDocTab={returnFalse}
+ pinToPres={emptyFunction}
+ removeDocument={returnFalse}
+ ScreenToLocalTransform={this.buttonBarXf}
+ PanelWidth={() => 100}
+ PanelHeight={() => 35}
+ renderDepth={0}
+ focus={() => undefined}
+ whenChildContentsActiveChanged={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined} />
+ </div>;
+ }
+
render() {
- const button = <Tooltip title={<div className="dash-tooltip">Pin Menu</div>} key="pin menu" placement="bottom">
- <button className="antimodeMenu-button" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}>
- <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
- </button>
- </Tooltip>;
const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left";
const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Properties Panel" : "Open Properties Panel";
const prop = <Tooltip title={<div className="dash-tooltip">{propTitle}</div>} key="properties" placement="bottom">
- <button className="antimodeMenu-button" key="properties" style={{ backgroundColor: "#424242" }}
+ <div className="collectionMenu-hardCodedButton"
+ style={{ backgroundColor: CurrentUserUtils.propertiesWidth > 0 ? Colors.MEDIUM_BLUE : undefined }}
+ key="properties"
onPointerDown={this.toggleProperties}>
<FontAwesomeIcon icon={propIcon} size="lg" />
- </button>
+ </div>
</Tooltip>;
- return this.getElement(!this.SelectedCollection ? [/*button*/] :
- [<CollectionViewBaseChrome key="chrome"
- docView={this.SelectedCollection}
- fieldKey={this.SelectedCollection.LayoutFieldKey}
- type={StrCast(this.SelectedCollection?.props.Document._viewType, CollectionViewType.Invalid) as CollectionViewType} />,
- prop,
- /*button*/]);
+ // NEW BUTTONS
+ //dash col linear view buttons
+ const contMenuButtons =
+ <div className="collectionMenu-container">
+ {this.contMenuButtons}
+ {prop}
+ </div>;
+
+ return contMenuButtons;
+
+ // const button = <Tooltip title={<div className="dash-tooltip">Pin Menu</div>} key="pin menu" placement="bottom">
+ // <button className="antimodeMenu-button" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}>
+ // <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
+ // </button>
+ // </Tooltip>;
+
+ // OLD BUTTONS
+ // return this.getElement(!this.SelectedCollection ? [/*button*/] :
+ // [<CollectionViewBaseChrome key="chrome"
+ // docView={this.SelectedCollection}
+ // fieldKey={this.SelectedCollection.LayoutFieldKey}
+ // type={StrCast(this.SelectedCollection?.props.Document._viewType, CollectionViewType.Invalid) as CollectionViewType} />,
+ // prop,
+ // /*button*/]);
}
}
@@ -720,7 +782,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })}
style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001, fontSize: this._dotsize[i], padding: 0, textAlign: "center" }}>
•
- </button>
+ </button>
</Tooltip>)}
</div>;
}
@@ -991,7 +1053,7 @@ export class CollectionTreeViewChrome extends React.Component<CollectionMenuProp
<button className="collectionTreeViewChrome-sort" onClick={this.toggleSort}>
<div className="collectionTreeViewChrome-sortLabel">
Sort
- </div>
+ </div>
<div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.ascending === undefined ? "90" : this.ascending ? "180" : "0"}deg)` }}>
<FontAwesomeIcon icon="caret-up" size="2x" color="white" />
</div>
@@ -1225,3 +1287,4 @@ Scripting.addGlobal(function gotoFrame(doc: any, newFrame: any) {
CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
});
+
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index a963f1cb9..7f62ecaa0 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -1,3 +1,6 @@
+@import "../global/globalCssVariables.scss";
+
+
input.lm_title:focus,
input.lm_title {
max-width: unset !important;
@@ -57,12 +60,11 @@ input.lm_title {
}
}
-.miniMap-hidden,
.miniMap {
position: absolute;
overflow: hidden;
- right: 10;
- bottom: 10;
+ right: 15;
+ bottom: 15;
border: solid 1px;
box-shadow: black 0.4vw 0.4vw 0.8vw;
width: 100%;
@@ -82,17 +84,21 @@ input.lm_title {
}
.miniMap-hidden {
+ cursor: pointer;
position: absolute;
- bottom: 0;
- right: 0;
- width: 45px;
- height: 45px;
- transform: translate(20px, 20px) rotate(45deg);
- border-radius: 30px;
+ bottom: 5;
+ display: flex;
+ right: 5;
+ width: 25px;
+ height: 25px;
+ border-radius: 3px;
padding: 2px;
+ justify-content: center;
+ align-items: center;
+ align-content: center;
+ background-color: $light-gray;
- >svg {
- margin-top: 3px;
- transform: translate(0px, 7px);
+ &:hover {
+ box-shadow: none;
}
} \ No newline at end of file
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index e24fcf372..f80a2d8b5 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -33,6 +33,7 @@ import { CollectionView, CollectionViewType } from './CollectionView';
import "./TabDocView.scss";
import React = require("react");
import Color = require('color');
+import { Colors, Shadows } from '../global/globalEnums';
const _global = (window /* browser */ || global /* node */) as any;
interface TabDocViewProps {
@@ -123,6 +124,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
tab.element[0].prepend(iconWrap);
tab._disposers.layerDisposer = reaction(() => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
({ layer, color }) => {
+ // console.log("TabDocView: " + this.tabColor);
+ // console.log("lightOrDark: " + lightOrDark(this.tabColor));
const textColor = lightOrDark(this.tabColor); //not working with StyleProp.Color
titleEle.style.color = textColor;
titleEle.style.backgroundColor = "transparent";
@@ -390,8 +393,15 @@ export class TabDocView extends React.Component<TabDocViewProps> {
background={this.miniMapColor}
document={this._document}
tabView={this.tabView} />
- <Tooltip style={{ display: this.disableMinimap() ? "none" : undefined }} key="ttip" title={<div className="dash-tooltip">{"toggle minimap"}</div>}>
- <div className="miniMap-hidden" onPointerDown={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} >
+ <Tooltip style={{ display: this.disableMinimap() ? "none" : undefined }} key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}>
+ <div className="miniMap-hidden"
+ style={{
+ color: this._document.hideMinimap ? Colors.BLACK : Colors.WHITE,
+ backgroundColor: this._document.hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
+ boxShadow: this._document.hideMinimap ? Shadows.STANDARD_SHADOW : undefined
+ }}
+ onPointerDown={e => e.stopPropagation()}
+ onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} >
<FontAwesomeIcon icon={"globe-asia"} size="lg" />
</div>
</Tooltip>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b5d9ebd9f..985d162f9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -508,7 +508,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const points = ge.points;
const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
const inkDoc = Docs.Create.InkDocument(ActiveInkColor(), CurrentUserUtils.SelectedTool, ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), points,
- { title: "ink stroke", x: B.x - Number(ActiveInkWidth()) / 2, y: B.y - Number(ActiveInkWidth()) / 2, _width: B.width + Number(ActiveInkWidth()), _height: B.height + Number(ActiveInkWidth()) });
+ { title: "ink stroke", x: B.x - ActiveInkWidth() / 2, y: B.y - ActiveInkWidth() / 2, _width: B.width + ActiveInkWidth(), _height: B.height + ActiveInkWidth() });
this.addDocument(inkDoc);
e.stopPropagation();
break;
diff --git a/src/client/views/collections/collectionFreeForm/index.ts b/src/client/views/collections/collectionFreeForm/index.ts
new file mode 100644
index 000000000..702dc8d42
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/index.ts
@@ -0,0 +1,7 @@
+export * from "./CollectionFreeFormLayoutEngines";
+export * from "./CollectionFreeFormLinkView";
+export * from "./CollectionFreeFormLinksView";
+export * from "./CollectionFreeFormRemoteCursors";
+export * from "./CollectionFreeFormView";
+export * from "./MarqueeOptionsMenu";
+export * from "./MarqueeView"; \ No newline at end of file
diff --git a/src/client/views/collections/collectionGrid/index.ts b/src/client/views/collections/collectionGrid/index.ts
new file mode 100644
index 000000000..be5d5667a
--- /dev/null
+++ b/src/client/views/collections/collectionGrid/index.ts
@@ -0,0 +1,2 @@
+export * from "./Grid";
+export * from "./CollectionGridView"; \ No newline at end of file
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
index 46e40489b..24c9bc9cb 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
@@ -1,15 +1,31 @@
-@import "../global/globalCssVariables";
-@import "../_nodeModuleOverrides";
+@import "../../global/globalCssVariables";
+@import "../../_nodeModuleOverrides";
.collectionLinearView-outer {
overflow: visible;
height: 100%;
pointer-events: none;
+ &.true {
+ padding-left: 5px;
+ padding-right: 5px;
+ border-left: $standard-border;
+ background-color: $medium-blue-alt;
+ }
+
+ >input:not(:checked)~&.true {
+ background-color: transparent;
+ }
+
.collectionLinearView {
display: flex;
height: 100%;
align-items: center;
+ gap: 5px;
+
+ .collectionView {
+ overflow: visible !important;
+ }
>span {
background: $dark-gray;
@@ -41,7 +57,7 @@
}
.bottomPopup-descriptions {
- cursor:pointer;
+ cursor: pointer;
display: inline;
white-space: nowrap;
padding-left: 8px;
@@ -54,7 +70,7 @@
}
.bottomPopup-exit {
- cursor:pointer;
+ cursor: pointer;
display: inline;
white-space: nowrap;
margin-right: 10px;
@@ -67,29 +83,26 @@
}
>label {
- margin-top: "auto";
- margin-bottom: "auto";
- background: $dark-gray;
- color: $white;
- display: inline-block;
- border-radius: 18px;
- font-size: 12.5px;
- width: 18px;
- height: 18px;
- margin-top: auto;
- margin-bottom: auto;
- margin-right: 3px;
+ pointer-events: all;
cursor: pointer;
+ background-color: $medium-blue;
+ padding: 5;
+ border-radius: 2px;
+ height: 25;
+ min-width: 25;
+ margin: 0;
+ color: $white;
+ display: flex;
+ font-weight: 100;
+ width: fit-content;
transition: transform 0.2s;
- }
-
- label p {
- padding-left: 5px;
- }
+ align-items: center;
+ justify-content: center;
+ transition: 0.1s;
- label:hover {
- background: $medium-gray;
- transform: scale(1.15);
+ &:hover {
+ transform: scale(1.05);
+ }
}
>input {
@@ -110,13 +123,11 @@
display: flex;
opacity: 1;
position: relative;
- margin-top: auto;
.collectionLinearView-docBtn,
.collectionLinearView-docBtn-scalable {
position: relative;
margin: auto;
- margin-left: 3px;
transform-origin: center 80%;
}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/collectionLinearView/CollectionLinearView.tsx
index 52c836556..5c16f8929 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.tsx
@@ -2,21 +2,22 @@ import { Tooltip } from '@material-ui/core';
import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, HeightSym, WidthSym } from '../../../fields/Doc';
-import { documentSchema } from '../../../fields/documentSchemas';
-import { Id } from '../../../fields/FieldSymbols';
-import { makeInterface } from '../../../fields/Schema';
-import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, Utils } from '../../../Utils';
-import { DragManager } from '../../util/DragManager';
-import { Transform } from '../../util/Transform';
-import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
-import { DocumentView } from '../nodes/DocumentView';
-import { LinkDescriptionPopup } from '../nodes/LinkDescriptionPopup';
-import { StyleProp } from '../StyleProvider';
+import { Doc, HeightSym, WidthSym } from '../../../../fields/Doc';
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { Id } from '../../../../fields/FieldSymbols';
+import { makeInterface } from '../../../../fields/Schema';
+import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, Utils } from '../../../../Utils';
+import { DragManager } from '../../../util/DragManager';
+import { Transform } from '../../../util/Transform';
+import { DocumentLinksButton } from '../../nodes/DocumentLinksButton';
+import { DocumentView } from '../../nodes/DocumentView';
+import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup';
+import { StyleProp } from '../../StyleProvider';
import "./CollectionLinearView.scss";
-import { CollectionSubView } from './CollectionSubView';
-import { CollectionViewType } from './CollectionView';
+import { CollectionSubView } from '.././CollectionSubView';
+import { CollectionViewType } from '.././CollectionView';
+import { Colors, Shadows } from '../../global/globalEnums';
type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -107,35 +108,54 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
}
render() {
- const guid = Utils.GenerateGuid();
- const flexDir: any = StrCast(this.Document.flexDirection);
+ const guid = Utils.GenerateGuid(); // Generate a unique ID to use as the label
+ const flexDir: any = StrCast(this.Document.flexDirection); // Specify direction of linear view content
+ const flexGap: number = NumCast(this.Document.flexGap); // Specify the gap between linear view content
+ const expandable: boolean = BoolCast(this.props.Document.linearViewExpandable); // Specify whether it is expandable or not
+ const floating: boolean = BoolCast(this.props.Document.linearViewFloating); // Specify whether it is expandable or not
+
const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-
- const menuOpener = <label htmlFor={`${guid}`} style={{ pointerEvents: "all", cursor: "pointer", background: backgroundColor === color ? "black" : backgroundColor, }}
+ const icon: string = StrCast(this.props.Document.icon); // Menu opener toggle
+ const menuOpener = <label htmlFor={`${guid}`}
+ style={{
+ color: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.BLACK,
+ backgroundColor: backgroundColor === color ? "black" : BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.LIGHT_GRAY
+ }}
onPointerDown={e => e.stopPropagation()} >
- <p>{BoolCast(this.layoutDoc.linearViewIsExpanded) ? "–" : "+"}</p>
+ <div className="collectionLinearView-menuOpener"
+ style={{ boxShadow: floating ? Shadows.STANDARD_SHADOW : undefined }}
+ >
+ {BoolCast(this.layoutDoc.linearViewIsExpanded) ? icon ? icon : "–" : icon ? icon : "+"}
+ </div>
</label>;
- return <div className="collectionLinearView-outer">
+ return <div className={`collectionLinearView-outer ${this.layoutDoc.linearViewSubMenu}`} style={{ backgroundColor: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : "transparent" }}>
<div className="collectionLinearView" ref={this.createDashEventsTarget} >
- <Tooltip title={<><div className="dash-tooltip">{BoolCast(this.layoutDoc.linearViewIsExpanded) ? "Close menu" : "Open menu"}</div></>} placement="top">
+ {!expandable ? (null) : <Tooltip title={<><div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close" : "Open"}</div></>} placement="top">
{menuOpener}
- </Tooltip>
- <input id={`${guid}`} type="checkbox" checked={BoolCast(this.layoutDoc.linearViewIsExpanded)} ref={this.addMenuToggle}
- onChange={action(() => this.layoutDoc.linearViewIsExpanded = this.addMenuToggle.current!.checked)} />
-
- <div className="collectionLinearView-content" style={{ height: this.dimension(), flexDirection: flexDir }}>
+ </Tooltip>}
+ <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.linearViewIsExpanded)} ref={this.addMenuToggle}
+ onChange={action(() => this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} />
+
+ <div className="collectionLinearView-content"
+ style={{
+ height: this.dimension(),
+ flexDirection: flexDir,
+ gap: flexGap
+ }}>
{this.childLayoutPairs.map((pair, ind) => {
const nested = pair.layout._viewType === CollectionViewType.Linear;
const dref = React.createRef<HTMLDivElement>();
- const scalable = pair.layout.onClick || pair.layout.onDragStart;
- return <div className={`collectionLinearView-docBtn` + (scalable ? "-scalable" : "")} key={pair.layout[Id]} ref={dref}
+ const hidden = pair.layout.hidden === true;
+ // const scalable = pair.layout.onClick || pair.layout.onDragStart;
+ return hidden ? (null) : <div className={`collectionLinearView-docBtn`} key={pair.layout[Id]} ref={dref}
style={{
pointerEvents: "all",
- minWidth: 30,
- width: nested ? pair.layout[WidthSym]() : this.dimension(),
- height: nested && pair.layout.linearViewIsExpanded ? pair.layout[HeightSym]() : this.dimension(),
+ width: nested ? undefined : NumCast(pair.layout._width),
+ height: nested ? undefined : NumCast(pair.layout._height),
+ // width: NumCast(pair.layout._width),
+ // height: NumCast(pair.layout._height),
}} >
<DocumentView
Document={pair.layout}
@@ -166,7 +186,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
</div>;
})}
</div>
- {DocumentLinksButton.StartLink ? <span className="bottomPopup-background" style={{
+ {DocumentLinksButton.StartLink && StrCast(this.layoutDoc.title) === "docked buttons" ? <span className="bottomPopup-background" style={{
pointerEvents: "all"
}}
onPointerDown={e => e.stopPropagation()} >
diff --git a/src/client/views/collections/collectionLinearView/index.ts b/src/client/views/collections/collectionLinearView/index.ts
new file mode 100644
index 000000000..ff73e14ae
--- /dev/null
+++ b/src/client/views/collections/collectionLinearView/index.ts
@@ -0,0 +1 @@
+export * from "./CollectionLinearView"; \ No newline at end of file
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
index aaa50ba67..b28c32e0e 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
@@ -413,7 +413,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
bool = fields ? fields[1] === "check" : false;
}
return <div key={key} className="key-option" style={{
- border: "1px solid lightgray", paddingLeft: 5, textAlign: "left",
+ paddingLeft: 5, textAlign: "left",
width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
}}
>
@@ -489,8 +489,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
}
render() {
return (
- <div style={{ display: "flex" }} ref={this.setNode}>
- <FontAwesomeIcon onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY); e.stopPropagation(); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+ <div style={{ display: "flex", width: '100%', alignContent: 'center', alignItems: 'center' }} ref={this.setNode}>
+ <div className="schema-icon" onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY); e.stopPropagation(); }}>
+ <FontAwesomeIcon icon={this.props.icon} size="lg" style={{ display: "inline" }} />
+ </div>
{/* <FontAwesomeIcon icon={fa.faSearchMinus} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} onClick={e => {
runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen })
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx
index f48906ba5..0e19ef3d9 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx
@@ -134,9 +134,9 @@ export class MovableRow extends React.Component<MovableRowProps> {
<div className="collectionSchema-row-wrapper" onKeyPress={this.onKeyDown} ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
<ReactTableDefaults.TrComponent onKeyPress={this.onKeyDown} >
<div className="row-dragger">
- <div className="row-option" style={{ left: 5 }} onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}><FontAwesomeIcon icon="trash" size="sm" /></div>
- <div className="row-option" style={{ cursor: "grab", left: 25 }} ref={reference} onPointerDown={onItemDown}><FontAwesomeIcon icon="grip-vertical" size="sm" /></div>
- <div className="row-option" style={{ left: 40 }} onClick={() => this.props.addDocTab(this.props.rowInfo.original, "add:right")}><FontAwesomeIcon icon="external-link-alt" size="sm" /></div>
+ <div className="row-option" onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}><FontAwesomeIcon icon="trash" size="sm" /></div>
+ <div className="row-option" style={{ cursor: "grab" }} ref={reference} onPointerDown={onItemDown}><FontAwesomeIcon icon="grip-vertical" size="sm" /></div>
+ <div className="row-option" onClick={() => this.props.addDocTab(this.props.rowInfo.original, "add:right")}><FontAwesomeIcon icon="external-link-alt" size="sm" /></div>
</div>
{children}
</ReactTableDefaults.TrComponent>
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index 40cdcd14b..3074ce66e 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -108,9 +108,7 @@
}
.rt-th {
padding: 0;
- border: solid lightgray;
- border-width: 0 1px;
- border-bottom: 2px solid lightgray;
+ border-left: solid 1px $light-gray;
}
}
.rt-th {
@@ -213,6 +211,8 @@
}
}
+
+
.collectionSchemaView-header {
height: 100%;
color: gray;
@@ -227,6 +227,15 @@ button.add-column {
width: 28px;
}
+.collectionSchemaView-menuOptions-wrapper {
+ background: rgb(241, 239, 235);
+ display: flex;
+ cursor: default;
+ height: 100%;
+ align-content: center;
+ align-items: center;
+}
+
.collectionSchema-header-menuOptions {
color: black;
width: 180px;
@@ -272,6 +281,9 @@ button.add-column {
width: 10px;
}
}
+
+
+
.keys-dropdown {
position: relative;
//width: 100%;
@@ -287,26 +299,7 @@ button.add-column {
font-weight: normal;
}
}
- .keys-options-wrapper {
- width: 100%;
- max-height: 150px;
- overflow-y: scroll;
- position: absolute;
- top: 28px;
- box-shadow: 0 10px 16px rgba(0, 0, 0, 0.1);
- background-color: white;
- .key-option {
- background-color: white;
- border: 1px solid lightgray;
- padding: 2px 3px;
- &:not(:first-child) {
- border-top: 0;
- }
- &:hover {
- background-color: $light-gray;
- }
- }
- }
+
}
.columnMenu-colors {
display: flex;
@@ -325,11 +318,53 @@ button.add-column {
}
}
+.schema-icon {
+ cursor: pointer;
+ width: 25px;
+ height: 25px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ align-content: center;
+ background-color: $medium-blue;
+ color: white;
+ margin-right: 5px;
+ font-size: 10px;
+ border-radius: 3px;
+
+}
+
+.keys-options-wrapper {
+ position: absolute;
+ text-align: left;
+ height: fit-content;
+ top: 100%;
+ z-index: 21;
+ background-color: #ffffff;
+ box-shadow: 0px 3px 4px rgba(0,0,0,30%);
+ padding: 1px;
+ .key-option {
+ cursor: pointer;
+ color: #000000;
+ width: 100%;
+ height: 25px;
+ font-weight: 400;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ padding-left: 5px;
+ &:hover {
+ background-color: $light-gray;
+ }
+ }
+}
+
.collectionSchema-row {
height: 100%;
background-color: white;
&.row-focused .rt-td {
- background-color: #bfffc0; //$light-gray;
+ background-color: $light-blue; //$light-gray;
+ overflow: visible;
}
&.row-wrapped {
.rt-td {
@@ -338,39 +373,40 @@ button.add-column {
}
.row-dragger {
display: flex;
- justify-content: space-around;
- //flex: 50 0 auto;
- width: 0;
- max-width: 50px;
- //height: 100%;
+ justify-content: space-evenly;
+ width: 58px;
+ position: absolute;
+ /* max-width: 50px; */
min-height: 30px;
align-items: center;
color: lightgray;
background-color: white;
transition: color 0.1s ease;
.row-option {
- // padding: 5px;
+ color: black;
cursor: pointer;
- position: absolute;
+ position: relative;
transition: color 0.1s ease;
display: flex;
flex-direction: column;
justify-content: center;
z-index: 2;
+ border-radius: 3px;
+ padding: 3px;
&:hover {
- color: gray;
+ background-color: $light-gray;
}
}
}
.collectionSchema-row-wrapper {
&.row-above {
- border-top: 1px solid red;
+ border-top: 1px solid $medium-blue;
}
&.row-below {
- border-bottom: 1px solid red;
+ border-bottom: 1px solid $medium-blue;
}
&.row-inside {
- border: 1px solid red;
+ border: 2px dashed $medium-blue;
}
.row-dragging {
background-color: blue;
@@ -383,24 +419,32 @@ button.add-column {
height: unset;
}
+.collectionSchemaView-cellContents {
+ width: 100%;
+}
+
.collectionSchemaView-cellWrapper {
+ display: flex;
height: 100%;
- padding: 4px;
text-align: left;
padding-left: 19px;
position: relative;
+ align-items: center;
+ align-content: center;
&:focus {
outline: none;
}
&.editing {
padding: 0;
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+ transform: scale(1.1);
+ z-index: 40;
input {
outline: 0;
border: none;
- background-color: rgb(255, 217, 217);
+ background-color: $white;
width: 100%;
height: 100%;
- padding: 2px 3px;
min-height: 26px;
}
}
diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx
index abe549072..1cf466cba 100644
--- a/src/client/views/collections/collectionSchema/SchemaTable.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx
@@ -194,10 +194,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up";
const header = <div className="collectionSchemaView-menuOptions-wrapper" style={{ background: col.color, padding: "2px", display: "flex", cursor: "default", height: "100%", }}>
{keysDropdown}
- <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
+ <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "pointer" }}>
<FontAwesomeIcon icon={sortIcon} size="lg" />
</div>
- {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
+ {/* {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>} */}
</div>;
return {
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index 7556f8b8a..caa9f4fe5 100644
--- a/src/client/views/global/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -1,6 +1,7 @@
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");
// colors
$white: #ffffff;
+$off-white: #fdfdfd;
$light-gray: #dfdfdf;
$medium-gray: #9f9f9f;
$dark-gray: #323232;
@@ -8,6 +9,7 @@ $black: #000000;
$light-blue: #bdddf5;
$medium-blue: #4476f7;
+$medium-blue-alt: #4476f73d;
$pink: #e0217d;
$yellow: #f5d747;
@@ -15,6 +17,7 @@ $close-red: #e48282;
$drop-shadow: "#32323215";
+
//padding
$minimum-padding: 4px;
$medium-padding: 16px;
@@ -24,7 +27,8 @@ $large-padding: 32px;
$icon-size: 28px;
// fonts
-$sans-serif: "Roboto", sans-serif;
+$sans-serif: "Roboto",
+sans-serif;
$large-header: 16px;
$body-text: 12px;
$small-text: 9px;
@@ -43,6 +47,13 @@ $radialMenu-zindex: 100000; // context menu shows up over everything
// borders
$standard-border: solid 1px #9f9f9f;
+// border radius
+$standard-border-radius: 3px;
+
+// shadow
+$standard-box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+
+
$searchpanel-height: 32px;
$mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc
$docDecorations-zindex: 998; // then doc decorations appear over everything else
@@ -67,4 +78,4 @@ $TREE_BULLET_WIDTH: 20px;
DFLT_IMAGE_NATIVE_DIM: $DFLT_IMAGE_NATIVE_DIM;
MENU_PANEL_WIDTH: $MENU_PANEL_WIDTH;
TREE_BULLET_WIDTH: $TREE_BULLET_WIDTH;
-}
+} \ No newline at end of file
diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx
index 2aeb8e338..56779c37c 100644
--- a/src/client/views/global/globalEnums.tsx
+++ b/src/client/views/global/globalEnums.tsx
@@ -5,6 +5,7 @@ export enum Colors {
LIGHT_GRAY = "#DFDFDF",
WHITE = "#FFFFFF",
MEDIUM_BLUE = "#4476F7",
+ MEDIUM_BLUE_ALT = "#4476f73d", // REDUCED OPACITY
LIGHT_BLUE = "#BDDDF5",
PINK = "#E0217D",
YELLOW = "#F5D747",
@@ -35,4 +36,8 @@ export enum IconSizes {
export enum Borders {
STANDARD = "solid 1px #9F9F9F"
+}
+
+export enum Shadows {
+ STANDARD_SHADOW = "0px 3px 4px rgba(0, 0, 0, 0.3)"
} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 3d2cdf5a4..544125ede 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -23,7 +23,7 @@ import "./DocumentView.scss";
import { EquationBox } from "./EquationBox";
import { FieldView, FieldViewProps } from "./FieldView";
import { FilterBox } from "./FilterBox";
-import { FontIconBox } from "./FontIconBox";
+import { FontIconBox } from "./button/FontIconBox";
import { FormattedTextBox, FormattedTextBoxProps } from "./formattedText/FormattedTextBox";
import { FunctionPlotBox } from "./FunctionPlotBox";
import { ImageBox } from "./ImageBox";
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index b37b68249..228e1bdcb 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -50,6 +50,7 @@
width: 80%;
height: 80%;
font-size: 100%;
+ font-family: 'Roboto';
transition: 0.2s ease all;
&:hover {
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 7648e866e..93cd02d93 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -2,25 +2,24 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "@material-ui/core";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, Opt, WidthSym, DocListCastAsync } from "../../../fields/Doc";
-import { emptyFunction, setupMoveUpEvents, returnFalse, Utils, emptyPath } from "../../../Utils";
+import { Doc, DocListCast, DocListCastAsync, Opt, WidthSym } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { Cast, StrCast } from "../../../fields/Types";
import { TraceMobx } from "../../../fields/util";
-import { DocUtils, Docs } from "../../documents/Documents";
+import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils";
+import { DocServer } from "../../DocServer";
+import { Docs, DocUtils } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
+import { Hypothesis } from "../../util/HypothesisUtils";
import { LinkManager } from "../../util/LinkManager";
import { undoBatch, UndoManager } from "../../util/UndoManager";
+import { Colors } from "../global/globalEnums";
+import { LightboxView } from "../LightboxView";
+import './DocumentLinksButton.scss';
import { DocumentView } from "./DocumentView";
-import { StrCast, Cast } from "../../../fields/Types";
import { LinkDescriptionPopup } from "./LinkDescriptionPopup";
-import { Hypothesis } from "../../util/HypothesisUtils";
-import { Id } from "../../../fields/FieldSymbols";
import { TaskCompletionBox } from "./TaskCompletedBox";
import React = require("react");
-import './DocumentLinksButton.scss';
-import { DocServer } from "../../DocServer";
-import { LightboxView } from "../LightboxView";
-import { cat } from "shelljs";
-import { Colors } from "../global/globalEnums";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
@@ -266,6 +265,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
style={{
backgroundColor: Colors.LIGHT_BLUE,
color: Colors.BLACK,
+ fontSize: "20px",
width: btnDim,
height: btnDim,
}}>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index bb259da3e..5d9f9c6db 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -13,7 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty
import { AudioField } from "../../../fields/URLField";
import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util';
import { MobileInterface } from '../../../mobile/MobileInterface';
-import { emptyFunction, hasDescendantTarget, OmitKeys, returnVal, Utils, returnTrue } from "../../../Utils";
+import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils } from "../../../Utils";
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from '../../documents/DocumentTypes';
@@ -25,6 +25,7 @@ import { InteractionUtils } from '../../util/InteractionUtils';
import { LinkManager } from '../../util/LinkManager';
import { Scripting } from '../../util/Scripting';
import { SelectionManager } from "../../util/SelectionManager";
+import { ColorScheme } from "../../util/SettingsManager";
import { SharingManager } from '../../util/SharingManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from "../../util/Transform";
@@ -41,13 +42,13 @@ import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView
import { DocumentContentsView } from "./DocumentContentsView";
import { DocumentLinksButton } from './DocumentLinksButton';
import "./DocumentView.scss";
+import { FormattedTextBox } from "./formattedText/FormattedTextBox";
import { LinkAnchorBox } from './LinkAnchorBox';
import { LinkDocPreview } from "./LinkDocPreview";
-import { PresBox } from './trails/PresBox';
import { RadialMenu } from './RadialMenu';
-import React = require("react");
import { ScriptingBox } from "./ScriptingBox";
-import { FormattedTextBox } from "./formattedText/FormattedTextBox";
+import { PresBox } from './trails/PresBox';
+import React = require("react");
const { Howl } = require('howler');
interface Window {
@@ -134,7 +135,7 @@ export interface DocumentViewSharedProps {
export interface DocumentViewProps extends DocumentViewSharedProps {
// properties specific to DocumentViews but not to FieldView
freezeDimensions?: boolean;
- hideResizeHandles?: boolean; // whether to suppress DocumentDecorations when this document is selected
+ hideResizeHandles?: boolean; // whether to suppress DocumentDecorations when this document is selected
hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings
hideDecorationTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings
treeViewDoc?: Doc;
@@ -422,13 +423,13 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
focus = (anchor: Doc, options?: DocFocusOptions) => {
LightboxView.SetCookie(StrCast(anchor["cookies-set"]));
- // copying over VIEW fields immediately allows the view type to switch to create the right _componentView
- Array.from(Object.keys(Doc.GetProto(anchor))).filter(key => key.startsWith(ViewSpecPrefix)).forEach(spec => {
- this.layoutDoc[spec.replace(ViewSpecPrefix, "")] = ((field) => field instanceof ObjectField ? ObjectField.MakeCopy(field) : field)(anchor[spec]);
- });
+ // copying over VIEW fields immediately allows the view type to switch to create the right _componentView
+ Array.from(Object.keys(Doc.GetProto(anchor))).filter(key => key.startsWith(ViewSpecPrefix)).forEach(spec => {
+ this.layoutDoc[spec.replace(ViewSpecPrefix, "")] = ((field) => field instanceof ObjectField ? ObjectField.MakeCopy(field) : field)(anchor[spec]);
+ });
// after a timeout, the right _componentView should have been created, so call it to update its view spec values
setTimeout(() => this._componentView?.setViewSpec?.(anchor, LinkDocPreview.LinkInfo ? true : false));
- const focusSpeed = this._componentView?.scrollFocus?.(anchor, !LinkDocPreview.LinkInfo); // bcz: smooth parameter should really be passed into focus() instead of inferred here
+ const focusSpeed = this._componentView?.scrollFocus?.(anchor, !LinkDocPreview.LinkInfo); // bcz: smooth parameter should really be passed into focus() instead of inferred here
const endFocus = focusSpeed === undefined ? options?.afterFocus : async (moved: boolean) => options?.afterFocus ? options?.afterFocus(true) : ViewAdjustment.doNothing;
this.props.focus(options?.docTransform ? anchor : this.rootDoc, {
...options, afterFocus: (didFocus: boolean) =>
@@ -766,7 +767,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
!Doc.UserDoc().novice && helpItems.push({ description: "Print DataDoc in Console", event: () => console.log(this.props.Document[DataSym]), icon: "hand-point-right" });
cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" });
}
-
+
if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event
cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15);
DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
@@ -794,7 +795,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
</div>;
return <div className="documentView-contentsView"
style={{
- pointerEvents: (this.props.contentPointerEvents as any) || (CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() || this.isContentActive() ? "all" : "none"),
+ pointerEvents: (this.props.contentPointerEvents as any), // || (CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() || this.isContentActive() ? "all" : "none")
height: this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined,
}}>
<DocumentContentsView key={1} {...this.props}
@@ -953,12 +954,13 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
@computed get renderDoc() {
TraceMobx();
+ const isButton: boolean = this.props.Document.type === DocumentType.FONTICON;
if (!(this.props.Document instanceof Doc) || GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate || this.hidden) return null;
return this.docContents ??
<div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
id={this.props.Document[Id]}
style={{
- background: this.backgroundColor,
+ background: isButton ? undefined : this.backgroundColor,
opacity: this.opacity,
color: StrCast(this.layoutDoc.color, "inherit"),
fontFamily: StrCast(this.Document._fontFamily, "inherit"),
@@ -974,7 +976,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
render() {
const highlightIndex = this.props.LayoutTemplateString ? (Doc.IsHighlighted(this.props.Document) ? 6 : 0) : Doc.isBrushedHighlightedDegree(this.props.Document); // bcz: Argh!! need to identify a tree view doc better than a LayoutTemlatString
- const highlightColor = (CurrentUserUtils.ActiveDashboard?.darkScheme ?
+ const highlightColor = (Doc.UserDoc().colorScheme === ColorScheme.Dark ?
["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] :
["transparent", "#4476F7", "#4476F7", "yellow", "magenta", "cyan", "orange"])[highlightIndex];
const highlightStyle = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"][highlightIndex];
@@ -986,6 +988,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const internal = PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc;
const boxShadow = this.props.treeViewDoc ? null : highlighting && this.borderRounding && highlightStyle !== "dashed" ? `0 0 0 ${highlightIndex}px ${highlightColor}` :
this.boxShadow || (this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined);
+
+ // Return surrounding highlight
return <div className={DocumentView.ROOT_DIV} ref={this._mainCont}
onContextMenu={this.onContextMenu}
onKeyDown={this.onKeyDown}
@@ -1146,14 +1150,15 @@ export class DocumentView extends React.Component<DocumentViewProps> {
TraceMobx();
const xshift = () => (this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined);
const yshift = () => (this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined);
+ const isButton: boolean = this.props.Document.type === DocumentType.FONTICON || this.props.Document._viewType === CollectionViewType.Linear;
return (<div className="contentFittingDocumentView">
{!this.props.Document || !this.props.PanelWidth() ? (null) : (
<div className="contentFittingDocumentView-previewDoc" ref={this.ContentRef}
style={{
position: this.props.Document.isInkMask ? "absolute" : undefined,
- transform: `translate(${this.centeringX}px, ${this.centeringY}px)`,
- width: xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
- height: yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
+ transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`,
+ width: isButton ? "100%" : xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
+ height: isButton ? undefined : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
`${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`),
}}>
<DocumentViewInternal {...this.props}
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
deleted file mode 100644
index 718af2c16..000000000
--- a/src/client/views/nodes/FontIconBox.scss
+++ /dev/null
@@ -1,103 +0,0 @@
-@import "../global/globalCssVariables";
-
-.fontIconBox-label {
- color: $white;
- margin-right: 4px;
- margin-top: 1px;
- position: relative;
- text-align: center;
- font-size: 7px;
- letter-spacing: normal;
- background-color: inherit;
- border-radius: 8px;
- margin-top: -8px;
- padding: 0;
- width: 100%;
-}
-
-.fontIconBadge-container {
- position:absolute;
- z-index: 1000;
- top: 12px;
-
- .fontIconBadge {
- position: absolute;
- top: -10px;
- right: -10px;
- color: $white;
- background: $pink;
- font-weight: 300;
- border-radius: 100%;
- width: 25px;
- height: 25px;
- text-align: center;
- padding-top: 4px;
- font-size: 12px;
- }
-}
-
-.menuButton-circle,
-.menuButton-round {
- border-radius: 100%;
- background-color: $dark-gray;
- padding: 0;
-
- .fontIconBox-label {
- //margin-left: -10px; // button padding is 10px;
- bottom: 0;
- position: absolute;
- }
-
- &:hover {
- background-color: $light-gray;
- }
-}
-
-.menuButton-square {
- padding-top: 3px;
- padding-bottom: 3px;
- background-color: $dark-gray;
-
- .fontIconBox-label {
- border-radius: 0px;
- margin-top: 0px;
- border-radius: "inherit";
- }
-}
-
-.menuButton,
-.menuButton-circle,
-.menuButton-round,
-.menuButton-square {
- margin-left: -5%;
- width: 110%;
- height: 100%;
- pointer-events: all;
- touch-action: none;
-
- .menuButton-wrap {
- touch-action: none;
- border-radius: 8px;
- width: 100%;
- }
-
- .menuButton-icon-square {
- width: auto;
- height: 29px;
- padding: 4px;
- }
-
- svg {
- width: 95% !important;
- height: 95%;
- }
-}
-.menuButton-round {
- width: 100%;
- svg {
- width: 50% !important;
- height: 50%;
- position: relative;
- bottom: 2px;
- }
-} \ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
deleted file mode 100644
index 0d415e238..000000000
--- a/src/client/views/nodes/FontIconBox.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Tooltip } from '@material-ui/core';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { AclPrivate, Doc, DocListCast } from '../../../fields/Doc';
-import { createSchema, makeInterface } from '../../../fields/Schema';
-import { ScriptField } from '../../../fields/ScriptField';
-import { Cast, StrCast } from '../../../fields/Types';
-import { GetEffectiveAcl } from '../../../fields/util';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils";
-import { DragManager } from '../../util/DragManager';
-import { ContextMenu } from '../ContextMenu';
-import { DocComponent } from '../DocComponent';
-import { StyleProp } from '../StyleProvider';
-import { FieldView, FieldViewProps } from './FieldView';
-import './FontIconBox.scss';
-import { Colors } from '../global/globalEnums';
-const FontIconSchema = createSchema({
- icon: "string",
-});
-
-type FontIconDocument = makeInterface<[typeof FontIconSchema]>;
-const FontIconDocument = makeInterface(FontIconSchema);
-@observer
-export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(FontIconDocument) {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); }
- showTemplate = (): void => {
- const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
- dragFactory && this.props.addDocTab(dragFactory, "add:right");
- }
- dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); };
- useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };
-
- specificContextMenu = (): void => {
- if (!Doc.UserDoc().noviceMode) {
- const cm = ContextMenu.Instance;
- cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
- cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
- cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
- }
- }
-
- render() {
- const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
- const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
- const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- const shape = StrCast(this.layoutDoc.iconShape, label ? "round" : "circle");
- const icon = StrCast(this.dataDoc.icon, "user") as any;
- const presSize = shape === 'round' ? 25 : 30;
- const presTrailsIcon = <img src={`/assets/${"presTrails.png"}`}
- style={{ width: presSize, height: presSize, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})`, marginBottom: "5px" }} />;
- const button = <button className={`menuButton-${shape}`} onContextMenu={this.specificContextMenu}
- style={{ backgroundColor: backgroundColor, }}>
- <div className="menuButton-wrap">
- {icon === 'pres-trail' ? presTrailsIcon : <FontAwesomeIcon className={`menuButton-icon-${shape}`} icon={icon} color={color}
- size={this.layoutDoc.iconShape === "square" ? "sm" : "sm"} />}
- {!label ? (null) : <div className="fontIconBox-label" style={{ color, backgroundColor }}> {label} </div>}
- <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} />
- </div>
- </button>;
- return !this.layoutDoc.toolTip ? button :
- <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
- {button}
- </Tooltip>;
- }
-}
-
-interface FontIconBadgeProps {
- collection: Doc | undefined;
-}
-
-@observer
-export class FontIconBadge extends React.Component<FontIconBadgeProps> {
- _notifsRef = React.createRef<HTMLDivElement>();
-
- onPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e,
- (e: PointerEvent) => {
- const dragData = new DragManager.DocumentDragData([this.props.collection!]);
- DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
- return true;
- },
- returnFalse, emptyFunction, false);
- }
-
- render() {
- if (!(this.props.collection instanceof Doc)) return (null);
- const length = DocListCast(this.props.collection.data).filter(d => GetEffectiveAcl(d) !== AclPrivate).length; // Object.keys(d).length).length; // filter out any documents that we can't read
- return <div className="fontIconBadge-container" style={{ width: 15, height: 15, top: 12 }} ref={this._notifsRef}>
- <div className="fontIconBadge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
- onPointerDown={this.onPointerDown} >
- {length}
- </div>
- </div>;
- }
-} \ No newline at end of file
diff --git a/src/client/views/nodes/button/ButtonScripts.ts b/src/client/views/nodes/button/ButtonScripts.ts
new file mode 100644
index 000000000..bb4dd8bc9
--- /dev/null
+++ b/src/client/views/nodes/button/ButtonScripts.ts
@@ -0,0 +1,14 @@
+import { Scripting } from "../../../util/Scripting";
+import { SelectionManager } from "../../../util/SelectionManager";
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function changeView(view: string) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ selected ? selected.Document._viewType = view : console.log("[FontIconBox.tsx] changeView failed");
+});
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function toggleOverlay() {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("failed");
+}); \ No newline at end of file
diff --git a/src/client/views/nodes/button/FontIconBadge.tsx b/src/client/views/nodes/button/FontIconBadge.tsx
new file mode 100644
index 000000000..3e451eea6
--- /dev/null
+++ b/src/client/views/nodes/button/FontIconBadge.tsx
@@ -0,0 +1,36 @@
+import { observer } from "mobx-react";
+import React from "react";
+import { AclPrivate, Doc, DocListCast } from "../../../../fields/Doc";
+import { GetEffectiveAcl } from "../../../../fields/util";
+import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../../Utils";
+import { DragManager } from "../../../util/DragManager";
+
+interface FontIconBadgeProps {
+ collection: Doc | undefined;
+}
+
+@observer
+export class FontIconBadge extends React.Component<FontIconBadgeProps> {
+ _notifsRef = React.createRef<HTMLDivElement>();
+
+ onPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e,
+ (e: PointerEvent) => {
+ const dragData = new DragManager.DocumentDragData([this.props.collection!]);
+ DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
+ return true;
+ },
+ returnFalse, emptyFunction, false);
+ }
+
+ render() {
+ if (!(this.props.collection instanceof Doc)) return (null);
+ const length = DocListCast(this.props.collection.data).filter(d => GetEffectiveAcl(d) !== AclPrivate).length; // Object.keys(d).length).length; // filter out any documents that we can't read
+ return <div className="fontIconBadge-container" style={{ width: 15, height: 15, top: 12 }} ref={this._notifsRef}>
+ <div className="fontIconBadge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
+ onPointerDown={this.onPointerDown} >
+ {length}
+ </div>
+ </div>;
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/button/FontIconBox.scss
new file mode 100644
index 000000000..8de97ea89
--- /dev/null
+++ b/src/client/views/nodes/button/FontIconBox.scss
@@ -0,0 +1,383 @@
+@import "../../global/globalCssVariables";
+
+.menuButton {
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 80%;
+ border-radius: $standard-border-radius;
+
+ .menuButton-wrap {
+ grid-column: 1;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ }
+
+ .fontIconBox-label {
+ color: $white;
+ position: relative;
+ text-align: center;
+ font-size: 7px;
+ letter-spacing: normal;
+ background-color: inherit;
+ margin-top: 5px;
+ border-radius: 8px;
+ padding: 0;
+ width: 100%;
+ font-family: 'ROBOTO';
+ text-transform: uppercase;
+ font-weight: bold;
+ }
+
+ .fontIconBox-icon {
+ width: 80%;
+ height: 80%;
+ }
+
+ &.clickBtn {
+ cursor: pointer;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3) !important;
+ }
+
+ svg {
+ width: 50% !important;
+ height: 50%;
+ }
+ }
+
+ &.tglBtn {
+ cursor: pointer;
+
+ &.switch {
+ //TOGGLE
+
+ .switch {
+ position: relative;
+ display: inline-block;
+ width: 100%;
+ height: 25px;
+ margin: 0;
+ }
+
+ .switch input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+ }
+
+ .slider {
+ position: absolute;
+ cursor: pointer;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: lightgrey;
+ -webkit-transition: .4s;
+ transition: .4s;
+ }
+
+ .slider:before {
+ position: absolute;
+ content: "";
+ height: 21px;
+ width: 21px;
+ left: 2px;
+ bottom: 2px;
+ background-color: $white;
+ -webkit-transition: .4s;
+ transition: .4s;
+ }
+
+ input:checked+.slider {
+ background-color: $medium-blue;
+ }
+
+ input:focus+.slider {
+ box-shadow: 0 0 1px $medium-blue;
+ }
+
+ input:checked+.slider:before {
+ -webkit-transform: translateX(26px);
+ -ms-transform: translateX(26px);
+ transform: translateX(26px);
+ }
+
+ /* Rounded sliders */
+ .slider.round {
+ border-radius: $standard-border-radius;
+ }
+
+ .slider.round:before {
+ border-radius: $standard-border-radius;
+ }
+ }
+
+ svg {
+ width: 50% !important;
+ height: 50%;
+ }
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3) !important;
+ }
+ }
+
+ &.toolBtn {
+ cursor: pointer;
+ width: 40px;
+ border-radius: 100%;
+
+ svg {
+ width: 60% !important;
+ height: 60%;
+ }
+ }
+
+ &.menuBtn {
+ cursor: pointer;
+ border-radius: 0px;
+ flex-direction: column;
+
+ svg {
+ width: 45% !important;
+ height: 45%;
+ }
+ }
+
+
+
+ &.colorBtn {
+ color: black;
+ cursor: pointer;
+ flex-direction: column;
+ background: transparent;
+
+ .colorButton-color {
+ margin-top: 3px;
+ width: 90%;
+ height: 6px;
+ }
+
+ .menuButton-dropdownBox {
+ position: absolute;
+ width: fit-content;
+ height: fit-content;
+ color: black;
+ top: 100%;
+ z-index: 21;
+ background-color: #e3e3e3;
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+ border-radius: 3px;
+ }
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3) !important;
+ }
+ }
+
+ &.drpdownList {
+ width: 100%;
+ display: grid;
+ grid-auto-columns: 80px 20px;
+ justify-items: center;
+ font-family: 'Roboto';
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ font-size: 13;
+ font-weight: 600;
+ overflow: hidden;
+ cursor: pointer;
+ background: transparent;
+ align-content: center;
+ align-items: center;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3) !important;
+ }
+
+ .menuButton-dropdownList {
+ position: absolute;
+ width: 150px;
+ height: fit-content;
+ top: 100%;
+ z-index: 21;
+ background-color: $white;
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+ padding: 1px;
+
+ .list-item {
+ color: $black;
+ width: 100%;
+ height: 25px;
+ font-weight: 400;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ padding-left: 5px;
+ }
+
+ .list-item:hover {
+ background-color: lightgrey;
+ }
+ }
+ }
+
+ &.numBtn {
+ cursor: pointer;
+ background: transparent;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3) !important;
+ }
+
+ &.slider {
+ color: $white;
+ cursor: pointer;
+ flex-direction: column;
+ background: transparent;
+
+ .menu-slider {
+ width: 100px;
+ }
+
+ .menuButton-dropdownBox {
+ position: absolute;
+ width: fit-content;
+ height: fit-content;
+ top: 100%;
+ z-index: 21;
+ background-color: #e3e3e3;
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+ border-radius: $standard-border-radius;
+ }
+ }
+
+ .button {
+ width: 25%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &.number {
+ width: 50%;
+
+ .button-input {
+ background: none;
+ border: none;
+ text-align: right;
+ width: 100%;
+ color: $white;
+ height: 100%;
+ text-align: center;
+ }
+
+ .button-input:focus {
+ outline: none;
+ }
+ }
+ }
+
+ &.list {
+ width: 100%;
+ justify-content: space-around;
+ border: $standard-border;
+
+ .menuButton-dropdownList {
+ position: absolute;
+ width: fit-content;
+ height: fit-content;
+ min-width: 50%;
+ max-height: 50vh;
+ overflow-y: scroll;
+ top: 100%;
+ z-index: 21;
+ background-color: $white;
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+ padding: 1px;
+
+ .list-item {
+ color: $black;
+ width: 100%;
+ height: 25px;
+ font-weight: 400;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .list-item:hover {
+ background-color: lightgrey;
+ }
+ }
+ }
+ }
+
+ &.editableText {
+ cursor: pointer;
+ background: transparent;
+ width: 100%;
+ height: 100%;
+
+ &:hover {
+ background-color: $close-red;
+ }
+ }
+
+ &.drpDownBtn {
+ cursor: pointer;
+ background: transparent;
+ border: solid 0.5px grey;
+
+ &.true {
+ background: rgba(0, 0, 0, 0.3);
+ }
+
+ .menuButton-dropdownBox {
+ position: absolute;
+ width: 150px;
+ height: 250px;
+ top: 100%;
+ background-color: #e3e3e3;
+ box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+ border-radius: $standard-border-radius;
+ }
+ }
+
+ .menuButton-dropdown {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 15px;
+ grid-column: 2;
+ border-radius: 0px 7px 7px 0px;
+ width: 13px;
+ height: 100%;
+ right: 0;
+ }
+
+ .menuButton-dropdown-header {
+ width: 100%;
+ font-weight: 300;
+ padding: 5px;
+ overflow: hidden;
+ font-size: 12px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
+ .dropbox-background {
+ width: 100vw;
+ height: 100vh;
+ top: 0;
+ z-index: 20;
+ left: 0;
+ background: transparent;
+ position: fixed;
+ }
+
+} \ No newline at end of file
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
new file mode 100644
index 000000000..53cd017b0
--- /dev/null
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -0,0 +1,761 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@material-ui/core';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { StringifyOptions } from 'querystring';
+import * as React from 'react';
+import { ColorState, SketchPicker } from 'react-color';
+import { Doc, StrListCast } from '../../../../fields/Doc';
+import { InkTool } from '../../../../fields/InkField';
+import { createSchema, makeInterface } from '../../../../fields/Schema';
+import { ScriptField } from '../../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, StrCast } from '../../../../fields/Types';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Scripting } from "../../../util/Scripting";
+import { SelectionManager } from '../../../util/SelectionManager';
+import { ColorScheme } from '../../../util/SettingsManager';
+import { UndoManager } from '../../../util/UndoManager';
+import { CollectionViewType } from '../../collections/CollectionView';
+import { ContextMenu } from '../../ContextMenu';
+import { DocComponent } from '../../DocComponent';
+import { EditableView } from '../../EditableView';
+import { Colors } from '../../global/globalEnums';
+import { StyleProp } from '../../StyleProvider';
+import { FieldView, FieldViewProps } from '.././FieldView';
+import { RichTextMenu } from '../formattedText/RichTextMenu';
+import './FontIconBox.scss';
+import { SetActiveInkWidth, SetActiveInkColor } from '../../InkingStroke';
+import { GestureOverlay } from '../../GestureOverlay';
+import { WebField } from '../../../../fields/URLField';
+const FontIconSchema = createSchema({
+ icon: "string",
+});
+
+export enum ButtonType {
+ MenuButton = "menuBtn",
+ DropdownList = "drpdownList",
+ DropdownButton = "drpdownBtn",
+ ClickButton = "clickBtn",
+ DoubleButton = "dblBtn",
+ ToggleButton = "tglBtn",
+ ColorButton = "colorBtn",
+ ToolButton = "toolBtn",
+ NumberButton = "numBtn",
+ EditableText = "editableText"
+}
+
+export enum NumButtonType {
+ Slider = "slider",
+ DropdownOptions = "list",
+ Inline = "inline"
+}
+
+export interface ButtonProps extends FieldViewProps {
+ type?: ButtonType;
+}
+
+type FontIconDocument = makeInterface<[typeof FontIconSchema]>;
+const FontIconDocument = makeInterface(FontIconSchema);
+@observer
+export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(FontIconDocument) {
+ public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); }
+ showTemplate = (): void => {
+ const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
+ dragFactory && this.props.addDocTab(dragFactory, "add:right");
+ }
+ dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); };
+ useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };
+
+ specificContextMenu = (): void => {
+ if (!Doc.UserDoc().noviceMode) {
+ const cm = ContextMenu.Instance;
+ cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
+ cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
+ cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
+ }
+ }
+
+ // Determining UI Specs
+ @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
+ @observable private icon = StrCast(this.dataDoc.icon, "user") as any;
+ @observable private dropdown: boolean = BoolCast(this.rootDoc.dropDownOpen);
+ @observable private buttonList: string[] = StrListCast(this.rootDoc.btnList);
+ @observable private type = StrCast(this.rootDoc.btnType);
+
+ /**
+ * Types of buttons in dash:
+ * - Main menu button (LHS)
+ * - Tool button
+ * - Expandable button (CollectionLinearView)
+ * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
+ * - Action button
+ * - Dropdown button
+ * - Color button
+ * - Dropdown list
+ * - Number button
+ **/
+
+ _batch: UndoManager.Batch | undefined = undefined;
+ /**
+ * Number button
+ */
+ @computed get numberButton() {
+ const numBtnType: string = StrCast(this.rootDoc.numBtnType);
+ const setValue = (value: number) => {
+ // Script for running the toggle
+ const script: string = StrCast(this.rootDoc.script) + "(" + value + ")";
+ ScriptField.MakeScript(script)?.script.run();
+ };
+
+ // Script for checking the outcome of the toggle
+ const checkScript: string = StrCast(this.rootDoc.script) + "(0, true)";
+ const checkResult: number = ScriptField.MakeScript(checkScript)?.script.run().result;
+
+
+ if (numBtnType === NumButtonType.Slider) {
+ const dropdown =
+ <div
+ className="menuButton-dropdownBox"
+ onPointerDown={e => e.stopPropagation()}
+ style={{ left: 0 }}
+ >
+ <input type="range" step="1" min="0" max="100" value={checkResult}
+ className={"menu-slider"} id="slider"
+ onPointerDown={() => { this._batch = UndoManager.StartBatch("presDuration"); }}
+ onPointerUp={() => { if (this._batch) this._batch.end(); }}
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); setValue(Number(e.target.value)); }}
+ />
+ </div>;
+ return (
+ <div
+ className={`menuButton ${this.type} ${numBtnType}`}
+ onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
+ >
+ {checkResult}
+ {this.rootDoc.dropDownOpen ? dropdown : null}
+ </div>
+ );
+ } else if (numBtnType === NumButtonType.DropdownOptions) {
+ const items: number[] = [];
+ for (let i = 0; i < 100; i++) {
+ if (i % 2 === 0) {
+ items.push(i);
+ }
+ }
+ const list = items.map((value) => {
+ return <div className="list-item" key={`${value}`}
+ style={{
+ backgroundColor: value === checkResult ? Colors.LIGHT_BLUE : undefined
+ }}
+ onClick={() => setValue(value)}>
+ {value}
+ </div>;
+ });
+ return (
+ <div
+ className={`menuButton ${this.type} ${numBtnType}`}
+ >
+ <div className={`button`} onClick={action((e) => setValue(checkResult - 1))}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"minus"} />
+ </div>
+ <div
+ className={`button ${'number'}`}
+ onPointerDown={(e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ }}
+ onDoubleClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
+ >
+ <input
+ style={{ width: 30 }}
+ className="button-input"
+ type="number"
+ value={checkResult}
+ onChange={action((e) => setValue(Number(e.target.value)))}
+ />
+ </div>
+ <div className={`button`} onClick={action((e) => setValue(checkResult + 1))}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"plus"} />
+ </div>
+ {this.rootDoc.dropDownOpen ?
+ <div>
+ <div className="menuButton-dropdownList"
+ style={{ left: "25%" }}>
+ {list}
+ </div>
+ <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
+ </div> : null}
+
+ </div>
+ );
+ } else {
+ return (
+ <div>
+
+ </div>
+ );
+ }
+
+
+ }
+
+ /**
+ * Dropdown button
+ */
+ @computed get dropdownButton() {
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ return (
+ <div className={`menuButton ${this.type} ${active}`}
+ style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
+ onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
+ <div
+ className="menuButton-dropdown"
+ style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
+ <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
+ </div>
+ {this.rootDoc.dropDownOpen ?
+ <div className="menuButton-dropdownBox"
+ style={{ left: 0 }}>
+ {/* DROPDOWN BOX CONTENTS */}
+ </div> : null}
+ </div>
+ );
+ }
+
+ /**
+ * Dropdown list
+ */
+ @computed get dropdownListButton() {
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+ const script: string = StrCast(this.rootDoc.script);
+
+ let noviceList: string[] = [];
+ let text: string | undefined;
+ let dropdown = true;
+ let icon: IconProp = "caret-down";
+
+
+ if (script === 'setView') {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ if (selected && StrCast(selected.Document.type) === DocumentType.COL) {
+ text = StrCast(selected.Document._viewType);
+ } else if (selected) {
+ dropdown = false;
+ text = StrCast(selected.Document.type);
+ icon = Doc.toIcon(selected.Document);
+ } else {
+ dropdown = false;
+ text = "None selected";
+ }
+ noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
+ } else if (script === 'setFont') {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ if (selected && StrCast(selected.Document.type) === DocumentType.RTF) {
+ text = StrCast(selected.Document._fontFamily);
+ } else {
+ const fontFamily = StrCast(Doc.UserDoc()._fontFamily);
+ text = fontFamily;
+ }
+ noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia",
+ "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
+ }
+
+ // Get items to place into the list
+ const list = this.buttonList.map((value) => {
+ if (Doc.UserDoc().noviceMode && !noviceList.includes(value)) {
+ return;
+ }
+ const click = () => {
+ const s = ScriptField.MakeScript(script + '("' + value + '")');
+ if (s) {
+ s.script.run().result;
+ }
+ };
+ return <div className="list-item" key={`${value}`}
+ style={{
+ fontFamily: script === 'setFont' ? value : undefined,
+ backgroundColor: value === text ? Colors.LIGHT_BLUE : undefined
+ }}
+ onClick={click}>
+ {value[0].toUpperCase() + value.slice(1)}
+ </div>;
+ });
+
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+
+ return (
+ <div className={`menuButton ${this.type} ${active}`}
+ style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
+ onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
+ {dropdown ? (null) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
+ <div className="menuButton-dropdown-header">
+ {text && text[0].toUpperCase() + text.slice(1)}
+ </div>
+ {label}
+ {!dropdown ? (null) : <div className="menuButton-dropDown">
+ <FontAwesomeIcon icon={icon} color={color} size="sm" />
+ </div>}
+ {this.rootDoc.dropDownOpen ?
+ <div>
+ <div className="menuButton-dropdownList"
+ style={{ left: 0 }}>
+ {list}
+ </div>
+ <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
+ </div>
+ : null}
+ </div>
+ );
+ }
+
+ /**
+ * Color button
+ */
+ @computed get colorButton() {
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+ const script: string = StrCast(this.rootDoc.script);
+ const scriptCheck: string = script + "(undefined, true)";
+ const boolResult = ScriptField.MakeScript(scriptCheck)?.script.run().result;
+
+ let stroke: boolean = false;
+ let strokeIcon: any;
+ if (script === "setStrokeColor"){
+ stroke = true;
+ const checkWidth = ScriptField.MakeScript("setStrokeWidth(0, true)")?.script.run().result;
+ strokeIcon = (<div style={{borderRadius: "100%", width: Number(checkWidth)+'%', height: Number(checkWidth)+'%', backgroundColor: boolResult }}/>)
+ }
+
+ const colorOptions: string[] = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+ '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+ '#FFFFFF', '#f1efeb'];
+
+ const colorBox = (func: (color: ColorState) => void) => <SketchPicker
+ disableAlpha={!stroke}
+ onChange={func} color={boolResult ? boolResult : "#FFFFFF"}
+ presetColors={colorOptions} />;
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+
+ const dropdownCaret = <div
+ className="menuButton-dropDown"
+ style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
+ <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
+ </div>;
+
+ const click = (value: ColorState) => {
+ const hex: string = value.hex;
+ const s = ScriptField.MakeScript(script + '("' + hex + '", false)');
+ if (s) {
+ s.script.run().result;
+ }
+ };
+ return (
+ <div className={`menuButton ${this.type} ${active}`}
+ style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
+ onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
+ onPointerDown={e => e.stopPropagation()}>
+ {stroke ? strokeIcon : <><FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ <div className="colorButton-color"
+ style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }}
+ ></div></>}
+ {label}
+ {/* {dropdownCaret} */}
+ {this.rootDoc.dropDownOpen ?
+ <div>
+ <div className="menuButton-dropdownBox"
+ onPointerDown={e => e.stopPropagation()}
+ onClick={e => e.stopPropagation()}
+ style={{ left: 0 }}>
+ {colorBox(click)}
+ </div>
+ <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
+ </div>
+ : null}
+ </div>
+ );
+ }
+
+ @computed get toggleButton() {
+ // Determine the type of toggle button
+ const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
+
+ // Script for running the toggle
+ const script: string = StrCast(this.rootDoc.script);
+
+ // Script for checking the outcome of the toggle
+ let checkScript:string;
+ if (StrCast(this.rootDoc.script).includes("(")){
+ checkScript = StrCast(this.rootDoc.script)
+
+ } else {
+ checkScript = StrCast(this.rootDoc.script) + "(true)";
+ }
+
+ // Function to run the script
+ const runScript = () => ScriptField.MakeScript(script + "()")?.script.run();
+ const checkResult = ScriptField.MakeScript(checkScript)?.script.run().result;
+
+ // Colors
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+ // Button label
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+
+ if (switchToggle) {
+ return (
+ <div className={`menuButton ${this.type} ${'switch'}`}
+ onClick={runScript}
+ >
+ <label className="switch">
+ <input type="checkbox"
+ checked={checkResult}
+ onChange={runScript}
+ />
+ <span className="slider round"></span>
+ </label>
+ </div>
+ );
+ } else {
+ return (
+ <div className={`menuButton ${this.type}`}
+ style={{ opacity: 1, backgroundColor: checkResult ? Colors.MEDIUM_BLUE : "transparent" }}
+ onClick={this.layoutDoc.ignoreClick ? runScript : undefined}
+ >
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={checkResult ? Colors.LIGHT_GRAY : Colors.LIGHT_GRAY} />
+ {label}
+ </div>
+ );
+ }
+ }
+
+
+
+ /**
+ * Default
+ */
+ @computed get defaultButton() {
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ return (
+ <div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu}
+ style={{ backgroundColor: "transparent", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
+ <div className="menuButton-wrap">
+ <FontAwesomeIcon className={`menuButton-icon-${this.type}`} icon={this.icon} color={"black"} size={"sm"} />
+ {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
+ </div>
+ </div>
+ );
+ }
+
+ @computed get editableText() {
+ // Script for running the toggle
+ const script: string = StrCast(this.rootDoc.script);
+
+ // Script for checking the outcome of the toggle
+ let checkScript:string = StrCast(this.rootDoc.script) + "('', true)";
+
+ // Function to run the script
+ const checkResult = ScriptField.MakeScript(checkScript)?.script.run().result;
+
+ const setValue = (value: string, shiftDown?: boolean): boolean => {
+ ScriptField.MakeScript(script + "('"+value+"')")?.script.run();
+ return true;
+ };
+ return (
+ <div className="menuButton editableText">
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"lock"} />
+ <EditableView GetValue={() => checkResult} SetValue={setValue} contents="...">
+ </EditableView>
+ </div>
+ );
+ }
+
+
+ render() {
+ const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+ const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ // Variables called through eval (from button)
+ const numSelected = SelectionManager.Views().length;
+
+ const dark: boolean = Doc.UserDoc().colorScheme === ColorScheme.Dark;
+
+ const active: string = StrCast(this.rootDoc.dropDownOpen);
+ const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
+ {this.label}
+ </div>;
+ const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
+ {this.label}
+ </div>;
+
+ // TODO:glr Add label of button type
+ let button = this.defaultButton;
+
+ switch (this.type) {
+ case ButtonType.EditableText:
+ console.log("Editable text");
+ button = this.editableText;
+ break;
+ case ButtonType.NumberButton:
+ button = this.numberButton;
+ break;
+ case ButtonType.DropdownButton:
+ button = this.dropdownButton;
+ break;
+ case ButtonType.DropdownList:
+ button = this.dropdownListButton;
+ break;
+ case ButtonType.ColorButton:
+ button = this.colorButton;
+ break;
+ case ButtonType.ToolButton:
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor: backgroundColor, color: color }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {label}
+ </div>
+ );
+ break;
+ case ButtonType.ToggleButton:
+ button = this.toggleButton;
+ break;
+ case ButtonType.ClickButton:
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1 }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {label}
+ </div>
+ );
+ break;
+ case ButtonType.MenuButton:
+ button = (
+ <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor }}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
+ {menuLabel}
+ </div >
+ );
+ break;
+ default:
+ break;
+ }
+
+ return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? button :
+ <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
+ {button}
+ </Tooltip>;
+ }
+}
+
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function setView(view: string) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ selected ? selected.Document._viewType = view : console.log("[FontIconBox.tsx] changeView failed");
+});
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: boolean) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+ if (checkResult) {
+ if (selected) {
+ console.log("[Background] (selected): " + StrCast(selected._backgroundColor));
+ return selected._backgroundColor;
+ } else {
+ return "#FFFFFF";
+ }
+ }
+ if (selected && selected.type === DocumentType.INK) selected.fillColor = color;
+ if (selected) selected._backgroundColor = color;
+ Doc.UserDoc()._fontColor = color;
+});
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+ if (checkResult && selected) {
+ return NumCast(selected.Document.z) === 1;
+ }
+ selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
+});
+
+/** TEXT
+ * setFont
+ * setFontSize
+ * toggleBold
+ * toggleUnderline
+ * toggleItalic
+ **/
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function setFont(font: string) {
+ SelectionManager.Views().map(dv => dv.props.Document._fontFamily = font);
+ Doc.UserDoc()._fontFamily = font;
+ return Doc.UserDoc()._fontFamily;
+});
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function setFontColor(color?: string, checkResult?: boolean) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+ if (checkResult) {
+ if (selected) {
+ console.log("[Font color] (selected): " + StrCast(selected._fontColor));
+ return selected._fontColor;
+ } else {
+ console.log("[Font color] (global): " + StrCast(Doc.UserDoc()._fontColor));
+ return Doc.UserDoc()._fontColor;
+ }
+ }
+ if (selected) selected._fontColor = color;
+ Doc.UserDoc()._fontColor = color;
+});
+
+// // toggle: Set overlay status of selected document
+// Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: boolean) {
+// const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
+// if (checkResult) {
+// if (selected) {
+// return selected.Document._fontColor;
+// } else {
+// return Doc.UserDoc()._fontColor;
+// }
+// }
+// Doc.UserDoc()._fontColor = color;
+// });
+
+
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function setFontSize(size: string, checkResult?: boolean) {
+ if (checkResult) {
+ const size: number = parseInt(StrCast(Doc.UserDoc()._fontSize), 10);
+ return size;
+ }
+ Doc.UserDoc()._fontSize = size + "px";
+});
+
+Scripting.addGlobal(function toggleBold(checkResult?: boolean) {
+ if (checkResult) {
+ return Doc.UserDoc().bold;
+ }
+ SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.RTF).map(dv => dv.props.Document.italic = !dv.props.Document.italic);
+ Doc.UserDoc().bold = !Doc.UserDoc().bold;
+ return Doc.UserDoc().bold;
+});
+
+Scripting.addGlobal(function toggleUnderline(checkResult?: boolean) {
+ if (checkResult) {
+ return Doc.UserDoc().underline;
+ }
+ SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.RTF).map(dv => dv.props.Document.italic = !dv.props.Document.italic);
+ Doc.UserDoc().underline = !Doc.UserDoc().underline;
+ return Doc.UserDoc().underline;
+});
+
+Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
+ if (checkResult) {
+ return Doc.UserDoc().italic;
+ }
+ SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.RTF).map(dv => dv.props.Document.italic = !dv.props.Document.italic);
+ Doc.UserDoc().italic = !Doc.UserDoc().italic;
+ return Doc.UserDoc().italic;
+});
+
+
+
+
+/** INK
+ * setActiveInkTool
+ * setStrokeWidth
+ * setStrokeColor
+ **/
+
+Scripting.addGlobal(function setActiveInkTool(tool: string, checkResult?: boolean) {
+ if (checkResult) {
+ return Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool;
+ }
+ if (tool === "circle") {
+ Doc.UserDoc().activeInkTool = "pen";
+ GestureOverlay.Instance.InkShape = tool;
+ } else if (tool === "square") {
+ Doc.UserDoc().activeInkTool = "pen";
+ GestureOverlay.Instance.InkShape = tool;
+ } else if (tool === "line") {
+ Doc.UserDoc().activeInkTool = "pen";
+ GestureOverlay.Instance.InkShape = tool;
+ } else if (tool) {
+ if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool){
+ GestureOverlay.Instance.InkShape = "";
+ Doc.UserDoc().activeInkTool = InkTool.None;
+ } else {
+ Doc.UserDoc().activeInkTool = tool;
+ }
+ } else {
+ Doc.UserDoc().activeInkTool = InkTool.None;
+ }
+});
+
+Scripting.addGlobal(function setStrokeWidth(width: number, checkResult?: boolean) {
+ if (checkResult) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+ if (selected && selected.type === DocumentType.INK){
+ return Number(selected.strokeWidth);
+ } else {
+ const width: number = NumCast(Doc.UserDoc().activeInkWidth);
+ return width;
+ }
+ }
+ Doc.UserDoc().activeInkWidth = width;
+ SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(width));
+});
+
+// toggle: Set overlay status of selected document
+Scripting.addGlobal(function setStrokeColor(color?: string, checkResult?: boolean) {
+ if (checkResult) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+ if (selected && selected.type === DocumentType.INK){
+ return selected.color;
+ } else {
+ const color: string = StrCast(Doc.UserDoc().activeInkColor);
+ return color;
+ }
+ }
+ SetActiveInkColor(StrCast(color));
+ SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.color = String(color));
+});
+
+
+/** WEB
+ * webSetURL
+ **/
+Scripting.addGlobal(function webSetURL(url: string, checkResult?: boolean) {
+ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
+ console.log("URL: ", url);
+ if (checkResult && selected && selected.type === DocumentType.WEB){
+ return Cast(selected.data, WebField, null).url;
+ }
+ else if (selected && selected.type === DocumentType.WEB){
+ selected.data = url;
+ }
+}); \ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 82ad2b7db..c081b8e26 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -277,6 +277,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const found = new Set<Mark>();
const { from, to } = state.selection as TextSelection;
state.doc.nodesBetween(from, to, (node) => node.marks.forEach(m => found.add(m)));
+ console.log("Marks: " + found);
return found;
}
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
index d04ae8a80..05aeb177c 100644
--- a/src/client/views/topbar/TopBar.scss
+++ b/src/client/views/topbar/TopBar.scss
@@ -22,7 +22,7 @@
.topBar-icon {
cursor: pointer;
- font-size: 12px;
+ font-size: 12.5px;
font-family: 'Roboto';
width: fit-content;
display: flex;
@@ -31,18 +31,20 @@
align-items: center;
justify-self: center;
align-self: center;
- border-radius: 5px;
+ border-radius: $standard-border-radius;
padding: 5px;
transition: linear 0.1s;
color: $black;
background-color: $light-gray;
- }
- .topBar-icon:hover {
- background-color: $light-blue;
+ &:hover {
+ background-color: $light-blue;
+ }
}
-
+
+
+
.topbar-center {
grid-column: 2;
display: inline-flex;
@@ -59,7 +61,7 @@
.topbar-lozenge-dashboard {
display: flex;
-
+
.topbar-dashSelect {
border: none;
@@ -156,9 +158,9 @@
}
&.topbar-input {
- margin:5px;
- border-radius:20px;
- border:$dark-gray;
+ margin: 5px;
+ border-radius: 20px;
+ border: $dark-gray;
display: block;
width: 130px;
-webkit-transition: width 0.4s;
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 05edb975c..4dbd5e22c 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -28,7 +28,7 @@ export class TopBar extends React.Component {
{`${Doc.CurrentUserEmail}`}
</div>
<div className="topbar-icon" onClick={() => window.location.assign(Utils.prepend("/logout"))}>
- {"Sign out"}
+ {"Log out"}
</div>
</div>
<div className="topbar-center" >
diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts
index 1270a2dab..f16e143d8 100644
--- a/src/fields/InkField.ts
+++ b/src/fields/InkField.ts
@@ -1,8 +1,8 @@
+import { createSimpleSchema, list, object, serializable } from "serializr";
+import { Scripting } from "../client/util/Scripting";
import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
+import { Copy, ToScriptString, ToString } from "./FieldSymbols";
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 {